1、漏洞理解
1)web缓存机制
当下很多web系统使用web缓存功能来存储一些经常检索的文件,以减少Web服务器响应的延迟和减轻服务器上的负载。常见的缓存内容往往是静态或公共文件:样式表(css),脚本(js),文本文件(txt),图像(png,bmp,gif)等。
如图,当一个用户第一次访问了文件,就会被缓存,下一次当有任何一个其他客户端请求该文件时,缓存机制由于已经存储了这个文件,会把缓存的文件内容发送给客户端而不需要去请求Web服务器,这样就减轻了服务器负载。
缓存通常通过CDN,负载均衡器或简单的反向代理来实现:
A)CND(内容分发网络):代理的分布式网络,目的是快速地提供内容。客户端将由一组离它最近的代理服务器提供服务。
B)负载均衡:除了平衡多个服务器之间的通信量外,负载均衡还可以缓存内容,以减少服务器的延迟。
C)反向代理:代理服务器代表客户端从web服务器检索资源,同时可以缓存web应用程序的一些内容
2)Web缓存欺骗
Web缓存欺骗(Web Cache Deception)是一种新的Web攻击向量,在2017年第一次被Omer Gil提出(阅读原文)。它的漏洞原理和RPO (Relative Path Overwrite)相对路径覆盖漏洞较为类似,根因都在于浏览器和网络服务器对相同URL请求的解析不一致(宽字节、00截断也是)。通过“欺骗”用户访问一个不存在的静态页面,从而使敏感页面保存在缓存中,从而窃取用户敏感信息,通常是用户个人信息、业务敏感数据等,如果响应的主体中包含了用户的会话标识符、CSRF令牌可进一步可导致ATO。
3)Web缓存中毒
Web缓存中毒(Web Cache Poisonning)和缓存欺骗通常被混淆,它的攻击方式是通过X-Forwarded-Host头,发送导致有害响应的请求,该响应将保存在缓存中并提供给其他用户,其他用户访问到此页面时将不是正常页面,而是被攻击者“中毒”之后的的页面,产生的危害通常是XSS,也可能导致信息泄露。
除了使用这个HTTP头来破坏缓存,还可以使用HTTP响应拆分(CRLF)和请求走私(RequestSmuggling)来完成攻击,这几个技术点后续补充。
1)缓存欺骗
如果代理服务器设置为缓存静态文件,忽略这类文件的caching header时,对于url地址http://www.example.com/myaccount/包含用户账户信息。攻击流程如下: 1)诱使用户通过浏览器请求不存在的css文件:http://www.example.com/myaccount/no-existent.css ;
2)由于服务器无法解析css文件,只能解析到myaccount/,所以返回myaccount/的内容。
3)此时响应经过反向代理服务器Nginx;
4)代理识别该文件有css后缀,在缓存目录下,代理服务器创建目录myaccount,将返回的内容作为 non-existent.css 保存;
5)攻击者请求相同链接,将得到缓存中的内容,即myaccount的敏感内容。
2)缓存中毒
缓存中毒的攻击流程很简单,最相像的漏洞利用是CORS,即在正常请求中添加X-Forwarded-Host头,对于这个XFH头的解释:
发送请求,可以看到系统使用X-Forwarded-Host头在元标记内生成OpenGraph URL:
很容易想到攻击思路,构造xss:
此时,这个响应已经被保存到缓存中,此时受害者正常请求此地址则会得到被中毒后的页面,从而被遭到xss攻击:
1) PayPal缓存欺骗
原理讲解中的真实案例,https://www.paypal.com/myaccount/home页面返回的是用户Omer账户信息:
追加malicious3.css访问不存在的资源,返回的依旧是原页面,但此时缓存中已经创建了名为home的目录,里面缓存了此页面:
打开一个新的浏览器(攻击者),访问此页面,获取到敏感页面:
此漏洞同样存在于Paypal的设置、历史页面等,Omer Gil因此被奖励了$3000。
2) 404页面缓存敏感信息
缓存欺骗的一个特殊案例,在某些情况下我们请求一个不存在的静态资源,返回404 error,虽然访问不到当前的业务数据,但还是在系统框架中:
查看源,虽然session没有被缓存,但用户信息已经被缓存:
3) Smule缓存中毒利用
web缓存中毒最常见的是攻击效果是XSS,有时也可以达到用户信息泄露及账户接管的攻击效果,如Smule请求端点
https://www.smule.com/s/smule_groups/user_groups/user_name,添加X-Forwarded-Hos头为 localhost:
系统接受了这个头并修改为页面的跳转链接,并将其保存至缓存中:
受害者访问此页面,将使用上述链接进行登录,请求变为:
攻击者可在自己的服务器上创建脚本,模仿web服务器端响应包,从而窃取用户CSRF token等敏感信息。
在挖掘web cache漏洞的时候首先要确定web系统架设了CDN,负载均衡器或反向代理等缓存设备,其次观察返回头是否设置缓存控制头Cache Control:no-cache,max-age=0,private,no-store,若未设置则很大可能存在此漏洞。
当然即使存在缓存标头也要尝试下,即使缺少缓存头,也不代表一定会获得缓存信息攻击。除此之外:
1)缓存欺骗
此漏洞存在需要满足两个条件:
1)Web缓存功能设置为通过URL的扩展名来判断是否进行缓存文件,且忽略任何缓存头。
2)当访问类似
http://www.example.com/home.php/non-existent.css不存在的页面,返回home.php 的内容而不是“页面不存在”。
3)诱使访问URL时,受害者必须已经经过身份验证。
附带一个自动挖掘工具:
https://github.com/arbazkiraak/web-cache-deception-checker
2)缓存中毒
探测过程较简单,添加X-Forwarded-Host头观察是否在返回包中回显(通常是生成的链接link)。
防御措施主要包括3点:
1)设置缓存机制,仅仅缓存httpcaching header允许的文件,推荐的防御手段;
2)如果缓存组件提供选项,设置为根据content-type进行缓存;
3)访问类似home.php/non-existent.css不存在的静态页面时候,不返回 home.php 的内容,而返回404或者302,即对任何不存在的路径都不应等效为对有效父路径的的请求。