ROP Emporium


We're back in ret2win territory, but this time with no useful gadgets.
How will we populate critical registers without them?

Click below to download the binary:

x86_64 ARMv5 MIPS

Same same, but different

This challenge is very similar to "callme", with the exception of the useful gadgets. Simply call the ret2win() function in the accompanying library with same arguments that you used to beat the "callme" challenge (ret2win(0xdeadbeef, 0xcafebabe, 0xd00df00d) for the ARM & MIPS binaries, ret2win(0xdeadbeefdeadbeef, 0xcafebabecafebabe, 0xd00df00dd00df00d) for the x86_64 binary.

Populating the elusive 3rd register using ROP can prove more difficult than you might expect, especially in smaller binaries with fewer gadgets. This can become particularly irksome since many useful GLIBC functions require three arguments.

So little room for activities

Start by using ropper to search for sensible gadgets, if there's no pop rdx for example, perhaps there's a mov rdx, rbp that you could chain with a pop rbp. If you're all out of ideas go ahead and read the last paragraph.


Fortunately some very smart people have come up with a solution to your problem and as is customary in infosec given it a collection of pretentious names, including "Universal ROP", "╬╝ROP", "return-to-csu" or just "ret2csu". You can learn all you need to on the subject from this BlackHat Asia paper. Note that more recent versions of gcc may use different registers from the example in __libc_csu_init(), including the version that compiled this challenge.

Back to top