I was reading this article by the InfoSec institute:


And was able to follow along until he did the ROP Chain.

He finds the offset of printf and execve to be 328160

He then finds the following ROP gadgets:

0x804886eL: add eax [ebx-0xb8a0008] ; add esp 0x4 ; pop ebx
0x804861fL: call eax ; leave ;;
0x804849cL: pop eax ; pop ebx ; leave ;;

I understand that the idea is to load the absolute address of execve into eax and then call eax, but where i get lost is the way he does it.

The gadget:

0x804886eL: add eax [ebx-0xb8a0008] ; add esp 0x4 ; pop ebx

Adds eax and [ebx - 0xb8a0008] and then stores it in eax for the next gadget to call.

The goal now seems to be to get ebx to contain the absolute address of printf@got, but instead he loads 0x138e9ff4 into ebx, he says its because:

printf@got + 0xb8a0008 = 0x138e9ff4

I just have no idea how he calculates the value 0x138e9ff4, as ASLR is enabled and printf@got should be different every time, and therefore the value loaded into ebx should too.

Would appreciate any input you have

1 Answer 1


I agree it is very poorly explained in the article. It took me several reads to understand what on earth was going on.

The key part is here:

Our aim now is to build a chained ROP to execute execve(). As we can see, we don’t have a GOT entry for this function and libc is randomized.

So what we will do first is to leak a libc function address for GOT then we will do some trivial calculation to get the exact execve libc address.

They're making the assumption that you've got an information leak that tells you where any single libc function is. In this case, they're using printf as an example.

From there, the exploit makes way more sense:

The first step is that they populate eax with 0x328160 and ebx with 0x138e9ff4 using the pop; pop; leave gadget. When that add instruction is executed it computes 0x138e9ff4 - 0xb8a0008 = 0x8049fec. This is the address of printf@got in the example. Note that this is the address of the Global Offsets Table (GOT) entry for printf, not the actual printf function itself. The base address of the GOT is not randomised in regular Linux (it may be in grsec-hardened kernels; I haven't looked into it)

The instruction is now essentially: add eax, [0x8049fec]. The attacker knows that for the target version of libc the distance between printf and execve is 0x328160, so when this instruction runs it takes the address of the printf function from the GOT and adds 0x328160 to it (from eax, which was preloaded by the pop pop leave) which loads the address of execve into eax.

The call eax then executes execve.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .