Comment on page
Controlling execution with snippets of code
Gadgets are small snippets of code followed by a
pop rdi; ret. We can manipulate the
retof these gadgets in such a way as to string together a large chain of them to do what we want.
Let's for a minute pretend the stack looks like this during the execution of a
pop rdi; retgadget.
What happens is fairly obvious -
0x10gets popped into
rdias it is at the top of the stack during the
pop rdi. Once the
retis equivalent to
0x5655576724gets moved into
rip. Note how the stack is laid out for this.
When we overwrite the return pointer, we overwrite the value pointed at by
rsp. Once that value is popped, it points at the next value at the stack - but wait. We can overwrite the next value in the stack.
Let's say that we want to exploit a binary to jump to a
pop rdi; retgadget, pop
rdithen jump to
flag(). Let's step-by-step the execution.
On the original
ret, which we overwrite the return pointer for, we pop the gadget address in. Now
ripmoves to point to the gadget, and
rspmoves to the next memory address.
rspmoves to the
pop rdi. Now when we pop,
0x100gets moved into
RSP moves onto the next items on the stack, the address of
retis executed and
Essentially, if the gadget pops values from the stack, simply place those values afterwards (including the
ret). If we want to pop
rdiand then jump to
0x16, our payload would look like this:
Note if you have multiple
popinstructions, you can just add more values.
rdias an example because, if you remember, that's the register for the first parameter in 64-bit. This means control of this register using this gadget is important.
$ ROPgadget --binary vuln-64
0x0000000000401069 : add ah, dh ; nop dword ptr [rax + rax] ; ret
0x000000000040109b : add bh, bh ; loopne 0x40110a ; nop ; ret
0x0000000000401037 : add byte ptr [rax], al ; add byte ptr [rax], al ; jmp 0x401024
Combine it with
grepto look for specific registers.
$ ROPgadget --binary vuln-64 | grep rdi
0x0000000000401096 : or dword ptr [rdi + 0x404030], edi ; jmp rax
0x00000000004011db : pop rdi ; ret