Post

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">

<!-- 代码的作用是告诉浏览器当前页面不被缓存,每次访问都需要去服务器拉取。 -->

cache

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的静态资源了。

攻击危害:

attack

attack

一旦 浏览器缓存资源 被污染

  • 当请求网站时,应用了污染的静态资源,
  • 则会产生xss一类的攻击。
  • 但这种攻击持久性会随缓存时间的到期而终止,又或者用户勤清缓存而解除。

攻击实现:

2020-05-07-15-48-41.png

当攻击者和受害者处于同一WiFi下,攻击者可以利用一些攻击手段,让自己成为受害者的代理,

  • 而当受害者请求目标网站资源时,攻击者可在中间修改。
  • 当目标网站 response 需要缓存的资源时,攻击者可将其替换为自己篡改的同名文件,以达到污染浏览器缓存的目的。
  • 但考虑到缓存存在时效性,如果目标网站认为缓存过期,则污染缓存就会失效
  • 因此如何最大化污染缓存时间成为一个新的问题,但这里我们可以采用如下做法:

2020-05-07-15-51-13.png

可以首先对一些知名网站进行分析,查看他们缓存时间最长的文件,以决定我们污染文件的文件名。

check 缓存时间呢:

  • 利用 Http Header 的属性:
  • Cache-Control : max-age=1000

浏览器污染工具:

  • https://github.com/EtherDream/mitm-http-cache-poisoning.git

Server Cache Poisoning 服务器缓存

attack

  1. 利用恶意的request,使Cache缓存恶意的response,让访问者受到拒绝服务攻击:

1592294799388320

  1. 通过特定的request,可以使目标网站缓存不同的response,例如使静态资源,甚至网站不可用:

1592294800300841

攻击实现:

服务器会缓存某个链接的第一个访问者的response内容

  • 如果第一个人是攻击者,就很有可能让CDN错误的缓存污染内容,达成攻击:

服务器如何判断2个请求者请求的是不是同一个页面

  • by Cache Key 的概念:
  • 服务器会判断橙色字部分,看其是否相同
    • 若相同则对应同一个cache,
    • 但蓝色字体部分其实不同,此时2个访问者的response理应不同,因为他们对应的不同语言,
    • 但因为缓存机制的问题,导致第2个请求者看到了错误语言的页面。

Screen Shot 2020-12-21 at 17.26.23

example 1:

  • response页面中会 拼接 X-Forwarded-Host
  • 假设我们是第一个请求者,此response将会被缓存,
  • attack
  • 那么当下一个请求者再次访问如下链接, 将受到xss的攻击。
  • attack

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

1592294800201069-1

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

1592294801142492

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

1592294801131698

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 的页面

1592294801146974

HMO攻击

  • 对于请求方式覆盖的http属性,测试了哪些后端框架是可以接受的:
  • Play1、Symfony、Lavarel框架都是默认支持这一方式的,
  • 那么如果后端使用上述框架之一,都可能遭受HMO攻击的影响。

1592294802551715

HHO攻击

  • 关键点在于header限制长度语义不对等的问题,测试web框架,CDN等header限制的长度:
  • 假设目标网站使用Play2作为网站后端框架,使用Azure作为缓存,那么即可能遭受HHO攻击,产生Dos攻击,因为 Play2的header长度限制为 8319bytes,而 Azure为 24567bytes
  • 如果攻击者发送 10000bytes 的header进行request
  • 那么就可能被缓存下 400 Bad Request 的状态。

1592294802104968

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或中间件:

1592294803410122


攻击前提

  • 即我们需要是第一个请求某个页面的人

如何做到这一点

  • 利用response里的 Age和 max-age
    • Age代表当前response的时间,
    • max-age代表该页面缓存何时会过期,
  • 以此我们即可计算出投毒时机。

attack

保护网站免收此类攻击

  • by cache key
  • 利用 Vary 指定 Cache Key 为 User-Agent,
  • 那么不仅需要2个访问者请求域名和url相同,同时需要2人拥有同样的User-Agent,才会命中同一块cache。

