Web缓存欺骗

0x01 概述

在 Web 缓存欺骗攻击中,攻击者诱使受害者访问恶意 URL,诱使受害者的浏览器对敏感内容发出模棱两可的请求。缓存将此错误解释为对静态资源的请求并存储响应。然后,攻击者可以请求相同的 URL 来访问缓存的响应,从而获得对私人信息的未经授权的访问。

image-20250427201703908

0x02 原理

Web缓存

Web缓存是位于源服务器和用户之间的系统。当客户端请求静态资源时,请求首先被定向到缓存。如果缓存未命中 ,则将请求转发到源服务器,该服务器处理并响应请求。然后响应将发送到缓存,然后再发送给客户端。如果缓存命中,则缓存直接将资源发送给客户端。

image-20250427204146332

缓存使用一组预配置的规则来确定是否存储响应。

缓存判断

想要判断某网站是否使用了缓存,可以通过多次请求静态资源,检查响应中是否包含X-cache: hit 这种特征header

0x03 利用方式

1. 静态扩展缓存规则

分隔符指定 URL 中不同元素之间的边界。使用字符和字符串作为分隔符通常是标准化的。例如, 通常用于将 URL 路径与查询字符串分开。但是,由于 URI RFC 非常宽松,因此不同的框架或技术之间仍然存在差异。

例如:Java Spring 框架使用 ; 字符添加称为矩阵变量的参数。因此,使用 Java Spring 的源服务器会将 ; 解释为分隔符。它会截断 /profile 之后的路径并返回配置文件信息。就可以构造如下请求路径来构造恶意url

/profile;test.css

2. 静态目录缓存规则

Web服务器通常将静态资源存储在特定的目录下,缓存规则通常通过匹配特定的URL前缀(例如/image, /static 等)来定位这些目录。这些规则也可能受到Web缓存欺骗的攻击。

缓存和源服务器规范化URL的方式存在差异,可以导致攻击者构建每个解析器以不同的方式解析URL请求路径,例如/static/..%2F/profile 命中了缓存规则,但是服务器却解析为/profile 接口,最终导致缓存了用户的敏感数据。

测试流程:

  1. 首先Fuzz 缓存规则
  2. 然后通过 Fuzz 确定分割符
  3. 然后根据缓存规则和分隔符构造Payload
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
//	fuzz 分隔符
!
"
#
$
%
&
'
(
)
*
+
,
-
.
/
:
;
<
=
>
?
@
[
\
]
^
_
`
{
|
}
~
%21
%22
%23
%24
%25
%26
%27
%28
%29
%2A
%2B
%2C
%2D
%2E
%2F
%3A
%3B
%3C
%3D
%3E
%3F
%40
%5B
%5C
%5D
%5E
%5F
%60
%7B
%7C
%7D
%7E
1
2
3
4
5
# 示例payload:
/profile;aa.js
/profile/aa.js
/static/../profile
/profile;%2F%2E%2E%2Frobots.txt

0x04 漏洞危害

攻击者可以通过发帖url链接,构造csrf攻击等方式,诱导受害者访问恶意构造的url来实现攻击,可以获取到受害者的敏感数据。

0x05 实战场景

这里以某网站举例:

在请求某xxx/xxx/xxx/list/ 接口时响应中并没有包含X-cache 类似的缓存命中的header

image-20250508225043487

这里直接通过扩展名来构造恶意请求

image-20250508225300905

可以看到响应中出现了 X-Cacheheader头,并且是miss状态,即缓存未命中,当我们再次发送该请求时,可以看到响应中的X-Cache 已经变成了 hit 状态,即证明该处存在web缓存欺骗漏洞,并且大概率全站的GET请求都会存在该问题。