ROP32 — PicoCTF2019
It’s been a long time since my last writeup, now i came back with this exciting challenge. I knew that there’s a lot of writeup about this challenge on the internet but this one I only based my own limited knowledge.
so let’s jump in!!!
Can you exploit the following program to get a flag? You can find the program in /problems/rop32_1_c4f09c419e5910665553c0237de93dcf on the shell server. Source.
This is a classic ROP to get a shell
The name and the hint itself pretty clear about what we’re going to do. If you don’t know what is ROP, then I suggest you should research it more about it andread this writeup.
From the source, we’ll see the
gets function that’s lead to the
Buffer Overflow (abbr BOF )vulnerability. But if we
that’s the NX bit is on, so there is no way we can put our shellcode to the stack and let it execute itself. We need to use
ROP technique to bypass NX bit.
So what’s ROP? Basically it use the present codes inside the binary, which we call gadgets, and we chain it into a ROP chain.
now let’s find our offset first
our offset is
0x1c (or 28 if you prefer decimal)
now because we’re all new to ROP (I presume that you readers and myself), we need to ROP our way some how to execute this syscall
execve(‘/bin/sh’, [‘/bin/sh’], NULL)
according to the syscall table above, we need
- eax == 0xb (11 in dec)
- ebx == address in the memory of the string ‘/bin/sh’
- ecx == a pointer point to the address of ‘/bin/sh’
- edx == NULL (\x00)
as you may know parameters are passed to syscall via the registers. You can see that each of the regs represent an argument in the
execve function, and of course the eax is the exception one, because you can determine which syscall should the machine use.
alright now let’s jump into the next step
first i use
ROPgadget to find our gadgets and dump it into a file.
let’s test this one and see
0x080a8e36 : pop eax ; ret
hmm, weird. Do you notice that my gadgets is
i’m strolling around the internet and then found this.
because in our gadget it has a special byte which is
0x0a if you decipher that hex value it means the newline character (AKA
\n). When the machine meet that byte it simply nulled it. that’s why our gadget didn’t work.
let’s find the suitable gadget without the badbyte
0x08056334 : pop eax ; pop edx ; pop ebx ; ret
alright let’s sum up what we should do
- first we found all the suitable gadgets to trigger the syscall
- I myself need to specify a clear way to solve this challenge xD
here are the basic step that i found suggest
- Step 1 — Write-what-where gadgets
- Step 2 — Init syscall number gadgets
- Step 3 — Init syscall arguments gadgets
- Step 4 — Syscall gadget
- Step 5 — Build the ROP chain
the first step is simple, you need to write your string to a writable memory (such ass .bss section)
the second step is to find the gadget that can allow you to modify the value of eax
the third step is to find gadgets that can allow you to modify the ebx, ecx, edx regs
the fourth step is to find the gadget that initiate the syscall (which is
the fifth step was the obvious captain !!!
now for the first step i’m using the .data section
- i’m using the following gadgets to write it:
0x8056e65 mov dword ptr [edx], eax ; ret
0x806ee6b pop edx ; ret
0x8056334 pop eax ; pop edx ; pop ebx ; ret
for the 2nd step
0x8056420 xor eax, eax ; ret
0x807c2fa inc eax ; ret
for the 3nd step
0x80481c9 pop ebx ; ret
0x806ee92 pop ecx ; pop ebx ; ret
0x806ee6b pop edx ; ret
the final one
0x8049563 int 0x80
now let’s stroll through our gadgets. The first step was pretty interesting one, you saw that i’m using the
mov [reg1] reg2 instruction. Because that’s the only way (i think) we can write a value to a specific address. So our first step’s gonna be
nice, now we can write it with the gadget
mov [reg1] reg2
Great! Now that we’re wrote ‘/bin’ to the
0x080da060 now we need to increase our address to 4 more bytes to write our next string ‘/bin//sh’ (because we need to fill up 4 bytes and when the machine saw 2 forward slashes, it ignore one)
Cool right? now before we move to the next step we just need to make sure like 4 bytes more with null byte because we need our ecx, edx == NULL
we just need to null it with the
mov [reg1] reg2 instruction
phew, finally done step one!!!
now we go to step two (i mean step 3 because step 2 it’s kinda easy we just using it for 11 times)
3rd and 4th step
now we just need to ssh to the sever and take our flag
enjoy hacking !!!