zoukankan      html  css  js  c++  java
  • 浅谈XXE

    转自FReeBUF

     

    0×00. 介绍

    现在越来越多主要的web程序被发现和报告存在XXE(XML External Entity attack)漏洞,比如说facebook、paypal等等。 举个例子,我们扫一眼这些网站最近奖励的漏洞,充分证实了前面的说法。尽管XXE漏洞已经存在了很多年,但是它从来没有获得它应得的关注度。很多XML的解析器默认是含有XXE漏洞的,这意味着开发人员有责任确保这些程序不受此漏洞的影响。 

    本文主要讨论什么是XML外部实体,这些外部实体是如何被攻击的。

    0×01. 什么是XML外部实体?

    如果你了解XML,你可以把XML理解为一个用来定义数据的东东。因此,两个采用不同技术的系统可以通过XML进行通信和交换数据。 比如,下图就是一个用来描述一个职工的XML文档样本,其中的’name’,'salary’,'address’ 被称为XML的元素。

    Image

    有些XML文档包含system标识符定义的“实体”,这些XML文档会在DOCTYPE头部标签中呈现。这些定义的’实体’能够访问本地或者远程的内容。比如,下面的XML文档样例就包含了XML ‘实体’。

    Image

    在上面的代码中, XML外部实体 ‘entityex’ 被赋予的值为:file://etc/passwd。在解析XML文档的过程中,实体’entityex’的值会被替换为URI(file://etc/passwd)内容值(也就是passwd文件的内容)。 关键字’SYSTEM’会告诉XML解析器,’entityex’实体的值将从其后的URI中读取。因此,XML实体被使用的次数越多,越有帮助。

    0×02. 什么是XML外部实体攻击?

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

    Image

    0×03. 怎么甄别一个XML实体攻击漏洞?

    最直接的回答就是: 甄别那些接受XML作为输入内容的端点。 但是有时候,这些端点可能并不是那么明显(比如,一些仅使用JSON去访问服务的客户端)。在这种情况下,渗透测试人员就必须尝试不同的测试方式,比如修改HTTP的请求方法,修改Content-Type头部字段等等方法,然后看看应用程序的响应,看看程序是否解析了发送的内容,如果解析了,那么则可能有XXE攻击漏洞。

    0×04. 如何确认XXE漏洞?

    出于演示的目的,我们将用到一个Acunetix维护的demo站点,这个站点就是: http://testhtml5.vulnweb.com/。这个站点可用于测试Acunetix web扫描器的功能。 访问 http://testhtml5.vulnweb.com/ 站点,点击 ‘Login’下面的 ‘Forgot Password’ 链接。注意观察应用程序怎样使用XML传输数据,过程如下图所示:

    请求:

    Image

    响应:

    Image

    观察上面的请求与响应,我们可以看到,应用程序正在解析XML内容,接受特定的输入,然后将其呈现给用户。为了测试验证XML解析器确实正在解析和执行我们自定义的XML内容,我们发送如下的请求

    修改后的请求和响应:

    Image

    如上图所示,我们在上面的请求中定义了一个名为myentity、值为’testing’的实体。 响应报文清晰地展示了解析器已经解析了我们发送的XML实体,然后并将实体内容呈现出来了。 由此,我们可以确认,这个应用程序存在XXE漏洞。

    0×05. 如何进行XXE攻击?

    Code 1:

    1. To read files on same server:

    <?xml version="1.0" encoding="ISO-8859-1"?>

    <!DOCTYPE foo [ 

    <!ENTITY myentity SYSTEM "file:///location/anyfile" >]>

    <abc>&myentity;</abc>

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

    <?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中的XXE漏洞攻击就是著名的’billion laughs’(https://en.wikipedia.org/wiki/Billion_laughs)攻击,该攻击通过创建一项递归的 XML 定义,在内存中生成十亿个”Ha!”字符串,从而导致 DDoS 攻击。原理为:构造恶意的XML实体文件耗尽可用内存,因为许多XML解析器在解析XML文档时倾向于将它的整个结构保留在内存中,解析非常慢,造成了拒绝服务器攻击。除了这些,攻击者还可以读取服务器上的敏感数据,还能通过端口扫描,获取后端系统的开放端口。

    影响:

    此漏洞非常危险, 因为此漏洞会造成服务器上敏感数据的泄露,和潜在的服务器拒绝服务攻击。

    补救措施:

    上面讨论的主要问题就是XML解析器解析了用户发送的不可信数据。然而,要去校验DTD(document type definition)中SYSTEM标识符定义的数据,并不容易,也不大可能。大部分的XML解析器默认对于XXE攻击是脆弱的。因此,最好的解决办法就是配置XML处理器去使用本地静态的DTD,不允许XML中含有任何自己声明的DTD。

    比如下面的Java代码,通过设置相应的属性值为false,XML外部实体攻击就能够被阻止。因此,可将外部实体、参数实体和内联DTD 都被设置为false,从而避免基于XXE漏洞的攻击。 

    以下是代码的第二段

    import javax.xml.parsers.DocumentBuilderFactory;

    import javax.xml.parsers.ParserConfigurationException; // catching unsupported features

    ...

    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();

    try {

    // Xerces 1 - http://xerces.apache.org/xerces-j/features.html#external-general-entities

    // Xerces 2 - http://xerces.apache.org/xerces2-j/features.html#external-general-entities

    String FEATURE = "http://xml.org/sax/features/external-general-entities";

    dbf.setFeature(FEATURE, false);

    // Xerces 1 - http://xerces.apache.org/xerces-j/features.html#external-parameter-entities

    // Xerces 2 - http://xerces.apache.org/xerces2-j/features.html#external-parameter-entities

    FEATURE = "http://xml.org/sax/features/external-parameter-entities";

    dbf.setFeature(FEATURE, false);

    // Xerces 2 only - http://xerces.apache.org/xerces2-j/features.html#disallow-doctype-decl

    FEATURE = "http://apache.org/xml/features/disallow-doctype-decl";

    dbf.setFeature(FEATURE, true);

    // remaining parser logic

    ...

    catch (ParserConfigurationException e) {

    // This should catch a failed setFeature feature

    logger.info("ParserConfigurationException was thrown. The feature '" +

    FEATURE +

    "' is probably not supported by your XML processor.");

    ...

    }

    catch (SAXException e) {

    // On Apache, this should be thrown when disallowing DOCTYPE

    logger.warning("A DOCTYPE was passed into the XML document");

    ...

    }

    catch (IOException e) {

    // XXE that points to a file that doesn't exist

    logger.error("IOException occurred, XXE may still possible: " + e.getMessage());.. }

  • 相关阅读:
    java基础部分的一些有意思的东西。
    antdvue按需加载插件babelpluginimport报错
    阿超的烦恼 javaScript篇
    .NET E F(Entity Framework)框架 DataBase First 和 Code First 简单用法。
    JQuery获得input ID相同但是type不同的方法
    gridview的删除,修改,数据绑定处理
    jgGrid数据格式
    Cannot read configuration file due to insufficient permissions
    Invoke action which type of result is JsonResult on controller from view using Ajax or geJSon
    Entity model数据库连接
  • 原文地址:https://www.cnblogs.com/drkang/p/8450113.html
Copyright © 2011-2022 走看看