• XML外部实体注入漏洞(一)


    警告

    请勿使用本文提到的内容违反法律
    本文不提供任何担保

    目录

    警告

    一、 基础知识

    (一)xml概述

    (二)xml用处

     (三)xml注入

    (四)XXE注入漏洞

    (五)XXE注入危害

    二、XML基础知识学习

    (一)xml示例学习

    (二)XML的格式

    (三)XML验证


    一、 基础知识

    (一)xml概述

            xml(eXtensibleMarkup Language),可扩展标记语言,使用简单的标记来描述数据。xml是一种非常灵活的语言,类似于HTML语言,但是并没有固定的标签,所有的标签都可以自定义,其设计的宗旨是传输数据,而不是像HTML一样显示数据。xml不会做任何事情,它是被设计用来结构化、存储以及传输信息,也就是xml文件所携带的信息,需要被其他的语言或者程序来解析,才能发挥作用。

    (二)xml用处

            xml被用于信息的记录传递(比如,数据库的导出导入会很麻烦,但是xml会很方便),也会被用于充当配置文件。也会被应用于Web 开发的许多方面,常用于简化数据的存储和共享。如:

    • XML 把数据从 HTML 分离,更方便在HTML文档中显示动态数据。
    • XML 简化数据共享,XML数据以纯文本格式进行存储,因此提供了一种独立于软件和硬件的数据存储方法。这让创建不同应用程序可以共享的数据变得更加容易。
    • XML 简化数据传输,由于可以通过各种不兼容的应用程序来读取数据,以 XML 交换数据降低了不兼容系统之间交换书据的复杂性。
    • XML 简化平台变更,使用XML存储一些不兼容的数据,可以在系统或软件升级,转换大量的数据时,避免数据的丢失。
    • XML 使您的数据更有用,XML可以使不同的应用程序都能够访问您的数据,使得数据的用途更广。
    • XML 用于创建新的互联网语言,如XHTML、WSDL、WAP 和 WML、RSS 、RDF 和 OWL等

     (三)xml注入

            XML与HTML一样,也存在注入漏洞。比如:一个 web 应用,在进行用户注册时,选择以 xml 来存储数据到 xmldb 数据库中,当用户填写用户名,密码和邮箱时,后台存储的文件格式及内容如下:

            那么攻击者就可以在注册的时候构造恶意的数据,假设他在用户名与密码的输入框中输入正常的文本,在最后的邮箱输入框中输入如下内容:

            那么就会多注册一个名为admin的用户。综合上面的小例子,我们可以知道,能够进行XML注入攻击的前提是,用户能够控制数据的输入,程序没有对输入的内容进行过滤且拼接了数据。那么相应的,破坏掉其中一个前提就可以进行防御了,既然我们无法限制用户的输入,那么就可以对数据进行过滤,将XML语言本身的“保留字符”进行过滤或者转义即可。

    (四)XXE注入漏洞

            XXE注入也是XML注入的一部分,但相较于普通的XML注入,XXE注入的攻击面更广,危害更大。 XXE注入(XML External Entity Injection) 全称为 XML 外部实体注入,从名字就能看出来,所注入的对象就是我们实验任务一中提到的重点: XML外部实体。当遇见能够解析XML内容的页面时,如果能注入外部实体并且成功解析的话,这就会大大拓宽我们 XML 注入的攻击面。
            XXE的攻击形式主要分为:带内数据实体注入基于错误的实体注入带外数据实体注入

    • 带内数据实体注入:in-band ,XML解析后的数据会直接显示在屏幕上
    • 基于错误:error-based,解析结果只有一大堆的错误
    • 带外数据:out-of-band,也叫XXE盲注,注入的XML解析后无任何输出响应,必须执行一些带外请求把数据提取出来。

    (五)XXE注入危害

    1. 任意文件读(本实验重点)
    2. SSRF,服务端请求伪造,借助漏洞实现内网探测,
    3. DOS攻击
    4. 远程命令执行

    二、XML基础知识学习

    (一)xml示例学习

    1. <?xml version="1.0" encoding="utf-8"?>
    2. <!--这里是注释-->
    3. <books>
    4. <book id="b01">
    5. <name>Python小甲鱼</name>
    6. <author>李四</author>
    7. <price>$50.00</price>
    8. </book>
    9. </books>

    分析一波:

            第一行是XML文档的声明,由“<?xml”开头,以“?>”结尾,其中的内容是对本xml文档所使用的版本 “version”和编码“encoding”的声明,version一般情况下都是1.0,因为目前为止,xml只有这一个版本。
            第二行是注释,不多做解释。
            从第三行开始,就是XML文档的主要内容了,如代码中所示的“<books>”,是本文档的根元素,“<book>”是“<books>”的子元素,而“<name>、<author>、<price>”也都是子元素,但是是“<book>”的子元素。
            那么我们可以将这个XML文档,视为是一个描述图书的文档,它所描述的内容,包括了图书的名字、作者和价格,如果使用程序对这个文档进行解析后,那么这些信息就可以更好的显示在web页面或者是应用程序中,方便用户查看。

    (二)XML的格式

    1.声明信息,用于描述xml的版本及编码格式。

    <?xml version="1.0" encoding="utf-8" ?>

    2.xml有且仅有一个根元素(可以理解为顶级的元素、没有被其他元素包起来的元素)。个人理解:像是数据库的表名
    3.xml中大小写敏感
    4.标签是成对出现的,所有元素都必须有一个关闭标签,而且要正确嵌套。
    5.属性值要使用双引号
    6.注释的写法。

    <!--这是注释 -->

    7.XML并不是让用户直接打开的,而是让别的语言来从文件中读取信息的。至于为什么可以直接用浏览器浏览,只是浏览器可以识别而已。

    (三)XML验证

            拥有正确语法的 XML 被称为"形式良好"的 XML(比如上面示例)。而判断XML的语法是否合法,叫做XML验证,是通过 DTD进行验证的。
            DTD:Document TypeDefinition 文档类型定义。用于约束xml的文档格式,保证xml是一个有效的xml,DTD分为内部和外部两种。DTD定义在xml文件中视为内部DTD;DTD定义在外部的dtd文件中,视为外部DTD。
            说的简单一点,DTD就是对当前的XML文档做一个约束,DTD中定义了这个文档中的根元素是什么,有几个子元素,每个子元素能出现几次,哪些元素有属性,属性的类型是什么,属性的默认值是什么等等,如果后面的XML内容中,与DTD中的定义不符,如元素个数不符、元素名称大小写不符等,那么XML文件解析时就会报错。

    1.内部DTD的使用:

    内部DTD的定义

    <!DOCTYPE 根元素 [元素声明]>

    元素声明语法

    1. [
    2. <!ELEMENT 根元素 (子元素)>
    3. <!ELEMENT 根元素的子元素 (子元素的子元素,子元素的子元素)>
    4. <!ELEMENT 子元素 (数据类型)>
    5. <!ELEMENT 子元素 (数据类型)>
    6. ]

    元素声明中的数量词

    1. "+" 表示出现一次或者多次
    2. "?"表示出现0次或多次
    3. "*"表示出现任意次。

    属性声明语法

    <!ATTLIST 元素名称 属性名称 属性类型 默认值>

    示例

    1. <?xml version="1.0" encoding="utf-8"?>
    2. <!--这里是注释-->
    3. <!DOCTYPE books [
    4. <!ELEMENT books (book+)>
    5. <!ELEMENT book (name,author,price)>
    6. <!ATTLIST book id CDATA #REQUIRED>
    7. <!ELEMENT name (#PCDATA)>
    8. <!ELEMENT author (#PCDATA)>
    9. <!ELEMENT price (#PCDATA)>
    10. ]>
    11. <books>
    12. <book id="b01">
    13. <name>Python小甲鱼</name>
    14. <author>李四</author>
    15. <price>$50.00</price>
    16. </book>
    17. </books>

            如上,就是一个内部DTD的引用示例,在DTD定义中,要求根元素books的子元素book出现一次及以上,子元素book又有三个子元素,分别为name,author和price,然后声明了元素book的id属性,其类型是CDATA,并且是必须的(#REQUIRED),最后定义了book的三个子元素的数据类型为#PCDATA,这表示这三个元素标签中的内容必须是文本,并能再出现子标签。

    2.外部DTD的使用:

    首先需要创建一个外部的dtd文件。内容中不需要包括<!DOCTYPE...>,直接<!ELEMENT...>,如下所示:

    1. <?xml version="1.0" encoding="utf-8"?>
    2. <!ELEMENT books (book+)>
    3. <!ELEMENT book (name,author,price)>
    4. <!ATTLIST book id CDATA #REQUIRED>
    5. <!ELEMENT name (#PCDATA)>
    6. <!ELEMENT author (#PCDATA)>
    7. <!ELEMENT price (#PCDATA)>

    然后在XML文档中引入外部的DTD:

    <!DOCTYPEbooks SYSTEM "xxx.dtd">
    

    注意外部实体引用时的关键字“SYSTEM”,同时也可以使用“PUBLIC”这个关键字,这两者的区别在于,SYSTEM表示私有的DTD,PUBLIC表示共有的DTD。

  • 相关阅读:
    趣学算法|斐波那契 矩阵算法
    抢先看!阿里发布2023最新版分布式核心小册,GitHub标星破已千万
    ConcurrentDictionary<T,V> 的这两个操作不是原子性的
    设计模式——原型模式05
    sql解决连续登录问题变形-节假日过滤
    Linux操作系统~进程替换,exec系列函数的使用
    web学习---JavaScript---笔记(二)
    Kotlin的股票交易接口是什么
    verilog HDL中定义位宽到底是[高位:0]还是[0:高位] 为什么看到了两种写法
    UNIAPP实战项目笔记47 显示默认收货地址和修改收货地址页面的布局
  • 原文地址:https://blog.csdn.net/xiaofengdada/article/details/125511717