乐趣区

Web安全之XSS构造技巧

XSS 构造技巧

利用字符编码

”百度搜藏”曾经在一个 <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> 标签

<base>标签并不常用,它定义页面上所有使用 ” 相对路径 ” 标签的 hosting 地址。它可以出现在页面的任何地方,并作用于位于该标签之后的所有标签。

攻击可以在页面中插入 <base> 标签,通过在远程服务器伪造图片、链接或脚本,劫持当前页面中所使用“相对路径”的标签

所以在设计 XSS 安全方案时,一定要过滤掉这个危险的标签。

window.name

window 对象是浏览器的窗体,很多时候 window 对象不受同源策略限制,可以实现跨域、跨页面传递数据。

使用 window.name 可以缩短 XSS Payload 的长度

<script>
  window.name = "alert(document.cookie)";
  location.href = "http://www.xss.com"
</script>

在同一个窗口打开 XSS 的站点后,只需要通过 XSS 执行代码

eval(window.name);

Apache Expect Header XSS

向服务器提交

Expect: <script>alert('xss');</script>

当服务器出错返回时,Expect 头的内容未经任何处理便会写入页面。对于 XSS 攻击来说,JavaScript 工作在渲染后的浏览器环境中,无法控制用户浏览器发出的 HTTP 头。该漏洞当初被认为是一个鸡肋。
但是,使用 Flash,可以自定义大多数请求的 HTTP 头。因此,Flash 在新版本中禁止用户发送 Expect 头。但后来发现可以通过注入 HTTP 头的方式绕过这个限制,Flash 目前已经修补了该问题。
此类攻击,还可以通过 Java Applet 等构造 HTTP 请求的第三方插件来实现。

Anehta 的回旋镖

反射型 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 XSS

在 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 攻击。

退出移动版