警告
请勿使用本文提到的内容违反法律。
本文不提供任何担保
目录
xml(eXtensibleMarkup Language),可扩展标记语言,使用简单的标记来描述数据。xml是一种非常灵活的语言,类似于HTML语言,但是并没有固定的标签,所有的标签都可以自定义,其设计的宗旨是传输数据,而不是像HTML一样显示数据。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与HTML一样,也存在注入漏洞。比如:一个 web 应用,在进行用户注册时,选择以 xml 来存储数据到 xmldb 数据库中,当用户填写用户名,密码和邮箱时,后台存储的文件格式及内容如下:
那么攻击者就可以在注册的时候构造恶意的数据,假设他在用户名与密码的输入框中输入正常的文本,在最后的邮箱输入框中输入如下内容:
那么就会多注册一个名为admin的用户。综合上面的小例子,我们可以知道,能够进行XML注入攻击的前提是,用户能够控制数据的输入,程序没有对输入的内容进行过滤且拼接了数据。那么相应的,破坏掉其中一个前提就可以进行防御了,既然我们无法限制用户的输入,那么就可以对数据进行过滤,将XML语言本身的“保留字符”进行过滤或者转义即可。
XXE注入也是XML注入的一部分,但相较于普通的XML注入,XXE注入的攻击面更广,危害更大。 XXE注入(XML External Entity Injection) 全称为 XML 外部实体注入,从名字就能看出来,所注入的对象就是我们实验任务一中提到的重点: XML外部实体。当遇见能够解析XML内容的页面时,如果能注入外部实体并且成功解析的话,这就会大大拓宽我们 XML 注入的攻击面。
XXE的攻击形式主要分为:带内数据实体注入、基于错误的实体注入和带外数据实体注入
- 带内数据实体注入:in-band ,XML解析后的数据会直接显示在屏幕上
- 基于错误:error-based,解析结果只有一大堆的错误
- 带外数据:out-of-band,也叫XXE盲注,注入的XML解析后无任何输出响应,必须执行一些带外请求把数据提取出来。
- 任意文件读(本实验重点)
- SSRF,服务端请求伪造,借助漏洞实现内网探测,
- DOS攻击
- 远程命令执行
- <?xml version="1.0" encoding="utf-8"?>
- <!--这里是注释-->
- <books>
- <book id="b01">
- <name>Python小甲鱼</name>
- <author>李四</author>
- <price>$50.00</price>
- </book>
- </books>
分析一波:
第一行是XML文档的声明,由“<?xml”开头,以“?>”结尾,其中的内容是对本xml文档所使用的版本 “version”和编码“encoding”的声明,version一般情况下都是1.0,因为目前为止,xml只有这一个版本。
第二行是注释,不多做解释。
从第三行开始,就是XML文档的主要内容了,如代码中所示的“<books>”,是本文档的根元素,“<book>”是“<books>”的子元素,而“<name>、<author>、<price>”也都是子元素,但是是“<book>”的子元素。
那么我们可以将这个XML文档,视为是一个描述图书的文档,它所描述的内容,包括了图书的名字、作者和价格,如果使用程序对这个文档进行解析后,那么这些信息就可以更好的显示在web页面或者是应用程序中,方便用户查看。
1.声明信息,用于描述xml的版本及编码格式。
<?xml version="1.0" encoding="utf-8" ?>
2.xml有且仅有一个根元素(可以理解为顶级的元素、没有被其他元素包起来的元素)。个人理解:像是数据库的表名
3.xml中大小写敏感
4.标签是成对出现的,所有元素都必须有一个关闭标签,而且要正确嵌套。
5.属性值要使用双引号
6.注释的写法。
<!--这是注释 -->
7.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 根元素 [元素声明]>
元素声明语法
- [
- <!ELEMENT 根元素 (子元素)>
- <!ELEMENT 根元素的子元素 (子元素的子元素,子元素的子元素)>
- <!ELEMENT 子元素 (数据类型)>
- <!ELEMENT 子元素 (数据类型)>
- ]
元素声明中的数量词
- "+" 表示出现一次或者多次
- "?"表示出现0次或多次
- "*"表示出现任意次。
属性声明语法
<!ATTLIST 元素名称 属性名称 属性类型 默认值>
示例
- <?xml version="1.0" encoding="utf-8"?>
- <!--这里是注释-->
- <!DOCTYPE books [
- <!ELEMENT books (book+)>
- <!ELEMENT book (name,author,price)>
- <!ATTLIST book id CDATA #REQUIRED>
- <!ELEMENT name (#PCDATA)>
- <!ELEMENT author (#PCDATA)>
- <!ELEMENT price (#PCDATA)>
-
- ]>
- <books>
- <book id="b01">
- <name>Python小甲鱼</name>
- <author>李四</author>
- <price>$50.00</price>
- </book>
- </books>
如上,就是一个内部DTD的引用示例,在DTD定义中,要求根元素books的子元素book出现一次及以上,子元素book又有三个子元素,分别为name,author和price,然后声明了元素book的id属性,其类型是CDATA,并且是必须的(#REQUIRED),最后定义了book的三个子元素的数据类型为#PCDATA,这表示这三个元素标签中的内容必须是文本,并能再出现子标签。
2.外部DTD的使用:
首先需要创建一个外部的dtd文件。内容中不需要包括<!DOCTYPE...>,直接<!ELEMENT...>,如下所示:
- <?xml version="1.0" encoding="utf-8"?>
- <!ELEMENT books (book+)>
- <!ELEMENT book (name,author,price)>
- <!ATTLIST book id CDATA #REQUIRED>
- <!ELEMENT name (#PCDATA)>
- <!ELEMENT author (#PCDATA)>
- <!ELEMENT price (#PCDATA)>
然后在XML文档中引入外部的DTD:
<!DOCTYPEbooks SYSTEM "xxx.dtd">
注意外部实体引用时的关键字“SYSTEM”,同时也可以使用“PUBLIC”这个关键字,这两者的区别在于,SYSTEM表示私有的DTD,PUBLIC表示共有的DTD。