YAQSecurity 2019-11-13
”百度搜藏”曾经在一个<script>
标签中输出了一个变量
var redirectUrl = "\";alert(/xss/);";
变量处于双引号内,系统转义了双引号导致变量无法“escape”。
但是,返回页面是GBK/GB2312编码的,因此”%c1“这两个字符组合在一起后,会成为一个Unicode字符。所以构造:
%c1";alert(/xss/);//
并提交,得到如下效果
var readirectUrl = "乱码";alert(2);//";
<input type=text value="$var" />
如果服务器对$var做个严格的长度限制,假如长度限制为20个字节
攻击者这样构造:
$var 为: "><script>alert(/xss/)</script>
超过了长度。
这样构造
$var 为: "onclick=alert(1)//
不会超过长度限制
最好的办法是将XSS Payload写到别处,再通过简短的代码加载它。
最常用的一个”藏代码“的地方,就是"localtion.hash",它的内容不会在HTTP包中发送,所以服务器端的Web日志中并不会记录下location.hash里的内容。
$var 修改为: " onclick="eval(location.hash.substr(1))
当然,还可以使用远程加载js的方法,以避免浏览器地址栏长度的限制。
<base>
标签并不常用,它定义页面上所有使用"相对路径"标签的hosting地址。它可以出现在页面的任何地方,并作用于位于该标签之后的所有标签。
攻击可以在页面中插入<base>
标签,通过在远程服务器伪造图片、链接或脚本,劫持当前页面中所使用“相对路径”的标签
所以在设计XSS安全方案时,一定要过滤掉这个危险的标签。
window对象是浏览器的窗体,很多时候window对象不受同源策略限制,可以实现跨域、跨页面传递数据。
使用window.name可以缩短XSS Payload的长度
<script> window.name = "alert(document.cookie)"; location.href = "http://www.xss.com" </script>
在同一个窗口打开XSS的站点后,只需要通过XSS执行代码
eval(window.name);
向服务器提交
Expect: <script>alert('xss');</script>
当服务器出错返回时,Expect头的内容未经任何处理便会写入页面。对于XSS攻击来说,JavaScript工作在渲染后的浏览器环境中,无法控制用户浏览器发出的HTTP头。该漏洞当初被认为是一个鸡肋。
但是,使用Flash,可以自定义大多数请求的HTTP头。因此,Flash在新版本中禁止用户发送Expect头。但后来发现可以通过注入HTTP头的方式绕过这个限制,Flash目前已经修补了该问题。
此类攻击,还可以通过Java Applet等构造HTTP请求的第三方插件来实现。
反射型XSS也可能像存储型XSS一样利用。
回旋镖的思路是:如果在B域上存在一个反射型“XSS_B”,在A域上存在一个存储型“XSS_A”,当用户访问A域上的“XSS_A”时,同时嵌入B域上的“XSS_B“,则可以达到在A域的XSS攻击B域用户的目的。
我们知道,在IE中,<iframe>
、<img>
、<link>
等标签都会拦截”第三方Cookie“的发送。在Firefox则无这种限制(第三方Cookie指得是保存在本地的Cookie,也就是服务器设置了expire时间的Cookie)。
所以对于Firefox,只需要在XSS_A处嵌入一个iframe即可
<iframe src="http://www.b.com/?xss..."></iframe>
对于IE,为了达到执行XSS_B的目的,可以使用一个<form>
标签,在浏览器提交form表单时,不会拦截第三方Cookie的发送。因此,先在XSS_A上写一个<form>
,自动提交到XSS_B,然后在XSS_B中再跳转回原来的XSS_A,完成了一个”回旋镖“。这种攻击的缺点是,用户会看到地址栏的变化。
在Flash中是可以嵌入ActionScript脚本的,
getURL("javascript:alert(document.cookie)");
使用<embed>
将Flash嵌入页面中。
在实现XSS Filter时,一般会禁用<embed>
、<object>
等标签。后者甚至可以加载ActiveX控件。
如果网站一定要使用Flash,如果仅仅是视频文件,则要求其转码为”flv文件“。flv是静态文件,不会产出安全隐患。如果是带动态脚本的Flash,可以通过Flash的配置参数限制。
限制Flash动态脚本的最重要的参数是”allowScriptAccess“,这个参数定义了Flash能否与HTML页面进行通信。它有三个可选值:
always 不做任何限制
sameDomain 只允许来自于本域的Flash与Html通信,默认值
nerver 禁止
allowNetworking 也非常关键,它能控制Flash与外部网络进行通信
all 允许所有网络 默认值
internal 不能与浏览器通信如navigateToURL,但可以调用其他的API
none 禁止
除了用户上传的Flash文件能够实施脚本攻击外,一些Flash也可能会产生XSS漏洞。
on (release) { getURL(_root.clickTAG, "_blank"); }
这段代码缺乏输入验证,会被XSS攻击。