one punch
Problem
Solution
Basic file checks
We're given a binary with a ld linker and a libc, first thing we'll do is run pwninit
with the provided linker so it can segfaultlessly load the provided libc
Next lets do some basic file check
FULL RELRO: so overwriting GOT is not an option
No Stack Canary: easier for us to do BOFs
NX enable: Shellcode is also not an option
PIE Enabled: means we have to do some leaking to correctly craft the ROP chains
Next, lets statically analyse the binary using ghidra
Binary Analysis
First the function will check if mapped_region
in the .data
section is empty, if not it will execute init
, we'll take a look at that later. Next we're greeted with an address leak, lets check what that is using gdb-pwndbg
It seems the address is pointing to an address that can be useful as our pop rdi; ret;
gadget which will enable our ROP chains.
The init
function fills the mapped_region
with the value of key which holds the value POWER, GET THE POWER.
. Next lets check vuln
Crafting ROP chains
Immediately we see that it's using the gets
which will enable our overflow, from here we already get an overview of how we'll exceute the ROP chains. First we'll leak one of the function within the GOT and print it out. We can then subtract that with its corresponding offset to find the Libc base address. we can call system
with /bin/sh
that's exist within the Libc as follows:
1st Payload:
pop rdi -> GOT puts -> PLT puts -> Main (Eventually will call vuln)
2nd Payload:
pop rdi -> binsh -> system
but there's a twist, vuln
will do a a comparison between key
and mapped_region
. If the two values is not the same, it will exit the program. Below it, the instruction will overwrite the first 21 bytes of mapped_region
with 0s. This basically is a check to make sure that vuln
can only be called once. To bypass this, we simply have to call init
to restore the value. In order to do that we cant return to main after our first BOFs since there's check on mapped_region
if the memory is empty. So instead, we need to return to init
passing the if statement and eventually will return to vuln through main.
1st Payload:
pop rdi -> GOT puts -> PLT puts -> init
2nd Payload:
pop rdi -> binsh -> system
Flag
dead{I_w4nn4_b3_4_s41ky0u_H3R00000000}
Last updated