Avatar

Labs / Type Juggling Bypass

  • Challenge
  • Released 13 Oct 2025

Can you exploit PHP's weak typing to break into the admin panel?

A login portal stands between you and the flag, protected by MD5 hashing. The developer used loose comparison instead of strict comparison, creating an exploitable weakness. Master the art of PHP type juggling and bypass authentication without knowing the real password. Can you turn this subtle vulnerability into complete access?

1
Flags
1
Points
Challenge
Pro Exclusive
Start Lab Environment
~1-2 min setup
AWS dedicated
Private instance
Industry standard
Challenge

Solution: Type Juggling Bypass

This challenge demonstrates a critical PHP vulnerability where loose comparison operators enable authentication bypass through type juggling.

Step 1: Reconnaissance

Navigate to the challenge URL at <target-ip> to access the admin login portal:

  1. Open your web browser and visit http://<target-ip>
  2. Observe the admin login form with username and password fields
  3. Note the hint mentioning MD5 hashing for password security
  4. Click the 'View Source Code' link at the bottom of the page

Step 2: Source Code Analysis

Examine the PHP source code to identify the vulnerability:

$admin_password_hash = '0e462097431906509019562988736854';

if ($username === 'admin' && md5($password) == $admin_password_hash) {
// Grant access
}

Key observations:

  • The stored password hash begins with '0e' followed by only digits
  • The comparison uses == (loose comparison) instead of === (strict comparison)
  • Username must be exactly 'admin' (strict comparison used correctly)
  • This creates a type juggling vulnerability in the password check

Step 3: Understanding the Vulnerability

PHP interprets strings starting with '0e' followed by only digits as numbers in scientific notation:

  • '0e462097431906509019562988736854' is interpreted as 0 x 10^462097431906509019562988736854
  • Any number raised to any power of 0 equals 0
  • Therefore, any MD5 hash starting with '0e' and containing only digits will equal 0 when compared with ==
  • We need to find a password whose MD5 hash also starts with '0e' followed by only digits

Step 4: Finding Magic Hashes

Several known strings produce MD5 hashes with the '0e' pattern (called 'magic hashes'):

md5('240610708') = '0e462097431906509019562988736854'
md5('QNKCDZO') = '0e830400451993494058024219903391'
md5('s878926199a') = '0e545993274517709034328855841020'
md5('s155964671a') = '0e342768416822451524974117254469'
md5('s214587387a') = '0e848240448830537924465865611904'

Any of these passwords will bypass authentication because they all equal 0 when compared with ==.

Step 5: Exploitation

Use any magic hash to bypass authentication:

  1. Return to the login form at http://<target-ip>
  2. Enter username: admin
  3. Enter password: QNKCDZO (or any other magic hash string)
  4. Click 'Login'
  5. The system will compute md5('QNKCDZO') which equals '0e830400451993494058024219903391'
  6. PHP compares: '0e830400451993494058024219903391' == '0e462097431906509019562988736854'
  7. Both strings are interpreted as 0 in scientific notation
  8. The comparison evaluates to true, granting access

Step 6: Retrieve the Flag

After successful login, the admin panel displays the flag as a UUID.

Alternative Methods

Method 1: Brute Force Magic Hashes

If you don't have a list of magic hashes, you can generate your own:

import hashlib
import itertools
import string

charset = string.ascii_uppercase + string.digits
for length in range(7, 12):
for combo in itertools.product(charset, repeat=length):
test = ''.join(combo)
hash_val = hashlib.md5(test.encode()).hexdigest()
if hash_val.startswith('0e') and hash_val[2:].isdigit():
print(f'Found: {test} -> {hash_val}')
break

Method 2: Using Burp Suite

  1. Configure your browser to proxy through Burp Suite
  2. Submit a login attempt with username 'admin' and any password
  3. Intercept the POST request in Burp
  4. Modify the password parameter to 'QNKCDZO' or another magic hash
  5. Forward the request to see the authentication bypass

Method 3: Command Line with cURL

curl -X POST http://<target-ip> \
-d 'username=admin&password=QNKCDZO' \
-c cookies.txt

# The response will contain the flag

Understanding the Security Impact

This vulnerability demonstrates several critical security issues:

  • Authentication Bypass: Attackers can login as any user without knowing the actual password
  • Poor Comparison Logic: Using == instead of === creates exploitable weaknesses
  • Weak Hashing: MD5 is cryptographically broken and should never be used for passwords
  • Predictable Patterns: Magic hash databases make exploitation trivial

Secure Implementation

The correct way to implement password verification in PHP:

// Secure password hashing
$hashed_password = password_hash($password, PASSWORD_ARGON2ID);

// Secure password verification
if ($username === 'admin' && password_verify($password, $stored_hash)) {
// Grant access
}

// Never use:
// - md5() or sha1() for passwords
// - == for comparing sensitive values
// - Manual hash comparison without constant-time comparison

Key Takeaways

  • Always use strict comparison (===) for security-critical operations
  • Never use MD5 or SHA1 for password hashing
  • Use PHP's built-in password_hash() and password_verify() functions
  • Type juggling vulnerabilities are common in PHP applications
  • Understanding PHP's type coercion rules is essential for secure coding
  • Magic hash databases make these vulnerabilities easy to exploit

Congratulations! You've successfully exploited PHP type juggling to bypass authentication. This challenge highlights why strict comparison and proper password hashing functions are essential for secure applications.