赞
踩
xml外部实体注入攻击 base on pikachu
xml是可扩展的标记语言,它是可以用来存储数据的,看到一些.xml的配置文件,就是用xml来写的,还可以用来传输数据,我们可以直接以xml的格式,把数据给放到请求当中,发给服务器,就像,我们之前用post请求,发送数据一样,像json一样,传一组数据到后台服务端,服务端收到后,会对数据进行解析存储,然后处理等等
在xml里面分为三个部分, <!--第一部分:XML声明--> <?xml version="1.0"?> //声明主要是定义一些编码和版本 <!--第二部分:文档类型定义DTD--> <!DOCTYPE note [ <!--定义此文档是 note 类型的文档--> <!ENTITY entity-name SYSTEM "URL/URL"> <!--外部实体声明--> ]]]> //我们这次讲的漏洞,主要出问题的地方,它可以在里面定义很多对应的实体内容,这个实体内容会对后面的xml文档,进行约束 <!--第三部分:文档元素--> <note> <to>Dave</to> <from>Tom</from> <head>Reminder</head> <body>You are a good man</body> </note> //正文,通过标签定义它的key和value
我们xml里面的标签,其实是用户,可以自定义的,我们可以通过在DTD里面,编写文档约束,就是一个规范,来约束xml文档里面的标签,它的这个规范,按照DTD的格式来写
1. DTD 内部声明
<!DOCTYPE 根元素 [元素声明]>
2. DTD 外部引用
<!DOCTYPE 根元素名称 SYSTEM “外部DTD的URI”>
3. 引用公共DTD
<!DOCTYPE 根元素名称 PUBLIC “DTD标识名” “公用DTD的URI”>
<?xml version = "1.0"?> //第一部分,简单的声明
<!DOCTYPE ANY [
<!ENTITY f SYSTEM "file:///etc/passwd">
]>
//第二部分是DTD,在DTD里面,它首先,定义了文档的类型,这个类型给它一个string类,然后,在这个约束里面,它定义了一个外部实体,外部实体,都是以f开头,并以sysytem为外部实体,指定file这个文件,然后把这个文件的内容,赋值给f
<x>&f;</x>
//这个名称可以是自定义的,然后,在把这个变量以&f,加变量名称,放到x标签里面,后面可以通过读x标签里面的f,读到etc/passwd下面的内容
外部引用可以支持http,file,ftp等协议。
如果一个接口支持接收前端传进来的xml数据,且没有对xml数据做任何安全上的措施,就可能导致XXE漏洞。
攻击者可以构造一个XML的文档,然后文档里面可以通过外部实体,通过协议指定一些文件,后台收到数据后,就会对外部实体进行执行,导致一些意外的数据泄露,这就是XXE漏洞形成的原因
函数转换形式良好的 XML 字符串为 SimpleXMLElement 对象
把一个xml文档,通过参数传给simplexml_load_string,它可以把xml文档解析成一个php对象,在后面的代码当中,通过对象的内容,对它进行读取
在PHP里面解析xml用的是libxml,其在≥2.9.0的版本中,默认是禁止解析xml外部实体内容的。
≥2.9.0的版本中,是不会发生xxe漏洞的
XXE漏洞发生在应用程序解析XML输入时,没有禁止外部实体的加载,导致攻击者可以构造一个恶意的XML
XML里面定义了一个DTD,这个DTD可以通过外部实体里面对应的数据,传给simplexml_load_string,这个函数就会对数据进行读取,有可能就会把数据泄露出去
我们打开一个xxe的漏洞看一下
这边有个数据接口,是用来接收xml数据的,也就是xml数据可以通过前端的数据,传给后端
我们来看一下,后台代码怎么写
后台会通过Post请求,获取前端传进来的数据,获取到数据之后,它就直接把数据丢给simplexml_load_string,因为现在很多版本里面的libxml的版本都>=2.9.0,所以,我们要把libxml_noent给开起来,构造这么个漏洞,也就是说,在这种情况下,当xml数据传给simplexml_load_string的时候,这个函数就会对xml外部实体,去进行解析,然后,在把解析的数据,返回前端
我们可以通过正常的例子测一下
这个地方是个正常的xml,这里面定义了一个内部实体,前面是声明,后面是DTD,DTD里面定义了一个变量,相对是hacker,这个变量的值就是
ESHLkangi
在正文里面,通过name属性,去引用了hacker这个变量,我们把这段复制一下
<?xml version = "1.0"?>
<!DOCTYPE note [
<!ENTITY hacker "ESHLkangi">
]>
<name>&hacker;</name>
在框框里面,提交一下
这里直接把DTD里面定义的变量,hacker的值给返回回来了,一个正常的提交
我们这个时候,可以做个定义,在DTD里面
通过system指定一个外部实体,然后外部实体意味着,我们可以通过指定外部数据,比如敏感的文件,etc/passwd,我们把这个payload演示一下,
<?xml version = "1.0"?>
<!DOCTYPE ANY [
<!ENTITY f SYSTEM "file:///c:/1.php">
]>
<x>&f;</x>
它就直接把我们外部实体,里面传进去的file,协议指定的目标文件,它的内容给读取出来,然后又把它返回到前端,然后就把你的敏感数据给读取出来了,这个其实就是它的后端,在接收xml数据,第一,它开启了外部实体解析,第二,它没有对传过来的数据,做任何过滤,就导致了这么个问题
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。