http://mdsec.net/error/5/
注解
如果在Internet Explorer中尝试这样的示例,弹出窗口可能无法显示,浏览器可能会显示以下消息:“为帮助阻止跨站点脚本,Internet Explorer已修改此页面。”这是因为最新版本的Internet Explorer包含一个旨在帮助用户防范反射型XSS漏洞的内置机制。如果要测试这些示例,可以尝试使用其他未使用这种保护机制的浏览器,或者通过以下方式禁用XSS筛选器:“工具” → “Internet选项” → “安全” → “自定义级别”,在“启用XSS筛选器”下选择“禁用”。我们将在本章后面部分讨论XSS筛选器的工作机制,以及避开这种筛选器的方法。
在现实世界的Web应用程序中存在的XSS漏洞,有近75%的漏洞属于这种简单的XSS bug。由于利用这种漏洞需要设计一个包含嵌入式JavaScript代码的请求,随后这些代码又被反射到任何提出请求的用户,因而它被称作反射型XSS。攻击有效载荷分别通过一个单独的请求与响应进行传送和执行。为此,有时它也被称为一阶XSS。
利用漏洞
下文将会介绍,利用XSS漏洞攻击应用程序其他用户的方式有很多种。最简单的一种攻击,也是我们常用于说明XSS漏洞潜在影响的一种攻击,可导致攻击者截获通过验证的用户的会话令牌。劫持用户的会话后,攻击者就可以访问该用户经授权访问的所有数据和功能(参见第7章)。实施这种攻击的步骤如图12-3所示。
(1)用户正常登录应用程序,得到一个包含会话令牌的cookie:
(2)攻击者通过某种方法(详情见下文)向用户提交以下URL:
和前面生成一个对话框消息的示例一样,这个URL包含嵌入式JavaScript代码。但是,这个示例中的攻击有效载荷更加恶毒。
(3)用户从应用程序中请求攻击者传送给他们的URL。
(4)服务器响应用户的请求。由于应用程序中存在XSS漏洞,响应中包含攻击者创建的JavaScript 代码。
(5)用户浏览器收到攻击者的JavaScript代码,像执行从应用程序收到的其他代码一样,浏览器执行这段代码。
(6)攻击者创建的恶意JavaScript代码为:
这段代码可让用户浏览器向mdattacker.net (攻击者拥有的一个域)提出一个请求。请求中包含用户访问应用程序的当前会话令牌:
(7)攻击者监控访问mdattacker.net的请求并收到用户的请求。攻击者使用截获的令牌劫持用户的会话,从而访问该用户的个人信息,并“代表”该用户执行任意操作。
注解
第6章已经介绍过,一些应用程序保存一个持久性cookie,以在用户每次访问时重新对其进行有效验证,例如,执行“记住我”功能。这时,就没有必要执行上述过程中的第一个步骤。即使目标用户并未处于活动状态或登录应用程序,攻击者仍然能够成功实现目标。为此,以这种方式使用cookie的应用程序更易受到XSS漏洞的影响。
完成上述步骤后,读者可能会心存疑惑:如果攻击者能够诱使用户访问他选择的URL,那么他为什么还要费这么大力气通过应用程序中的XSS漏洞传送自己的恶意JavaScript代码呢?为什么他不在mdattacker.net上保存一段恶意脚本,并向用户传送一个直接指向这段脚本的链接呢?这段脚本不是可以和上例中的脚本一样执行吗?
要了解攻击者为什么需要利用XSS漏洞,需要回顾第3章介绍的同源策略。为防止不同域在用户浏览器中彼此干扰,浏览器对从不同来源(域)收到的内容进行隔离。攻击者的目的不是单纯地执行任意脚本,而是截获用户的会话令牌。浏览器不允许任何旧有脚本访问一个站点的cookie,否则,会话就很容易被劫持。而且,只有发布cookie的站点能够访问这些cookie:仅在返回发布站点的HTTP请求中提交cookie ;只有通过该站点返回的页面所包含或加载的JavaScript才能访问cookie。因此,如果mdattacker.net上的一段脚本查询document.cookie,它将无法获得mdsec.net发布的cookie,劫持攻击也不会成功。
就用户的浏览器而言,利用XSS漏洞的攻击之所以取得成功,是因为攻击者的恶意JavaScript是由mdsec.net送交给它的。当用户请求攻击者的URL时,浏览器向http://mdsec.net/error/5/Error.ashx提交一个请求,然后应用程序返回一个包含一段JavaScript的页面。和从mdsec.net收到的任何JavaScript一样,浏览器执行这段脚本,因为用户信任mdsec.net。这也就是为何攻击的脚本能够访问mdsec.net发布的cookie的原因,虽然它实际来自其他地方。这也是为何该漏洞被称作跨站点脚本的原因。
另一种常见的XSS漏洞叫做保存型跨站点脚本。如果一名用户提交的数据被保存在应用程序中(通常保存在一个后端数据库中),然后不经适当过滤或净化就显示给其他用户,此时就会出现这种漏洞。
在支持终端用户交互的应用程序中,或者在具有管理权限的员工访问同一个应用程序中的用户记录和数据的应用程序中,保存型XSS漏洞很常见。例如,以一个拍卖应用程序为例,它允许买家提出与某件商品有关的问题,然后由卖家回答。如果一名用户能够提出一个包含嵌入式JavaScript的问题,而且应用程序并不过滤或净化这个JavaScript,那么攻击者就可以提出一个专门设计的问题,在任何查看该问题的用户(包括卖家和潜在的买家)的浏览器中执行任意脚本。在这种情况下,攻击者就可让不知情的用户去竞标一件他不想要的商品;或者让一位卖家接受他提出的低价,结束竞标。
一般情况下,利用保存型XSS漏洞的攻击至少需要向应用程序提出两个请求。攻击者在第一个请求中传送一些专门设计的数据,其中包含恶意代码,应用程序接受并保存这些数据。在第二个请求中,一名受害者查看某个包含攻击者的数据的页面,这时恶意代码开始执行。为此,这种漏洞有时也叫做二阶跨站点脚本。(在这个示例中,使用XSS实际上并不准确,因为攻击中没有跨站点元素。但由于这个名称被人们广泛使用,因此我们在这里仍然沿用它。)
图12-4说明了一名攻击者如何利用保存型XSS漏洞,实施上述利用反射型XSS漏洞实施的相同会话劫持攻击。