Meow's CyberAttack - - Web cache posion
Meow’s CyberAttack - Web cache posion
背景知识
在请求网站时,会遇到 js,css,图片等等的加载, 如果每次请求都加载一次,服务器可能会消耗许多时间, 因此服务器缓存尤为重要,其中CDN就是Web Server Cache的一个典例
- 网站通常都会通过如CDN、负载均衡器、或者反向代理来实现
Web缓存功能
。- 通过缓存频繁访问的文件,降低服务器响应延迟。 因此浏览器中可引入Cache,用以缓存静态资源,以加快访问速度。
浏览器缓存控制机制有两种:
HTML Meta标签
以及HTTP头信息
- 通常,web开发者可以在HTML页面的<head>节点中加入标签,比如:
1
2
3
4
#!html
<META HTTP-EQUIV="Pragma" CONTENT="no-cache">
<!-- 代码的作用是告诉浏览器当前页面不被缓存,每次访问都需要去服务器拉取。 -->
访问链接在第一个人访问后,其页面response将会被CDN缓存,下一个请求者则会直接从CDN获取response
- 减轻服务器处理请求的压力,
- 同时达到了防止Dos攻击的目的。
- 加快请求速度,例如我们访问服务器,请求首先会被CDN处理,计算出response给我们的最优ip地址。
但如果Cache被攻击者利用,也可以产生一些严重的攻击, 聚焦于以下3种攻击:
- User Browser Cache Poisoning
- Server Cache Poisoning
- Web Cache Deception
User Browser Cache Poisoning 浏览器缓存投毒
影响浏览器缓存的文件,将其污染以达到攻击目的。
- 可能被污染的文件: 浏览器一般缓存 静态资源 ,攻击者的攻击目标也就是诸如JS、CSS的静态资源了。
攻击危害:
一旦 浏览器缓存资源 被污染
- 当请求网站时,应用了污染的静态资源,
- 则会产生xss一类的攻击。
- 但这种攻击持久性会随缓存时间的到期而终止,又或者用户勤清缓存而解除。
攻击实现:
当攻击者和受害者处于同一WiFi下,攻击者可以利用一些攻击手段,让自己成为受害者的代理,
- 而当受害者请求目标网站资源时,攻击者可在中间修改。
- 当目标网站 response 需要缓存的资源时,攻击者可将其替换为自己篡改的同名文件,以达到污染浏览器缓存的目的。
- 但考虑到缓存存在时效性,如果目标网站认为缓存过期,则污染缓存就会失效
- 因此如何最大化污染缓存时间成为一个新的问题,但这里我们可以采用如下做法:
可以首先对一些知名网站进行分析,查看他们缓存时间最长的文件,以决定我们污染文件的文件名。
check 缓存时间呢:
- 利用
Http Header
的属性: Cache-Control : max-age=1000
浏览器污染工具:
- https://github.com/EtherDream/mitm-http-cache-poisoning.git
Server Cache Poisoning 服务器缓存
- 利用恶意的request,使Cache缓存恶意的response,让访问者受到拒绝服务攻击:
- 通过特定的request,可以使目标网站缓存不同的response,例如使静态资源,甚至网站不可用:
攻击实现:
服务器会缓存某个链接的第一个访问者的response内容
- 如果第一个人是攻击者,就很有可能让CDN错误的缓存污染内容,达成攻击:
服务器如何判断2个请求者请求的是不是同一个页面
- by Cache Key 的概念:
- 服务器会判断橙色字部分,看其是否相同
- 若相同则对应同一个cache,
- 但蓝色字体部分其实不同,此时2个访问者的response理应不同,因为他们对应的不同语言,
- 但因为缓存机制的问题,导致第2个请求者看到了错误语言的页面。
example 1:
example 2:
攻击者可以发送一个带有 恶意值(X-Malicious-Header) 的request请求
- 由于该请求是第一次请求,因此其不存在于Cache中,
- 于是交由Origin Server进行处理,
- 但是由于http header中存在非法值,导致Origin Server解析时出现400的错误,并进行response,
- 而此时由于Cache服务器的设置问题,其错误的将请求
example.org/index.html
的请求,判定为response为400
- 从而导致以后的访问者再次访问该页面时,只能得到页面400错误的response
- 从而达成Dos攻击。
可以发送的使网站出现解析异常的恶意value:
- HTTP Method
Override (HMO) Attack
- HTTP Header
Oversize (HHO) Attack
- HTTP
Meta Character (HMC) Attack
HTTP Method Override (HMO) Attack
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 存在一些http header可以更改请求方式,例如如下几种:
X-HTTP-Method-Override
X-HTTP-Method
X-Method-Override
# 假设请求发送形式为:
GET /index.html HTTP/1.1
Host: example.org
X-HTTP-Method-Override: POST
# 此时服务器则会认为该请求为POST请求,于是会返回:
HTTP/1.1 404 Not Found
Content-Length: 29
Content-Type: text/plain
POST on /index.html not found
# 从而导致请求资源方式的错误,以至于Cache服务器缓存404页面
# 而以后的用户,如果正常通过GET访问该网址,则会导致DOS攻击,回显404 Not Found:
HTTP Header Oversize (HHO) Attack
1
2
3
4
5
6
7
8
9
但该攻击为什么会发生:
例如CDN,是会对过长的request进行拦截的,并不会进行缓存或者发送至源服务器。
但对于一个request请求,其header长度通常被限制在 8,000 bytes 以下,
例如Amazon CloudFront CDN允许的header长度却为 24,713 bytes。
因此如果攻击者发送的header长度为10,000bytes,是可以通过CDN的拦截,并产生危害的。
HTTP Meta Character (HMC) Attack
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 为了防止CRLF攻击,通常http会禁止value中带有\n或\r等符号
# 但由于Cache对此可能并不做过滤,那么就会产生语义上的gap
# 假设攻击者发送请求:
GET /index.html HTTP/1.1
Host: example.org
X-Metachar-Header: \n
# 由于该请求为第一次请求,Cache服务器将其转发给源服务器
# 而源服务器解析由于遇到危险字符,将会返回:
HTTP/1.1 400 Bad Request
Content-Length: 21
Content-Type: text/plain
Character not allowed
# 但由于Cache服务器对这些字符未必有过滤,于是将其对应缓存下来,那么当正常用户访问该页面时,将受到400 Bad Request的回显,从而产生Dos攻击。
实验测试
作者为了验证自己的3种攻击方式的可用性,其选择5个较为出名的proxies caches以及10个CDN:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Apache HTTP Server (Apache HTTPD) v2.4.18
Nginx v1.10.3,
Varnish v6.0.1
Apache Traffic Server (Apache TS) v8.0.2
Squid v3.5.12
Akamai
CloudFront
Cloudflare
Stackpath
Azure
CDN77
CDNSun
Fastly
KeyCDN
G-Score Labs
为了达成Dos攻击,那么要求上述缓存服务器必须可以缓存400 / 500等http状态的页面
- 只有
Varnish, Apache TS, Akamai, Azure, CDN77, Cloudflare, CloudFront
可以缓存400 / 500
的页面
HMO攻击
- 对于请求方式覆盖的http属性,测试了哪些后端框架是可以接受的:
- Play1、Symfony、Lavarel框架都是默认支持这一方式的,
- 那么如果后端使用上述框架之一,都可能遭受HMO攻击的影响。
HHO攻击
- 关键点在于header限制长度语义不对等的问题,测试web框架,CDN等header限制的长度:
- 假设目标网站使用Play2作为网站后端框架,使用Azure作为缓存,那么即可能遭受HHO攻击,产生Dos攻击,因为 Play2的header长度限制为 8319bytes,而 Azure为 24567bytes
- 如果攻击者发送
10000bytes
的header进行request - 那么就可能被缓存下
400 Bad Request
的状态。
HMC攻击
- 依赖于服务端对 http header中关键字符的过滤,而缓存服务器则无视的语义差异
- 当http header属性中带有
\t
,对于Play2后端框架会发生400 Bad Request
, - 而对于CDN Azure,可以正常放行
- 如此攻击即可用
\t
来攻击Play2+Azure
的组合,产生Dos攻击。
对于使用CDN CloudFront的网站,非常容易受到 HMO / HHO / HMC的攻击。 而对于Varnish, Akamai, CDN77, Cloudflare或是Fastly则相对安全。
有多少网站使用较为危险的CDN或中间件:
攻击前提
- 即我们需要是第一个请求某个页面的人
如何做到这一点
- 利用response里的 Age和 max-age
- Age代表当前response的时间,
- max-age代表该页面缓存何时会过期,
- 以此我们即可计算出投毒时机。
保护网站免收此类攻击
- by cache key
- 利用 Vary 指定 Cache Key 为 User-Agent,
- 那么不仅需要
2个访问者请求域名和url相同
,同时需要2人拥有同样的User-Agent
,才会命中同一块cache。
Web Cache Deception Web缓存欺骗
相较于前两种攻击,该攻击更为普遍,利用也相对容易。不乏其在CTF中出现的频频身影。
例如,
- 网站
htttp://www.example.com
配置了反向代理。 - 对于包含用户个人信息的页面,如
https://www.example.com/home.php
,由于每个用户返回的内容有所不同,因此这类页面通常是动态生成,并不会在缓存服务器中进行缓存。 - 通常缓存的主要是可公开访问的静态文件,如
css文件、js文件、txt文件、图片
等等。 - 此外,很多最佳实践类的文章也建议,对于那些能公开访问的静态文件进行缓存,并且忽略HTTP缓存头。
Web cache攻击类似于RPO相对路径重写攻击,都 依赖于浏览器与服务器对URL的解析方式
- 当访问不存在的URL时,如
https://www.example.com/home.php/non-existent.css
- 浏览器发送get请求,依赖于使用的技术与配置,服务器返回了页面
https://www.example.com/home.php
的内容 - 同时URL地址仍然是
https://www.example.com/home.php/non-existent.css
, - http头的内容也与直接访问
https://www.example.com/home.php
相同,cacheing header、content-type(此处为text/html)也相同。
漏洞成因
当代理服务器设置为 缓存静态文件 并 忽略这类文件的caching header 时,
- 访问
https://www.example.com/home.php/no-existent.css
- 浏览器请求
https://www.example.com/home.php/no-existent.css
; - 服务器返回
https://www.example.com/home.php
的内容(通常来说不会缓存该页面); - 响应经过代理服务器;
- 代理识别该文件有css后缀;
- 在缓存目录下,代理服务器创建目录
home.php
,将返回的内容作为non-existent.css
保存。
漏洞利用
A successful exploitation will cause the vulnerable page – containing the user's personal content – to be cached and thus publicly accessible.
- This is a cached, static version of the file; the attacker cannot impersonate the victim.
- The file cannot be overridden, and remains valid until it expires.
- 导致含有用户个人信息的页面被缓存,从而能被公开访问到。
- The impact can increase significantly
if the body of the response
contains theuser's session identifier (for some reason)
,security answers
,CSRF tokens
, etc.- 如果返回的内容包含session标识、安全问题的答案,或者csrf token。这样攻击者能接着获得这些信息,因为通常而言大部分网站静态资源都是公开可访问的。
- leveraged to additional attacks, and lead to a complete account takeover.
漏洞条件
Three conditions must be met in order for an attacker to perform web cache deception:
- accessing
https://www.example.com/home.php/nonexistent.css
, the web server returns the content ofhome.php
for that URL. - Web cache functionality is set for the web application to cache files by their extensions, disregarding any caching headers.
- The victim must be authenticated while accessing the malicious URL
- web cache功能根据扩展进行保存,并忽略caching header;
攻击实现:
example 1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 诱导管理员访问链接:
https://10.2.122.1/secret.php/test.css
# 由于是第一次访问,Web Cache将其转发给源服务器,
# 服务器处理该链接源服务器在解析时,由于中间件或者后端配置问题,将其解析为访问/secret.php路由,并进行response,而此时Web Cache将其对应记录。
# 由于test.css不存在,其会向前解析,如下:
https://10.2.122.1/secret.php
# 此时response页面即为secret.php的页面内容,而CDN对此不知,其认为当请求链接为:
https://10.2.122.1/secret.php/test.css
# response应为管理员的secret.php页面内容。
# 而后攻击者再次请求:
https://10.2.122.1/secret.php/test.css
# CDN将作出响应,将管理员的secret.php页面内容返回,造成信息泄露。
工具设计
利用该攻击 WCD(Web Cache Deception) 的场景为:
- 网站有一些私有信息,只能由用户访问,
- 但因为Web Cache欺骗,致使其他用户可以访问到这些数据。
- 这就是一次WCD(Web Cache Deception)攻击。
首先作者进行了网站搜集,其建立一个种子池:
- 然后使用启发式工具,发现池中网站的子域名,以此扩充数据集。
- 然后对每个网站进行账户创建,此时分别创立2个用户:攻击者用户与受害者用户。
- 此举旨在后期利用攻击者用户获取受害者用户数据。
- 同时还会使用爬虫搜集攻击者与受害者的cookies信息,以判断WCD攻击是否需要依赖于Cookies。
值得注意的是,在搜集网站的时候,由于利用种子池中的域名,进行启发式搜集 那么爬虫可能遇到大量相似的url: 这样的遍历和循环非常的浪费时间,于是作者设置了上限,诸如此类的url,每个域名只随机挑选500个。
1
2
3
4
5
6
7
https://example.com/?lang=en
https://example.com/?lang=fr
https://example.com/?lang=cn
https://example.com/028
https://example.com/142
https://example.com/359
在上述准备工作完毕后,则使用工具以此测试每个url是否存在WCD攻击隐患。攻击做法如下:
- 对于指定url:
https://example.com/028
- 在其路径后拼接随机数.css文件:
https://example.com/028/.css
使用受害者账户点击上述网址
使用攻击者账户点击上述网址,并记录回显
- 再次点击上述网址,但此时不带任何cookie,并记录回显
然后对搜集到的response进行提取
- 查看里面是否有受害者账户的关键信息,
- 同时判断response中是否带出安全相关属性,例如 :
csrf、xsrf、token、state、client-id
实验评估
作者首先在Alexa Top 5K网站中,选取了295个支持Google OAuth的网站:
将其作为种子池,进行爬取并测试:
在1470410个网页中
同时在受到WCD的网页中,其可以泄露的私密数据分布如下:
并且通过对照观察,在使用cookie和不使用cookie时,攻击结果一致
- 说明WCD攻击不依赖于授权用户或带有cookie的访问者。
- 进一步提升了该攻击的危害性,降低攻击成本。
同时,作者还提出了相应的bypass方式,其发现不仅诸如如下请求方式可以进行WCD攻击:使用其他一些手段也可以达成相应的目的:
1
2
3
4
5
/account.php/nonexistent.jpg
/account.php%0Anonexistent.jpg
/account.php%3Bnonexistent.jpg
/account.php%23nonexistent.jpg
/account.php%3Fnonexistent.jpg
同时作者进一步加大了数据集,用于测试新的payload方式,同时发现其分布如下:
可见这些bypass方式可以有效的进行WCD攻击。
- 同时这些攻击也可以并存
- 例如既可以使用
%0A
进行WCD攻击,也可以使用%3F
进行WCD攻击:
example 2
1
2
3
4
5
6
7
# 1. The attacker lures a logged-on user to access https://www.bank.com/account.do/logo.png.
# 2. The victim's browser requests https://www.bank.com/account.do/logo.png.
# 3. The request arrives to the proxy, which is not familiar with this file, and therefore asks the web server for it.
# 4. The web server returns the content of the victim's account page with a 200 OK response, meaning the URL stays the same.
# 5. The caching mechanism receives the file and identifies that the URL ends with a static extension (.png). Because the mechanism is configured to cache all static files and disregard any caching headers, the imposter .png file is cached. A new directory named account.do is created in the cache directory, and the file is cached with the name logo.png.
# 6. The user receives his account page.
# 7. The attacker accesses https://www.bank.com/account.do/logo.png. The request arrives to the proxy server, which directly returns the victim’s cached account page to the attacker's browser.
漏洞防御 MITIGATIONS
- Configure the
cache mechanism
- to cache files only if their
HTTP caching headers
allow. - 从根本上杜绝该问题;
- to cache files only if their
- Store all static files in a designated directory and cache only that directory.
- If the cache component provides the option, configure it to cache files by their content type.
- 如果缓存组件提供选项,设置为根据content-type进行缓存;
- Configure the web server
- so pages like
https://www.example.com/home.php/nonexistent.css
, - the web server does not return the content of
home.php
with the triggering URL; - instead, the server should return a
404 or 302
response.
- so pages like
Web Cache欺骗攻击实例
Paypal Paypal在未修复之前,通过该攻击,可以获取的信息包括:用户姓名、账户金额、信用卡的最后4位数、交易数据、emaill地址等信息。受该攻击的部分页面包括:
https://www.paypal.com/myaccount/home/attack.css
https://www.paypal.com/myaccount/settings/notifications/attack.css
https://history.paypal.com/cgi-bin/webscr/attack.css?cmd=_history-details
。
此种攻击在2019 CyBRICS CTF Quals或2019 XCTF Final都有出现,
以2019 CyBRICS CTF Quals的一道题为例:
结合题目提示:cache is vulnerabilities,那么可以判断此处应该为Web缓存欺骗的情况。
需要利用request功能,让其去请求flag页面,再利用缓存信息将内容带出。
- 首先可以读取主页内容,构造
https://95.179.190.31/index.php/skyiscool.js
- 此时缓存将会将此url记录,对应内容则为
index.php
的内容。 - 然后我们再次访问该链接,即可获取 index.php内容:
- 再让题目携带 csrf-token 去请求 flag 即可:
- 此时再请求缓存页面,即可获取flag:
cybrics{Bu9s_C4N_83_uN1N73Nd3D!}
ref:
- https://drops.xmd5.com/static/drops/tips-9947.html
- https://skysec.top/2019/07/22/CyBRICS-CTF-Quals-2019-Web-Writeup/#Fixaref
- https://www.blackhat.com/docs/us-17/wednesday/us-17-Gil-Web-Cache-Deception-Attack-wp.pdf
- WHITE PAPERWEB CACHE DECEPTION ATTACK
- Web缓存利用分析(一)
- Web缓存利用分析(二)
- Web缓存利用分析(三)
- Cached and Confused: Web Cache Deception in the Wild
- practical web cache poisoning
- End-Users Get Maneuvered: Empirical Analysis of Redirection Hijacking in Content Delivery Networks
Comments powered by Disqus.