XXE
什么是XXE
XXE(XML External Entity Injection) 全称为 XML 外部实体注入 XML注入 在极客2025里面做过的 用svg标签来得到 当然太局限局限了 继续往下看 XML 文件可以通过 “外部实体”(DOCTYPE 声明中的 ENTITY)引用外部资源,但如果服务器的 XML 解析器未禁用外部实体加载,攻击者就能构造恶意 XML 内容,诱导解析器执行非法操作(比如读取服务器本地文件、访问内部网络等)。
基础知识
- DTD 简单说简单说,DTD 是 XML 的 “格式说明书”:
规定 XML 里能出现哪些元素、属性;
定义元素的嵌套顺序、次数;
统一不同 XML 文档的格式(比如数据交换时保证双方的 XML 结构一致) - 分为 内部 DTD:直接写在 XML 文档里(用
<!DOCTYPE>声明)和 外部 DTD:写在单独的文件里,XML 通过SYSTEM或PUBLIC引用 - ENTITY 可被替换展开的占位符 其实就相当于
1 | <!DOCTYPE test [ |
把name换成了Alice 下面的&是引用前面的
- SYSTEM —— “直接指定位置”
1 | <!ENTITY 实体名 SYSTEM "URI"> |
其实就是
1 | <!ENTITY xxe SYSTEM "file:///etc/passwd"> |
等于直接读取 /etc/passwd 内容
还可以发送http请求 比如
1 | <!ENTITY xxe SYSTEM "http://127.0.0.1:8080/admin"> |
是向 127.0.0.1 发起 HTTP 请求
PUBLIC —— 给一个名字,你自己找(xxe基本用不到 了解一下)
1 | <!ENTITY 实体名 PUBLIC "公共标识符" "URI"> |
一般的例子
1 | <!DOCTYPE html PUBLIC |
前面是一套公共的标准 大概就是规范化命名格式 后面就是System Identifier(系统标识符)给一个找东西的参考地址
- 通用实体 用 &实体名; 引用的实体
- 参数实体 使用 % 实体名(这里面空格不能少) 在 DTD 中定义,并且只能在 DTD 中使用 %实体名 文章里面讲的没有太细 看输了概念觉得也不需要很细 毕竟攻击的源头其实是他们的外部引用 但是这里文章说 参数实体在我们 Blind XXE 中起到了至关重要的作用 边看边记录了
XXE攻击
- 有回显读本地敏感文件(Normal XXE)
其实就是用简单的引用外部实体去得到服务器上的文件 需要满足
服务器 解析了 XML
实体被展开
展开的内容 被返回给你看
1 | <?xml version="1.0" encoding="UTF-8"?> |
假设 然后后端发现 &xxe;
查实体表
发现是 外部实体
读取 file:///etc/passwd
把读取到的内容 当成普通文本插进去
文章这里提到的情况 如果要读取的是有一些特殊情况的文件 比如在XML中,有时实体内包含了些字符,如&,<,>,”,’等。这些均需要对其进行转义,否则会对XML解释器生成错误
用到CDATA
CDATA 是:
告诉 XML 解析器——“这里面的内容当作纯文本,不要当成 XML 语法来解析”
1 | <
