WEB安全——XML注入
浅析XML注入
- 认识XML DTD
- XML注入
- XPath注入
- XSL和XSLT注入
前言
前段时间学习了.net,通过更改XML让连接数据库变得更方便,简单易懂,上手无压力,便对XML注入这块挺感兴趣的,刚好学校也开了XML课程,忍不住花时间研究了一下
首先认识XML
XML有两个先驱——SGML(标准通用标记语言)和HTML(超文本标记语言),这两个语言都是非常成功的标记语言。SGML多用于科技文献和政府办公文件中,SGML非常复杂,其复杂程度对于网络上的日常使用简直不可思议。HTML免费、简单,已经获得了广泛的支持,方便大众的使用。而XML(可扩展标记语言)它既具有SGML的强大功能和可扩展性,同时又具有HTML的简单性。
XML 与 HTML 的主要差异
XML 被设计为传输和存储数据,其焦点是数据的内容。
HTML 被设计用来显示数据,其焦点是数据的外观。
HTML 旨在显示信息 ,而 XML 旨在传输信息。
然后认识DTD
文档类型定义(DTD)可定义合法的XML文档构建模块。它使用一系列合法的元素来定义文档的结构。
DTD 可被成行地声明于 XML 文档中,也可作为一个外部引用。
不过,XML对于标记的语法规定比HTML要严格地多
l 区分大小写
l 在标记中必须注意区分大小写,在XML中,<TEST>和<test>是两个截然不同的标记
l 要有正确的结束标记
l 结束标记除了要和开始编辑在拼写和大小上完全相同,还必须在前面加上一个斜杠“/”
l 若开始标记<test>,结束标记则为</test>。XML严格要求标记配对,HTML中的<br>、<hr>的元素形式在XML中是不合法的。当一对标记之间没有任何文本内容时,可以不写结束标记,在开始标记的末尾加上斜杠”/”来确认,例如:<test /> 这样的标记被称为“空标记”。
l 标记要正确嵌套
l 在一个XML元素中允许包含其他XML元素,但这些元素之间必须满足嵌套性
l 有效使用属性
l 标记中可以包含任意多个属性。在标记中,属性以名称/取值对出现,属性名不能重复,名称与取值之间用等号“=”分隔,且取值用引号引起来。
l 举个例子:<衣服 品牌=“耐克” 类型=“T恤” >
XML基础
XML声明:<?xml version="1.0" encoding="utf-8" ?>
内部DTD声明:<!DOCTYPE 根元素名称 [元素声明]>
在DTD中定义属性:<!ATTLIST 元素名 (属性名 属性类型 缺省值)*>
外部实体声明:<!ELEMENT 实体名称 SYSTEM “URI/URL”>
XML注入
XML的设计宗旨是传输数据,而非显示数据。
XML注入是一种古老的技术,通过利用闭合标签改写XML文件实现的。
举个最简单的例子
<?xml version="1.0" encoding="utf-8" ?>
<USER>
<user Account="admin">用户输入</user>
<user Account="root">root</user>
</USER>
若攻击者刚好能掌控用户输入字段,输入
admin</user><user Account="hacker">hacker
最终修改结果为
<?xml version="1.0" encoding="utf-8" ?>
<USER>
<user Account="admin">admin</user>
<user Account="hacker">hacker</user>
<user Account="root">root</user>
</USER>
这样我们可以通过XML注入添加一个管理员账户
XML注入两大要素:标签闭合和获取XML表结构
XPath注入
XPath 是一门在 XML 文档中查找信息的语言。XPath 用于在 XML 文档中,通过元素和属性进行导航。类似jquery选择器的选择路径。
XPath的强大之处在于逻辑运算,使程序变得更有逻辑性,同时也会造成注入漏洞。
通过XPath注入攻击,可以攻击XML。XPath与SQL注入的方式类似,首先我们了解一下SQL注入。
假设有一张BookDB表,其中包括BookID、BookName、Price,用Sql Server查询图书ID时SQL语句代码如下:
select * from BookDB where BookID=1
当我们输入1 or 1=1时,运行结果可以显示当前表中的所有数据,这就是SQL注入攻击,与XPath注入原理相似,这时我们把BookDB换成XML,代码如下:
<?xml version="1.0" encoding="utf-8" ?>
<bookstore>
<book>
<bookid>001</bookid>
<bookname>C语言从入门到精通</bookname>
<price>38</price>
</book>
<book>
<bookid>002</bookid>
<bookname>GO语言从入门到放弃</bookname>
<price>28</price>
</book>
<book>
<bookid>003</bookid>
<bookname>ASP.NET网站开发</bookname>
<price>48</price>
</book>
<book>
<bookid>004</bookid>
<bookname>WinFrom开发桌面应用程序</bookname>
<price>58</price>
</book>
<book>
<bookid>005</bookid>
<bookname>JAVA编程思想</bookname>
<price>65</price>
</book>
<book>
<bookid>006</bookid>
<bookname>C#面向对象程序设计</bookname>
<price>45</price>
</book>
</bookstore>
若需要查询编号为001的图书对应的书名,则XPath语句为:
/bookstore/book[bookid/text()='001'
]/bookname
下面我们用JavaScript来查询,代码如下
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title></title>
<meta charset="utf-8" />
</head>
<body>
<script type="text/javascript">
function loadXMLDoc(dname) {
if (window.XMLHttpRequest) {
xhttp = new XMLHttpRequest();
}
else {
xhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xhttp.open("GET", dname, false);
xhttp.send("");
return xhttp.responseXML;
}
xml = loadXMLDoc("../BookList.xml");
path = "/bookstore/book[bookid/text()='001' ]/bookname";
if (window.ActiveXObject) {
var nodes = xml.selectNodes(path);
for (i = 0; i < nodes.length; i++) {
document.write(nodes[i].childNodes[0].nodeValue);
document.write("<br />");
}
}
else if (document.implementation && document.implementation.createDocument) {
var nodes = xml.evaluate(path, xml, null, XPathResult.ANY_TYPE, null);
var result = nodes.iterateNext();
while (result) {
document.write(result.childNodes[0].nodeValue);
document.write("<br />");
result = nodes.iterateNext();
}
}
</script>
</body>
</html>
假设我们可以控制XPath语句,那么可以使用之前提到的“ or 1=1 ”遍历全部的bookname,代码如下:
/bookstore/book[bookid/text()='001' or 1=1]]/bookname
JavaScript代码如下:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title></title>
<meta charset="utf-8" />
</head>
<body>
<script type="text/javascript">
function loadXMLDoc(dname) {
if (window.XMLHttpRequest) {
xhttp = new XMLHttpRequest();
}
else {
xhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xhttp.open("GET", dname, false);
xhttp.send("");
return xhttp.responseXML;
}
xml = loadXMLDoc("../BookList.xml");
path = "/bookstore/book[bookid/text()='001' or 1=1]]/bookname";
if (window.ActiveXObject) {
var nodes = xml.selectNodes(path);
for (i = 0; i < nodes.length; i++) {
document.write(nodes[i].childNodes[0].nodeValue);
document.write("<br />");
}
}
else if (document.implementation && document.implementation.createDocument) {
var nodes = xml.evaluate(path, xml, null, XPathResult.ANY_TYPE, null);
var result = nodes.iterateNext();
while (result) {
document.write(result.childNodes[0].nodeValue);
document.write("<br />");
result = nodes.iterateNext();
}
}
</script>
</body>
</html>
运行结果为:
成功get所有的bookname,这里建议大家不要用XML传输一些敏感信息
XSL介绍
XSL 指扩展样式表语言(EXtensible Stylesheet Language),XML本身就是一个XML文档,它是通过XML进行定义的,遵守XML的语法规则,是XML的一种具体应用。
如果说HTML的样式表是CSS,那么XML的样式表就是XSL。但XSL比CSS更强大。
XSL - 不仅仅是样式表语言
XSL 包括以下三部分:
XSLT:一种用于转换 XML 文档的语言。
XPath:一种用于在 XML 文档中导航的语言。
XSL-FO:一种用于格式化 XML 文档的语言。
什么是XSLT?
XSL(可扩展样式表语言)是一种用于转换XML文档的语言,XSLT表示的就是XSL转换,而XSL转换指的就是XML文档本身。转换后得到的一般都是不同的XML文档或其他类型文档,例如HTML文档、CSV文件以及明文文本文件等等。
首先我们来了解一下XML与XSLT之间的转换
先来看看下面这个XML文件(cdcatalog.xml)
<?xml version="1.0" encoding="utf-8" ?>
<catalog>
<cd>
<title>Empire Burlesque</title>
<artist>Bob Dylan</artist>
<country>USA</country>
<company>Columbia</company>
<price>10.90</price>
<year>1985</year>
</cd>
</catalog>
接下来,我们使用下XSL转换技术来将XML文档转换为明文文本文件
以下是XSTL文件(cdcatalog.xslt)代码:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
<h2>My CD Collection</h2>
<table border="1">
<tr bgcolor="#9acd32">
<th align="left">Title</th>
<th align="left">Artist</th>
</tr>
<xsl:for-each select="catalog/cd">
<tr>
<td>
<xsl:value-of select="title"/>
</td>
<td>
<xsl:value-of select="artist"/>
</td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
由于样式表不能直接运行,所以我们将 XSL 样式表链接到 XML 文档里
向 XML 文档("cdcatalog.xml")添加 XSL 样式表引用,代码如下:
<?xml version="1.0" encoding="utf-8" ?>
<?xml-stylesheet type="text/xsl" href="cdcatalog.xslt"?>
<catalog>
<cd>
<title>Empire Burlesque</title>
<artist>Bob Dylan</artist>
<country>USA</country>
<company>Columbia</company>
<price>10.90</price>
<year>1985</year>
</cd>
</catalog>
运行结果如下:
寻找切入点:
假设应用程序可以生成下列XSLT文档(cdcatalog.xslt),而字符串“HELLO I FIND YOU”来自于不受信任的用户输入。
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
HELLO I FIND YOU
<h2>My CD Collection</h2>
<table border="1">
<tr bgcolor="#9acd32">
<th align="left">Title</th>
<th align="left">Artist</th>
</tr>
<xsl:for-each select="catalog/cd">
<tr>
<td>
<xsl:value-of select="title"/>
</td>
<td>
<xsl:value-of select="artist"/>
</td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
运行结果:
为了确认应用程序是否存在这个漏洞,我们可以向其注入一些类似双引号、单引号以及破折号等特殊字符,因为这类字符可以让XML文档中的语句失效。如果服务器返回了错误,那么这个应用就很有可能存在漏洞。需要注意的是,这种方法同样适用于XML注入漏洞。
system-property()函数
我们可以使用system-property()函数来查看代码库的开发者名称,该功能符合XSLT v1.0标准,所有的代码库都实现了这种功能。
有效参数:
xsl:vendor
xsl:vendor-url
xsl:version
下面代码可以用来确定代码库的开发者(vendor):
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
<xsl:value-of select="system-property('xsl:vendor')"/>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
运行结果如下:
若想查看URL,在参数后加上“-url”,得到结果如下:
Import和Include
import和include标签可以用来合并多个XSLT文档,但是只能在XSLT文档中间注入内容的话,也许不能直接使用XML外部实体(XXE)攻击或脚本来进行攻击了,因为这些攻击技术要求我们在文档头部实现内容注入。
我们用上面讲到的cdcatalog.xslt文件演示一下
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
<h2>My CD Collection</h2>
<table border="1">
<tr bgcolor="#9acd32">
<th align="left">Title</th>
<th align="left">Artist</th>
</tr>
<xsl:for-each select="catalog/cd">
<tr>
<td>
<xsl:value-of select="title"/>
</td>
<td>
<xsl:value-of select="artist"/>
</td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
我们需要include下面这个名为“include.xslt”的外部XSLT文件:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
We are all anonymous
</body>
</html>
</xsl:template>
</xsl:stylesheet>
若想引用include外部文档,我们需要注入语句为:
<xsl:include href="include.xslt"/>
由于XML中开始标签与闭合标签都是成对出现的,所以我们需要闭合“xsl:template”标签,然后添加“xsl:include”标签,最终语句如下:
</xsl:template>
<xsl:include href="include.xslt"/>
<xsl:template name="a">
注入完成后,最终代码如下:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
</xsl:template>
<xsl:include href="include.xslt"/>
<xsl:template name="a">
<html>
<body>
<h2>My CD Collection</h2>
<table border="1">
<tr bgcolor="#9acd32">
<th align="left">Title</th>
<th align="left">Artist</th>
</tr>
<xsl:for-each select="catalog/cd">
<tr>
<td>
<xsl:value-of select="title"/>
</td>
<td>
<xsl:value-of select="artist"/>
</td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
结果如下:
注入成功,仅显示include外部文档。
小结:
- 尽量不要用XML传输敏感数据
- 尽可能地避免用户提供的XSLT文档
- 不要轻易相信外来的XSLT文档
WEB安全——XML注入的更多相关文章
- WEB安全第五篇--其他注入的奇技淫巧:XML注入、Xpath注入、Json注入、CRLF注入
零.前言 最近做专心web安全有一段时间了,但是目测后面的活会有些复杂,涉及到更多的中间件.底层安全.漏洞研究与安全建设等越来越复杂的东东,所以在这里想写一个系列关于web安全基础以及一些讨巧的pay ...
- XML注入介绍--XXE,XEE,xpath等
XML注入指在请求的XML中插入攻击利用代码.根据不同的场景,可能会形成以下的漏洞形式: (1)XEE ----xml entity xpansion(xml实体膨胀,用于dos) 具体介绍:http ...
- 【web渗透技术】渗透攻防Web篇-SQL注入攻击初级
[web渗透技术]渗透攻防Web篇-SQL注入攻击初级 前言不管用什么语言编写的Web应用,它们都用一个共同点,具有交互性并且多数是数据库驱动.在网络中,数据库驱动的Web应用随处可见,由此而存在的S ...
- 【网络安全】SQL注入、XML注入、JSON注入和CRLF注入科普文
目录 SQL注入 一些寻找SQL漏洞的方法 防御SQL注入 SQL注入相关的优秀博客 XML注入 什么是XML注入 预防XML注入 JSON注入 什么是JSON注入 JSON注入的防御 CRLF注入 ...
- Apache Cocoon XML注入 [CVE-2020-11991]
受影响版本: Apache Cocoon <= 2.1.x 程序使用了StreamGenerator这个方法时,解析从外部请求的xml数据包未做相关的限制,恶意用户就可以构造任意的xml表达式, ...
- phpshe xml注入
*php商城系统 xml注入* **页面样式* *Xml原理参考:* https://www.cnblogs.com/20175211lyz/p/11413335.html *漏洞函数simplexm ...
- Web API 依赖注入与扩展
与 MVC 类似, Web API 提供了System.Web.Http.Services.IDependencyResolver 接口来实现依赖注入, 我们可以很容易的用 Unity 来实现这个接口 ...
- JAVA WEB EL表达式注入
看猪猪侠以前的洞,顺便总结下: 一.EL表达式简介 EL 全名为Expression Language.EL主要作用: 1.获取数据 EL表达式主要用于替换JSP页面中的脚本表达式,以从各种类型的we ...
- 这一次搞懂Spring Web零xml配置原理以及父子容器关系
前言 在使用Spring和SpringMVC的老版本进行开发时,我们需要配置很多的xml文件,非常的繁琐,总是让用户自行选择配置也是非常不好的.基于约定大于配置的规定,Spring提供了很多注解帮助我 ...
随机推荐
- SuperBenchmarker一个用.NET编写的压测工具
0x01 前言 在这之前想必大家对ab(http)与abs(https)也有一些了解,我们今天不去看ab和abs,SuperBenchmarker(sb.exe)是一个压测工具,他是一个受Apache ...
- Linux基本操作及常用指令
今天复习了下Linux的基本操作及常用指令,上学期大数据云计算课一直也在用linux系统还是比较熟悉的,并在centos6.7虚拟机上部署了前几天做的web项目,了解了Nginx的反向代理与负载均衡, ...
- 2020Ubuntu server1804最新安装后的配置
一.Putty进行ssh连接. 完成最基本配置之后,就远程连接服务器了.在windows是我习惯putty 在我以前的老电脑里面找一个putty是0.6版本的,连上Ip ,还是原来的配方,还是原来的味 ...
- Django 图片上传到数据库 并调用显示
环境:Django2.0 Python3.6.4 建立项目,数据库设置,就不说了. 直接上代码: 在models.py中,需要建立模型,这里使用了ImageField字段,用来存储图片路径,这个字段继 ...
- Hyperledger Fabric ChainCode开发
预览 Hyperledger Fabric的chaincode开发目前支持Go.Java.Node.js语言,下面以Go语言作为例子,我们先看下面的一个官方提供chaincode模板 ··· pack ...
- 大数据存储利器 - Hbase 基础图解
由于疫情原因在家办公,导致很长一段时间没有更新内容,这次终于带来一篇干货,是一篇关于 Hbase架构原理 的分享. Hbase 作为实时存储框架在大数据业务下承担着举足轻重的地位,可以说目前绝大多数大 ...
- 在5G+AI+Cl 拉动互联网走向物联网
大家好我是浅笑若风,今天在这里和大家聊聊的是:5G+AI+CL拉动互联网走向物联网 在虫洞时空里我们早已能遇见到世界的尽头会是什么样子,微服务,微生活的迅速发展的时代.我们在虚拟的多次元世界购物.交易 ...
- 聊一聊 React 中的 CSS 样式方案
和 Angular,Vue 不同,React 并没有如何在 React 中书写样式的官方方案,依靠的是社区众多的方案.社区中提供的方案有很多,例如 CSS Modules,styled-compone ...
- Natas0-34 Writeup
Natas是一个教授服务器端Web安全基础知识的 wargame,通过在每一关寻找Web安全漏洞,来获取通往下一关的秘钥,适合新手入门Web安全. 传送门~ 接下来给大家分享一下,1-34题的Writ ...
- 在macOS平台下制作SSL证书,免费域名通配符证、单域名证书、多域名证书教程
1.安装 home-brew 2.安装 certbot 在终端执行下面命令 brew install certbot 3.制作SSL证书 第一步: 在终端执行下面命令 sudo certbot cer ...