protect


Web Cache Deception Web缓存欺骗

相较于前两种攻击,该攻击更为普遍,利用也相对容易。不乏其在CTF中出现的频频身影。

Web

例如,

  • 网站 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 时,

  1. 访问 https://www.example.com/home.php/no-existent.css
  2. 浏览器请求 https://www.example.com/home.php/no-existent.css ;
  3. 服务器返回 https://www.example.com/home.php 的内容(通常来说不会缓存该页面);
  4. 响应经过代理服务器;
  5. 代理识别该文件有css后缀;
  6. 在缓存目录下,代理服务器创建目录 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 the user'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:

  1. accessing https://www.example.com/home.php/nonexistent.css, the web server returns the content of home.php for that URL.
  2. Web cache functionality is set for the web application to cache files by their extensions, disregarding any caching headers.
  3. The victim must be authenticated while accessing the malicious URL
  4. web cache功能根据扩展进行保存,并忽略caching header;

攻击实现:

example 1

attack

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页面内容返回,造成信息泄露。

工具设计

2020-06-12-22-01-47.png

利用该攻击 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攻击隐患。攻击做法如下:

  1. 对于指定url:
    • https://example.com/028
    • 在其路径后拼接随机数.css文件:
    • https://example.com/028/.css
  2. 使用受害者账户点击上述网址

  3. 使用攻击者账户点击上述网址,并记录回显

  4. 再次点击上述网址,但此时不带任何cookie,并记录回显

然后对搜集到的response进行提取

  • 查看里面是否有受害者账户的关键信息,
  • 同时判断response中是否带出安全相关属性,例如 : csrf、xsrf、token、state、client-id

实验评估

作者首先在Alexa Top 5K网站中,选取了295个支持Google OAuth的网站:

  • OAuth

将其作为种子池,进行爬取并测试:

  • 种子池

在1470410个网页中

  • 有17293个页面存在WCD攻击,
  • 同时发现对于使用 Cloudflare 和 Akamai CDN 的网站可能更容易受到威胁:
  • WCD

同时在受到WCD的网页中,其可以泄露的私密数据分布如下:

  • victim
  • 不仅用户名泄露较为严重,Sess ID、Auth Code等安全相关的信息泄露也存在一定比例。

并且通过对照观察,在使用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方式,同时发现其分布如下:

2020-06-12-22-19-05.png

可见这些bypass方式可以有效的进行WCD攻击。

  • 同时这些攻击也可以并存
  • 例如既可以使用 %0A 进行WCD攻击,也可以使用 %3F 进行WCD攻击:

2020-06-12-22-20-41.png

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

  1. Configure the cache mechanism
    • to cache files only if their HTTP caching headers allow.
    • 从根本上杜绝该问题;
  2. Store all static files in a designated directory and cache only that directory.
  3. If the cache component provides the option, configure it to cache files by their content type.
    • 如果缓存组件提供选项,设置为根据content-type进行缓存;
  4. 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.

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的一道题为例:

  • CTF
  • 题目预设了request功能,同时注意到其http header:
  • CTF

结合题目提示:cache is vulnerabilities,那么可以判断此处应该为Web缓存欺骗的情况。

需要利用request功能,让其去请求flag页面,再利用缓存信息将内容带出。

  • 首先可以读取主页内容,构造 https://95.179.190.31/index.php/skyiscool.js
  • 此时缓存将会将此url记录,对应内容则为 index.php 的内容。
  • 然后我们再次访问该链接,即可获取 index.php内容:
    • index
  • 再让题目携带 csrf-token 去请求 flag 即可:
    • index
    • https://95.179.190.31/index.php/skyiscool.js?csrf-token=b04d2bc2f3d3654947ba82d59a2b367630743d3447dbc0af46182359f166c4bd%26flag=1
  • 此时再请求缓存页面,即可获取flag:
    • cybrics{Bu9s_C4N_83_uN1N73Nd3D!}

ref:

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

Comments powered by Disqus.