Before you proceed any further, make sure you have all the requirements fulfilled.

  • ASM knowledge
  • Debugger familiarity
  • GDB
  • Basic ROP knowledge
  • Brain


In this post, we will try to learn ROP (Return Oriented Programming) by using ropemporium ret2win 32bit binary. Lets setup our machine for debugging by installing PEDA and downloading the target binary.

We have downloaded the binary and extracted it, time to start gdb.


We have found the offset at 44 which means that the EIP will hold the next 4bytes. We will use a custom boiler plate to ease our exploit development for this binary which can be found in the final exploit.


Now we need to understand the concept of dependencies/libraries and how import symbol resolution works. I will try to explain it with gdb alone without going into theoreticals. Load the binary inside gdb and have a look

As of now, there is no symbol resolution performed by the dynamic linker because we haven’t started the binary. At this time, at callme_three@plt function entry there is an instruction which jumps directly to GOT address which as of now points back to the next instruction right after the jump. Now if we start the program, this changes because the linker resolved the address and updated the Global Offset Table entry which results in jumping to the updated address. Before that, lets have a look at the .PLT section

As we can see, the PLT section first pushes the resolved GLOBAL_OFFSET_TABLE address to stack. It says GLOBAL_OFFSET_TABLE because this is handled by the linker and the address is provided back, if it would’ve been a hardcoded address the program would crash just like the linker resolves printf@plt address from libc library. We will try to resolve the first instruction in the PLT section with gdb

The GOT address resolved to dynamic linker which is now used to resolve the symbols right after 0x804858c. Similarly, our callme_three@plt function address is resolved to library and updated inside GOT. The binary, by default doesn’t uses any callme_ functions but contains references inside the PLT. We can use this info to make our payload and retrieve the flag. The challenge help page on ropemporium also says

You must call callme_one(), callme_two() and callme_three() in that order, each with the arguments 1,2,3 e.g. callme_one(1,2,3) to print the flag. The solution here is simple enough, use your knowledge about what resides in the PLT to call the callme_ functions in the above order and with the correct arguments. Don’t get distracted by the incorrect calls to these functions made in the binary, they’re there to ensure these functions get linked. You can also ignore the .dat files and the encrypted flag in this challenge, they’re there to ensure the functions must be called in the correct order.

We have gathered all the information now, so lets not waste any time and make our payload.



Leave a Reply

Your email address will not be published. Required fields are marked *