═══════════════════════════════════════════════════════════════════════════════ 🎯 PASTEBOARD XSS CHALLENGE - COMPLETE SUMMARY ═══════════════════════════════════════════════════════════════════════════════ Challenge: https://pasteboard-1fb68b7836775bea.chals.uoftctf.org/ Bot: Runs Chrome with --no-sandbox --disable-gpu --headless flags ═══════════════════════════════════════════════════════════════════════════════ ✅ WHAT WE CONFIRMED WORKS ═══════════════════════════════════════════════════════════════════════════════ 1. XSS VULNERABILITY (CONFIRMED WORKING) - Location: app.js error handler - Method: DOM clobbering via
- Payload structure:
✅ We successfully executed arbitrary JavaScript in bot's context ✅ Bot visits pages (confirmed via webhook requests) ✅ Can exfiltrate data via fetch() to external webhook 2. CONFIRMED DATA FROM BOT - Bot is running on localhost:5000 - Bot is Chrome 143 on Linux (HeadlessChrome) - XSS executes successfully - User-Agent: HeadlessChrome/143.0.0.0 ═══════════════════════════════════════════════════════════════════════════════ ❌ WHAT WE FOUND EMPTY/INACCESSIBLE ═══════════════════════════════════════════════════════════════════════════════ 1. STANDARD BROWSER APIS (All Empty) ❌ document.cookie → "" ❌ localStorage → empty ❌ sessionStorage → empty ❌ window.FLAG / window.flag → undefined ❌ No flag-related properties in window object 2. FILE/PROTOCOL ACCESS BLOCKED ❌ file:// protocol → NetworkError (blocked even with --no-sandbox) ❌ Tried fetch() to file:// URLs → Failed ❌ Tried navigation to file:// URLs → No response 3. INTERNAL ENDPOINTS (All 404) ❌ /flag, /flag.txt, /admin, /secret ❌ /static/flag.txt, /../flag.txt ❌ All returned 404 or no accessible data 4. CHROME DEVTOOLS PROTOCOL (CDP) ❌ localhost:9222/json → Connection failed (no debugging port) ❌ import('/devtools/main/main.js') → No response/silent failure ❌ chrome:// URL navigation → No response ❌ CDP Runtime.evaluate → Could not test (import failed) 5. TIMING/POLLING ATTEMPTS ❌ Polled for flag appearance for 20 seconds → nothing appeared ❌ Delayed checks (5-20 seconds) → no change ❌ No flag materialized asynchronously ═══════════════════════════════════════════════════════════════════════════════ 🔍 THE MYSTERY ═══════════════════════════════════════════════════════════════════════════════ CONFIRMED FACTS: 1. bot.py defines: FLAG = "uoftctf{fake_flag}" 2. This FLAG variable is NEVER USED in the bot code 3. XSS works perfectly - we can execute arbitrary JS 4. --no-sandbox flag is present but CDP access doesn't work 5. Organizers said: "working as intended" and "solvable locally" THE QUESTION: WHERE IS THE FLAG ACTUALLY STORED/ACCESSIBLE? Theories that DIDN'T work: - Not in cookies (empty) - Not in localStorage/sessionStorage (empty) - Not in window global (checked all properties) - Not in file system (file:// blocked, no accessible endpoints) - Not via CDP (port not open, module import fails) - Not set asynchronously (polling for 20 seconds found nothing) ═══════════════════════════════════════════════════════════════════════════════ 📋 COMPLETE LIST OF PAYLOADS TRIED ═══════════════════════════════════════════════════════════════════════════════ 1. Simple ping test → ✅ Confirmed XSS works 2. Comprehensive data dump → ✅ Got all browser data (all empty) 3. CDP exploitation (multiple variants) → ❌ No response 4. Chrome debugging port check → ❌ Port closed 5. DevTools module import → ❌ Silent failure 6. chrome://inspect navigation → ❌ No response 7. chrome://version navigation → ❌ No response 8. file:// URL fetch → ❌ Blocked 9. file:// URL navigation → ❌ No response 10. Internal endpoint scanning → ❌ All 404 11. Flag polling (20 seconds) → ❌ Nothing appeared 12. Delayed checks (5-10 seconds) → ❌ No change 13. Window property enumeration → ❌ No flag-related properties 14. HTML DOM search → ❌ No flag in page content 15. Meta tag search → ❌ No flag in meta tags 16. Hidden input search → ❌ No hidden flag inputs 17. CSS variable check → ❌ No flag in CSS 18. Performance entries check → ❌ No flag in timing data 19. Iframe source check → ❌ No iframes 20. Service worker check → ❌ No service workers ═══════════════════════════════════════════════════════════════════════════════ 💡 POSSIBLE MISSING PIECES ═══════════════════════════════════════════════════════════════════════════════ 1. REMOTE BOT MIGHT DIFFER FROM LOCAL - Maybe remote bot.py actually USES the FLAG variable - Maybe remote has different Chrome flags - Maybe remote has debugging port open 2. CDP ACCESS METHOD UNCLEAR - We couldn't get CDP to work - Maybe there's a different way to access it - ASIS CTF 2022 used CDP, but we can't replicate it 3. FLAG LOCATION UNKNOWN - Theory: FLAG is in process.env (Python environment variable) - Theory: FLAG is in a file we can't access without CDP - Theory: FLAG requires special Chrome flag we don't have - Theory: Remote challenge has different setup 4. POSSIBLE ALTERNATIVES NOT TRIED - Maybe there's a different XSS vector? - Maybe DOM clobbering can access something else? - Maybe there's a CSRF or other vulnerability? - Maybe need to exploit the bot differently? ═══════════════════════════════════════════════════════════════════════════════ 🛠️ TECHNICAL DETAILS FOR YOUR FRIEND ═══════════════════════════════════════════════════════════════════════════════ XSS EXPLOIT MECHANISM: 1. app.js has error handler that loads script from window.errorReporter.path 2. We create
to clobber window.errorReporter 3. We set 4. We trigger error with 5. Error handler loads our malicious script via data: URI 6. CSP allows this because of 'strict-dynamic' directive BOT CONFIGURATION: - Chrome 143 (HeadlessChrome) - Flags: --no-sandbox --disable-gpu --headless - Visits page for 30 seconds - No cookies set before visiting - No localStorage/sessionStorage set - No debugging port open (localhost:9222 not accessible) WHAT WE CAN DO: ✅ Execute arbitrary JavaScript in bot context ✅ Make fetch() requests to external servers ✅ Access all standard browser APIs ✅ Read DOM, document properties, window properties ✅ Navigate to URLs (though no response visible) WHAT WE CANNOT DO: ❌ Access file:// protocol ❌ Access Chrome DevTools Protocol ❌ Navigate to chrome:// URLs (or at least see results) ❌ Find flag in any standard browser storage ❌ Access internal endpoints with flag ═══════════════════════════════════════════════════════════════════════════════ ❓ QUESTIONS FOR YOUR FRIEND ═══════════════════════════════════════════════════════════════════════════════ 1. How do we access the FLAG variable from bot.py in JavaScript? - It's defined but never used in the Python code - Is it supposed to be in process.env? - How do we read Python process environment from JS? 2. How do we get Chrome DevTools Protocol (CDP) access? - --no-sandbox should enable it, but how? - Import of /devtools/main/main.js fails silently - No debugging port open on localhost:9222 - What are we missing? 3. Is there an alternative exploitation path? - Different vulnerability besides XSS? - Different way to access the flag? - Something we're overlooking in the source code? 4. Does the remote challenge differ from local? - Does remote bot.py actually SET a cookie with the flag? - Does remote have debugging port open? - Are there different Chrome flags on remote? 5. What does "solvable locally" mean exactly? - Same exploit works locally and remotely? - Or just the XSS part is testable locally? - Should we see the fake flag locally if we do it right? ═══════════════════════════════════════════════════════════════════════════════ 📁 FILES AVAILABLE ═══════════════════════════════════════════════════════════════════════════════ All exploitation scripts created: - quick_send.py → Sends simple ping test - send_cdp.py → CDP exploitation attempt - send_cdp_debug.py → CDP with step-by-step logging - send_alternatives.py → Alternative methods - auto_send.py → Interactive menu for all payloads - TROUBLESHOOTING_GUIDE.txt → Complete troubleshooting steps - README_CDP_SOLUTION.md → Full CDP exploitation documentation Source code in src/: - app.py → Flask application - bot.py → Selenium bot (has FLAG variable that's never used) - static/app.js → Contains XSS vulnerability - templates/ → HTML templates ═══════════════════════════════════════════════════════════════════════════════ 🎯 BOTTOM LINE ═══════════════════════════════════════════════════════════════════════════════ WE HAVE: ✅ Working XSS that executes in bot context ✅ Ability to exfiltrate any browser-accessible data ✅ Full control over JavaScript execution WE'RE MISSING: ❌ Way to access the FLAG from bot.py ❌ Method to use Chrome DevTools Protocol ❌ Understanding of where flag is actually stored THE EXPLOIT IS WORKING - WE JUST DON'T KNOW WHERE TO LOOK FOR THE FLAG. ═══════════════════════════════════════════════════════════════════════════════