XSS 跨站脚本攻击
什么是XSS
跨站脚本攻击(Cross-site scripting)是一种安全漏洞,攻击者可以利用这种漏洞在网站上注入恶意的客户端代码。若受害者运行这些恶意代码,攻击者就可以突破网站的访问限制并冒充受害者。
如果 Web 应用程序没有部署足够的安全验证,那么,这些攻击很容易成功。浏览器无法探测到这些恶意脚本是不可信的,所以,这些脚本可以任意读取 cookie,session tokens,或者其他敏感的网站信息,或者让恶意脚本重写HTML内容。
在以下两种情况,容易发生XSS攻击:
- 数据从一个不可靠的链接进入到一个web应用程序
- 没有过滤掉恶意代码的动态内容被发送给web用户
恶意内容一般包含javascript
,但是,有时候也会包括html
,flash
或者是其他浏览器可执行的代码。XSS 攻击的形式千差万别,但他们通常都会:将 cookies 或其他隐私信息发送给攻击者,将受害者重定向到由攻击者控制的网页,或是经由恶意网站在受害者的机器上进行其他恶意操作。
XSS攻击可以分为三类:
- 存储型XSS:注入型脚本永久存储在目标服务器上,当浏览器请求数据时,脚本从服务器上被执行
- 反射性XSS:当用户点击一个恶意链接,或者提交一个表单,或者进入一个恶意网站时,注入脚本进入被注入攻击者的网站,web服务器将注入脚本,比如一个错误信息,搜索结果等返回到用户的浏览器上。由于浏览器认为这个响应来自 可信任 的服务器,所以会执行这段脚本
- 基于DOM的XSS:通过修改原始的客户端代码,受害者浏览器的DOM环境改变,导致有效载荷的进行。也就是说,页面本身没有变化,但由于DOM环境被恶意修改,有客户端被包含进了页面,并且意外执行
攻击者如何利用xss漏洞盗取会话令牌:
反射型XSS攻击
反射性XSS攻击又称非持久性XSS攻击,这种攻击往往具有一次性
攻击者通过邮件等形式将包含xss代码的url发送给用户,用户点击,服务器接收该用户请求并进行处理,然后把带有xss的代码发送给用户。用户浏览器解析执行代码,触发xss漏洞
例如<?php echo $_GET["username"]?>
当用户访问url?username=<script>alert("/xss/")</script>
时触发代码,弹出对话框
反射型xss的代码分析:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html";charset=utf-8"/>
<title>xss exploit</title>
</head>
<body>
<center>
<h6>把我们输入的字符串输出到input里的value属性里面</h6>
<form action="" method="get">
<h6>
请输入想要显示的字符串
</h6>
<input type="text" name="xss_input_value" value="输入"><br>
<input type="submit">
</form>
<?php
if(isset($_GET['xss_input_value'])){
echo '<input type="text" value="'.$_GET['xss_input_value'].'">';
}else{
echo '<input type="text" value="输出">';
}
?>
</center>
</body>
</html>
在代码中,要显示的字符串为xss_input_value
,通过get方式传入php函数后,将字符串输出。由于xss_input_value
是在<input>
属性中,所以想要执行js代码,就需要闭合>
符号,所以输入"><script>alert()"hello")</script>
,就可以成功执行js脚本
存储型XSS攻击
存储型XSS攻击又被称为持久性XSS,存储型XSS攻击是最危险的一种跨站脚本
允许用户存储数据的web应用程序都可能会出现存储型xss漏洞,当攻击者提交一段xss代码后,被服务器端接收并存储,当攻击者再次访问某个页面时,这段xss代码被程序读出来响应给浏览器,造成xss跨站攻击,这就是存储型xss
存储型xss页面实现的功能是:获取用户输入的留言信息,标题和内容,然后将标题和内容插入到数据库中,并将数据库中的留言信息输出到页面上
存储型xss与反射性xss,DOM型xss相比,有更高的隐蔽性。它们最大的区别在于反射型xss和dom型xss执行都必须依靠用户手动去触发,而存储型xss不需要
存储型xss的代码分析:
<!DOCTYPE html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
<title>xss利用输出的环境构造代码</title>
</head>
<body>
<center>
<h6>输入留言内容</h6>
<from action="" method="post">
标题: <input type="text" name="title"><br/>
内容: <input type="text" name="content"></textarea><br/>
</from>
<hr>
<?php
$con = mysqli_connect("localhost","root","123456","test");
if(mysqli_connect_errno()){
echo "connect failed: ".mysqli_connect_error();
}
if(isset($_POST['title'])){
$result1 = mysqli_query($con,"insert into xss(`title`,`content`) values ('".$_POST['title']."','".$_POST['content']."')");
}
$result2 = mysqli_query($con,"select * from xss");
echo "<table border='1'><tr><td>标题</td><td>内容</td></tr></table>";
while($row = mysqli_fetch_array($result2)){
echo "<tr><td>".$row['title']."</td><td>".$row['content']."</td>";
}
echo "</table>";
?>
</center>
</body>
</html>
这段代码中,输入的内容是title,且用户输入的内容被存放在了数据库中,当在标题处写入<img src=1 oneerr=alert(/xss/)>
,数据库中的数据如下
|--id--|-----------title-------------------|---content---|
| 1 |--<img src=1 oneerr=alert(/xss/)>--|--11---------|
当title输出到页面时,页面执行了<img src=1 oneerr=alert(/xss/)>
DOM型XSS攻击
首先介绍什么是DOM:
DOM(document object model
),文档对象模型,是HTML文档和XML文档的编程接口,其中HTML DOM定义了所有HTML元素的对象和属性,以及访问它们的方法。换言之,HTML DOM是关于如何获取、修改、添加或删除HTML元素的标准。DOM以树结构表达HTML文档。下图为HTML DOM树形结构示例:
什么是DOM型XSS:
DOM型XSS是基于DOM文档对象模型的一种漏洞。严格地说,DOM型XSS其实算反射型XSS,区别在于DOM型XSS并不会和后台进行交互,是完完全全的Web前端安全问题,要做防御也只能在客户端上进行防御。
首先,客户端的脚本程序可以通过DOM动态地检查和修改页面内容,它并不与服务端进行交互而是从客户端获得DOM中的数据(如从URL中获取数据)并在本地执行;其次,浏览器用户可以操纵DOM中的一些对象如URL、location等;因此,当攻击者可以控制一些DOM对象、输入一些恶意JS代码,而客户端的脚本并没有对用户输入内容进行有效的过滤就传入一些执行危险操纵的函数如eval等或直接输出到页面时,就会导致DOM型XSS漏洞的存在。
如下面的HTML文件就存在DOM型XSS,其功能是当我们在URL栏输入参数name的值后,就会在当前页面显示输入如的name的值,其功能的实现全都在前端JS中进行、未与后台进行任何交互:
DOM XSS的代码分析:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>Test</title>
<script type="text/javascript">
function tihuan(){
document.getElementById("id1").innerHTML = document.getElementById("dom_input").value;
}
</script>
</head>
<body>
<center>
<h6 id="id1">这里显示输入的内容</h6>
<form action="" method="post">
<input type="text" id="dom_input" value="输入"><br/>
<input type="button" value="替换" onclick="tihuan()">
</form>
</center>
</body>
</html>
在<head>
标签中写入的javascript函数实现替换函数内容部分,由于是隐式输出,查看页面源代码时,看不到输出的xss代码
XSS进阶
常用语句
xss常用语句有
<script>alert(1)</script>
<img src=x onerror=alert(1)>
<svg onload=alert(1)>
<a href=javascript:alert(1)>
编码绕过
-
js编码:
JS提供了四种编码字符的策略:- 三个八进制数字
- 两个16进制数字
- 四个16进制数字
- 对于一些控制字符,使用特殊的C类型转义风格
-
HTML实体编码
-
URL编码