1. 核心原理:什么是 XXE?
XXE 漏洞发生在应用程序解析 XML 输入时。如果没有禁止外部实体 (External Entities) 的加载,攻击者可以干扰 XML 数据的处理。
-
XML (可扩展标记语言): 用于存储和传输数据。
-
DTD (文档类型定义): 用来定义 XML 文档的结构。在 DTD 中,你可以定义"实体"(Entity),这有点像编程中的变量。
-
外部实体: 这种实体的值不是直接定义的,而是从外部资源(如本地文件系统或 URL)加载的。
漏洞逻辑:
-
你向服务器发送一段 XML。
-
你在 XML 中定义了一个恶意的外部实体(比如叫
&xxe;),告诉解析器:"去读取file:///etc/passwd这个文件的内容,并把它赋值给xxe这个变量"。 -
你在数据字段中使用了这个变量
&xxe;。 -
服务器解析 XML,乖乖地去读取了
/etc/passwd,然后把文件内容放进了数据字段。 -
服务器在报错或响应中把这个字段的内容(即文件内容)回显给了你。
2. 具体解题步骤 (Step-by-Step)
你需要使用 Burp Suite 来拦截并修改请求。
第一步:分析正常请求
-
进入靶场(Access the lab)。
-
随便点击一个产品的 "View details"。
-
点击页面下方的 "Check stock" (检查库存) 按钮。
-
在 Burp Suite 的
Proxy->HTTP history中找到这个 POST 请求
看到请求体是这样的 XML 结构:
XML
<?xml version="1.0" encoding="UTF-8"?>
<stockCheck>
<productId>
2
</productId>
<storeId>
1
</storeId>
</stockCheck>
第二步:构造 Payload (攻击载荷)
我们需要做两件事:
-
定义实体 :在 XML 声明(第一行)之后,根元素(
<stockCheck>)之前,插入 DTD 定义。 -
调用实体 :把
productId的值替换成我们需要引用的实体。
修改后的 XML 如下:
XML
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE test [ <!ENTITY xxe SYSTEM "file:///etc/passwd"> ]>
<stockCheck>
<productId>&xxe;</productId>
<storeId>1</storeId>
</stockCheck>
代码解释:
-
<!DOCTYPE test [...]>: 定义了一个名为test的 DTD。 -
<!ENTITY xxe SYSTEM "file:///etc/passwd">: 定义了一个名为xxe的外部实体。关键字SYSTEM告诉解析器这是一个外部引用,通过file://协议去读取 Linux 系统下的密码文件/etc/passwd。 -
&xxe;: 在productId标签内引用这个实体。当解析器读到这里时,会把刚才读到的/etc/passwd内容填在这里。
第三步:发送并观察结果
-
在 Burp Suite 中,将修改后的请求发送(点击 Forward 或 Send to Repeater 后发送)。
-
观察服务器的 Response (响应)。
因为题目描述说:"返回响应中任何意外的值" (returns any unexpected values in the response),通常服务器会报错说"无效的产品ID:[你注入的内容]"。
你看到的响应应该包含类似以下的内容:
这就意味着你成功读取了服务器的 /etc/passwd 文件。
3. 为什么会成功?
这个靶场之所以能被攻破,是因为后端处理 XML 的解析器配置不当:
-
未禁用 DTD:允许用户自定义文档类型定义。
-
未禁用外部实体 :允许解析器通过
SYSTEM关键字去加载外部资源(文件)。 -
有回显:应用程序将解析后的结果(即使是作为错误信息的一部分)返回给了前端。