1 of 29

Return-oriented Programing

Exploiting Buffer overflow with ROP

2 of 29

3 of 29

Buffer overflow attack

  • Simply writing to the buffer (stack) assembly instructions and let the machine execute them

4 of 29

Why ROP?

  • Traditional buffer overflow is almost impossible to exploit
  • Attacker can still use code in memory that is marked as runnable
  • Shared libraries such as libc usually contain useful pieces of code

5 of 29

What do we need for ROP?

  • To control the stack.
  • ROP chains are expected to be longer than shellcodes, usually requiring overriding many dozens bytes.

6 of 29

What is Return-Oriented-Programming?

  • ROP is an attack against the infamous NX bit, which disables executing code from the stack and other writable segments.

7 of 29

What is Return-Oriented-Programming?

  • In ROP we override the addresses stored in the stack, and by doing that we control the program flow.

8 of 29

Possible issues

  • ASLR
  • Stack Canary (Cookie)
  • 64-bit system
  • strcpy

9 of 29

Basic Information

  • Functions addresses
    • More generally, addresses with executable code/data.
  • Stack structure.

10 of 29

Example stack structure

11 of 29

Example – the basic scenario

  • The setup: The program we are going to exploit:

12 of 29

Passing an argument (or more..)

13 of 29

What is Return-Oriented-Programming?

  • Instead of returning to libc functions we will be utilizing small instruction sequences available in either the binary or libraries linked to the application. These small instructions are called gadgets.

14 of 29

What is Return-Oriented-Programming?

  • There are intended gadgets and unintended gadgets.
  • intended gadgets are instruction sequences that the developer meant for them to be there.
  • unintended as you can imagine, are instruction sequences that aren’t intended to be there by the developer.

15 of 29

16 of 29

What is Return-Oriented-Programming?

  • What?!? Unintended?!? how come?!?
  • Well, if you look at a sentence like �“The article” the writer intended to say, “the article” but he didn’t intend to have the word “heart”, did he ☺

17 of 29

What is Return-Oriented-Programming?

  • Basically what we need to do, is instead of returning to an address of a function in libc we wil return to ROP gadgets.

18 of 29

What are ROP gadgets?

  • ROP gadgets are small instruction sequences ending with a “ret” instruction.
  • Combining these gadgets will enable us to perform certain tasks.
  • in case of turing-complete set, we will be able to perform any task.
    • But why? ☹
  • and in the end conduct our attack as we will see later .
  • The ROP gadget must end with a “ret” to enable us to perform multiple sequences.
  • Hence it is called return oriented.

19 of 29

How to find these gadgets?

  • We search the binary for all “ret” (c3) byte.
  • We go backwards to see if the previous byte contains a valid instruction.
  • We reverse to the maximum number of bytes that can make a valid instruction (20 bytes).
  • We then record all valid instruction sequences found in the binary or linked libraries.

20 of 29

What can we do with ROP Gadgets?

  • Loading a constant into register
  • Loading from memory
  • Storing into memory
  • Arithmetic operations
  • System call

21 of 29

Gadgets

  • A way to use my own code.
  • A gadget, as mentioned before is a (small) set of assembly instructions ending with ret.
  • We generally don’t care about the registers involved…..

22 of 29

Gadgets

  • Example:
    • 0x80045129 pop %ebp
    • 0x8004512a ret

This gadget pops one value out of the stack and increments %esp

23 of 29

Gadgets chaining

  • Gadget 1:
    • 0x80049d37 mov %ebx, (%eax)
    • 0x80049d3a ret
  • Gadget 2:
    • 0x80045129 pop %ebx
    • 0x80045129 pop %eax
    • 0x8004512a ret

This gadget pops one value out of the stack and increments %esp

24 of 29

Gadgets

  • How do we find gadgets?
  • We look for an executable memory sequence, and search for the byte 0xc3 – ret in assembly.
  • We then look behind to search for a valid aassembly instructions.
  • If we found – this is a gadget (though not necessarily useful). Otherwise – discard.

25 of 29

Useful gadgets

  • Popping – loading a stack memory into a register. Very useful, as we control the stack.
  • Loading from memory.
  • Storing into memory.
  • Arithmetic operation – can be used to achieve more complex gadgets.
  • System calls.

26 of 29

Our enemies

  • In the standard calling conventions, some registers are called non-volatiles, or callee-saved. For example, ebx/rbx.
  • If we want to return the program to its original state, we should preserve/restore these registers.
  • 0x60 – pusha (assembly). Saves all registers. No 64bit equivalent.

27 of 29

A quick win…

  • Using memory protection functions, such as VirtualProtect (Windows) or mprotect (Linux), usually result in RWX pages where we can execute an arbitrary shellcode.

28 of 29

A quick win…

29 of 29

movl %class, (%home)�ret