This shows you the differences between two versions of the page.
cns:labs:lab-08 [2020/12/07 16:14] mihai.dumitru2201 [3. ROP: Find the buffer] |
cns:labs:lab-08 [2021/12/14 13:28] (current) razvan.deaconescu |
||
---|---|---|---|
Line 1: | Line 1: | ||
- | ====== Lab 08 - Return Oriented Programming ====== | + | ====== Lab 08 - Return-Oriented Programming ====== |
===== Introduction ===== | ===== Introduction ===== | ||
Line 263: | Line 263: | ||
* As usual, we have to identify the overflowed buffer ''offset'' where the return address starts. We can do this using the ''peda'' ''pattc'' and ''patto'' commands as in the previous [[http://ocw.cs.pub.ro/courses/cns/labs/lab-06#phase_2finding_the_vulnerability|labs]]. | * As usual, we have to identify the overflowed buffer ''offset'' where the return address starts. We can do this using the ''peda'' ''pattc'' and ''patto'' commands as in the previous [[http://ocw.cs.pub.ro/courses/cns/labs/lab-06#phase_2finding_the_vulnerability|labs]]. | ||
* The complete exploit can be found in ''00-tutorial-2-ret2libc/solution.py'' | * The complete exploit can be found in ''00-tutorial-2-ret2libc/solution.py'' | ||
- | |||
- | </code> | ||
==== 3. ROP: Find the buffer ==== | ==== 3. ROP: Find the buffer ==== | ||
Line 294: | Line 292: | ||
<note tip> | <note tip> | ||
The buffer address is stored in a register when ''ret'' is executed. | The buffer address is stored in a register when ''ret'' is executed. | ||
+ | |||
+ | There is no need for a memory disclosure / information leak of the buffer address. **You can find a gadget that jumps / calls that register.** | ||
Use ''%%ropsearch ... libc%%''. Instead of ''%%...%%'' place the instructions you search. | Use ''%%ropsearch ... libc%%''. Instead of ''%%...%%'' place the instructions you search. | ||
Line 306: | Line 306: | ||
io = process(["./ropbuf", payload]) # Run ./ropbuf using payload as command line argument. | io = process(["./ropbuf", payload]) # Run ./ropbuf using payload as command line argument. | ||
</code> | </code> | ||
+ | </note> | ||
+ | |||
+ | <note important> | ||
+ | You can't send NUL-bytes as part of command line arguments. When constructing the payload, use ''%%pack(...).strip(b\"x00")%%''. | ||
</note> | </note> | ||
Line 321: | Line 325: | ||
As we've seen in the above sections, ROP is useful when we want to chain multiple function calls. Using ROP Gadgets we can setup function arguments in between function calls. | As we've seen in the above sections, ROP is useful when we want to chain multiple function calls. Using ROP Gadgets we can setup function arguments in between function calls. | ||
- | Take a look at ''4-ropfunc/ropfunc.c'' and make it call ''call_1()'' followed by ''call_2()'' and ''call_exit()''. You can start from the skeleton in ''ropfunc.py''. When calling ''call_1()'' and ''call_2()'', make them print the messages in the ''if'' block by passing the proper parameters. | + | Take a look at ''02-ropchain/ropchain.c'' and make it call ''call_1()'' followed by ''call_2()'' and ''call_exit()''. You can start from the skeleton in ''02-ropchain/exploit.py''. When calling ''call_1()'' and ''call_2()'', make them print the messages in the ''if'' block by passing the proper parameters. |
==== 5. Bonus ROP: Libc Functions chain ==== | ==== 5. Bonus ROP: Libc Functions chain ==== | ||
Now let's move to a more practical example by chaining useful ''libc'' functions. | Now let's move to a more practical example by chaining useful ''libc'' functions. | ||
- | Take a look at ''roplibc.c''. We can see that we have a buffer overflow on ''buf'' and a global, unused ''gbuf''. | + | Take a look at ''03-roplibc/roplibc.c''. We can see that we have a buffer overflow on ''buf'' and a global, unused ''gbuf''. |
* The stack is not executable so, at the first sight, we cannot put our shellcode neither in ''buf'', nor in ''gbuf''. But what if we manage to call (jump to) **mprotect** over the memory area where we store the shellcode, and make it executable? | * The stack is not executable so, at the first sight, we cannot put our shellcode neither in ''buf'', nor in ''gbuf''. But what if we manage to call (jump to) **mprotect** over the memory area where we store the shellcode, and make it executable? | ||
* Furthermore, given the fact that ''gbuf'' is larger than ''buf'', we might want to put our shellcode there. But how do we do this when the only ''read'' call is on ''buf''? In this case, we will also want to call (jump to) **read** in our exploit payload. | * Furthermore, given the fact that ''gbuf'' is larger than ''buf'', we might want to put our shellcode there. But how do we do this when the only ''read'' call is on ''buf''? In this case, we will also want to call (jump to) **read** in our exploit payload. | ||
* A possible ROP chain (that will start from the overwritten return address from ''buf'') for the described attack will look something like below. The return addresses in the ROP chain are highlighted with red and the function parameters with green. | * A possible ROP chain (that will start from the overwritten return address from ''buf'') for the described attack will look something like below. The return addresses in the ROP chain are highlighted with red and the function parameters with green. | ||
- | **[<color red>pop rdi;ret</color>][<color green>fd=0</color>][<color red>pop rsi;ret</color>][<color green>gbuf</color>][<color red>pop rdx;ret</color>][<color green>shellcode_len</color>][read_addr] | ||
+ | **[<color red>pop rdi;ret</color>][<color green>fd=0</color>][<color red>pop rsi;ret</color>][<color green>gbuf</color>][<color red>pop rdx;ret</color>][<color green>shellcode_len</color>][read_addr]** | ||
+ | |||
+ | **[<color red>pop rdi;ret</color>][<color green>page</color>][<color red>pop rsi;ret</color>][<color green>page_size</color>] [<color red>pop rdx;ret</color>][<color green>mp3</color>][mprotect_addr]** | ||
- | [<color red>pop rdi;ret</color>][<color green>mp1</color>][<color red>pop rsi;ret</color>]][<color green>mp2</color>] [<color red>pop rdx;ret</color>][<color green>mp3</color>][mprotect_addr][gbuf_addr]** | + | **[gbuf_addr]** |