『跨站脚本攻击』XSS构造技巧
本文主要介绍如何进行构造XSS
利用字符编码
应用场景
网站对用户的输入中的双引号等特殊符号进行了转义
方法
构造字符编码吃掉转义符号
例子
网站在一个
<script>
标签里面输出了一个用户输入的变量1
var redirectUrl=" ";
如果我们输入以下内容:
1
";alert(/XSS/);
因为双引号被转义,所以在html页面上的输出如下:
1
var redirectUrl="\";alert(/XSS/);";
并不能执行后面的XSS代码
javascript中的转义字符是
\
,会将特殊符号如单引号、双引号等构造成\'
,\"
的形式。在这里的话
\"
就直接被视作文本的"
了,而并不会和前面的前引号"
形成闭合。但是,百度的返回页面是
GBK/GB2312
编码的,因此%c1\
这两个字符组合在一起后,会成为一个Unicode字符。在firefox浏览器中会认为这是一个字符,所以构造xss攻击代码如下:1
%c1";alert(/XSS/);//
在页面上,引号
%c1"
被转义成%c1\"
,而%c1\
组成了一个新的Unicode字符,吃掉了转义符号\
,从而让构造的"
和前面的前引号形成闭合绕过了系统的安全检查,成功实施了XSS注入。
绕过长度限制
应用场景
有时候服务器端可能对输入变量的长度进行了限制,长度限制不足以构造XSS
方法
1)使用event
- onclick
2)将payload写到别处,通过简短的代码加载这段XSS payload
loaction.hash
location.hash
是 JavaScript 中location
对象的一个属性,它返回 URL 中的哈希/锚部分(即#
号及其后面的部分)。location.hash
对象的具体解释: location.hash详解因为哈希部分不会被发送到服务器,所以服务器端的Web日志中并不会记录下location.hash 里的内容,从而也更好地隐藏了黑客真实的意图。
location.hash
没有长度限制,所以可以将XSS代码写在location.hash
部分,然后在页面中限制长度的地方构造代码执行location.hash
远程加载js文件
利用注释符
例子
1)onclick
构造文本框内输入
1
<input type=text value="" onclick=alert(1)// "/>
2.1)loaction.hash
构造url为:
1
http://www.a.com/test.html#alert(1)
这里的
#alert(1)
就是location.hash
构造网页中的文本输入框为:
1
<input type="text" value="" onclick="eval(location.hash.substr(1)) " />
eval()函数:
- 如果参数是一个表达式,eval() 函数将执行表达式。
- 如果参数是 Javascript 语句,eval() 将执行 Javascript 语句。
当我们点击这个文本框的时候,会执行
location.hash
中的代码,并去掉哈希部分的第一个字符(#
)因此,当用户点击这个输入框时,
location.hash
为#alert(1)
,去掉第一个字符后,eval
函数将执行alert(1)
,从而弹出一个警告框。这样就成功执行了我们构造的XSS攻击代码。
2.3)利用注释符
网站上存在两个文本框,第一个文本框存在长度限制,第二个文本框允许写入更多的字节。
此时可以利用HTML的“注释符号”,把两个文本框之间的HTML代码全部注释掉,从而“打通”两个
<input>
标签。例,有2个文本框
1
2
3<input id=1 type="text" value="" />
xxxxxxxxxxxxx
<input id=2 type="text" value="" />在第一个input文本框中,输入:
1
" onfocus="var a='This is a long ';"><!--
onfocus
事件是一个 JavaScript 事件,它在元素获得焦点时触发。焦点是指用户通过点击、触摸或使用键盘(如 Tab 键)将输入光标或选中状态移动到某个元素上。在 HTML 中,
onfocus
事件可以直接在元素标签内部指定在第二个input文本框中,输入:
1
--><script>alert(a + 'XSS attack!');</script>
最终生成的html代码如下:
1
2
3<input id="input1" type="text" value="" onfocus="var a='This is a long ';"><!--" />
<!-- Some HTML content or other inputs -->
<input id="input2" type="text" value="--><script>alert(a + 'XSS attack!');</script>" />在这个例子中,当第一个文本框获得焦点时,会执行
onfocus
事件中的JavaScript代码,定义了一个变量a
。由于第一个文本框的值以"><!--
结尾,它实际上将中间的HTML内容注释掉了,直到遇到第二个文本框中的-->
,这结束了注释。然后,第二个文本框中的<script>
标签被正确解析并执行,弹出带有完整消息的警告框。通过这种方式,我们成功地将较长的攻击代码分割成两个部分,并利用HTML注释符将它们连接起来,绕过了单个输入字段的长度限制。
使用base标签
<base>
标签的作用是定义页面上的所有使用“相对路径”标签的hosting地址,可以作用于该标签之后的所有标签。
例如:
这样访问的img路径就是 http://www.google.com/intl/en_ALL/images/srpr/logo1w.png
1 | <body> |
攻击者如果在页面中插入了 <base>
标签,就可以通过在远程服务器上伪造图片、链接或脚本,劫持当前页面中的所有使用“相对路径”的标签。
因此需要对这个标签进行过滤。
window.name
对当前窗口的window.name
对象赋值,没有特殊字符的限制。
因为window对象是浏览器的窗体,而并非document对象,因此很多时候window对象不受同源策略的限制。黑客利用这个对象,可以实现跨域、跨页面传递数据。
使用window.name 可以缩短XSS Payload的长度,如下所示:
1 | <script> |
在同一窗口打开存在XSS的站点后,只需通过XSS执行name中的代码即可:
1 | eval(name); |
只有11个字节,短到了极点。