http://mdsec.net/settings/12/
http://mdsec.net/settings/31/
攻击者可以建立一个URL,在请求它的任何用户的浏览器中设定任意cooike。例如:
如果进行适当配置,这些cookie可以访问不同的浏览器会话。这时,通过前面利用反射型XSS漏洞时使用的相同传送机制(电子邮件、第三方Web站点等),就可以诱使目标用户访问恶意URL。
传送其他攻击
因为HTTP消息头注入允许攻击者控制整个响应主体,所以几乎任何针对其他用户的攻击都可以使用它作为传送机制,包括虚拟Web站点置换、脚本注入、任意重定向、针对ActiveX控件的攻击等。
HTTP响应分割
这是一种试图通过恶意内容“毒害”代理服务器缓存,从而攻破通过代理服务器访问应用程序的其他用户的攻击技巧。例如,如果企业网络中的所有用户通过缓存代理服务器访问某个应用程序,那么,通过在代理服务器的缓存中注入恶意内容(显示给任何请求受影响页面的用户),攻击者就可以向这些用户实施攻击。
攻击者可以按以下步骤,利用消息头注入漏洞来实施响应分割攻击:
(1)攻击者在代理服务器缓存中选择一个他希望“毒害”的应用程序页面。例如,他可能会用一个木马登录表单(用于向攻击者的服务器提交用户证书)代替/admin/处的页面。
(2)攻击者确定某个消息头注入漏洞,构造一个请求,在服务器响应中注入一个完整的HTTP主体以及另一组响应消息头和另一个响应主体。第二个响应主体中包含他的木马登录表单的HTML源代码。这样,服务器的响应看起来就像是两个连接在一起的单独HTTP响应。因此,这种技巧叫做HTTP响应分割(HTTP response splitting),因为攻击者已经把服务器的响应“分割”成两个单独的响应。例如:
(3)攻击者与代理服务器建立TCP连接,传送这个专门设计的请求,后面紧跟着访问被“毒害”的页面的请求。在HTTP协议中,以这种方式连接请求是合法的。
(4)代理服务器与应用程序建立TCP连接,送出这两个以相同方式连接的请求。
(5)应用程序用攻击者注入的HTTP内容响应第一个请求,它看起来就像是两个单独的HTTP响应。
(6)代理服务器收到这两个看似单独的响应,并认为其中第二个响应与攻击者的第二个请求相对应,该请求指向URL:http://mdsec.net/admin/。代理服务器把第二个响应作为这个URL的内容保存在缓存中。(如果代理服务器已经在缓存中保存有该页面的副本,那么攻击者就可以在他的第二个请求中插入一个适当的If-Modified-Since消息头,并在注入的响应中插入一个Last-Modified消息头,使得代理服务器重新请求这个URL,用新的内容更新它的缓存。)
(7)应用程序发布它对攻击者的第二个请求的响应,其中包含URL http://mdsec.net/admin/的真实内容。代理服务器并不认为它是对它发布的请求的响应,因而抛弃这个响应。
(8)一名用户通过代理服务器访问http://mdsec.net/admin/,并收到这个URL保存在代理服务器缓存中的内容。这个内容实际上是攻击者的木马登录表单,因此用户的证书被攻破。
实施这种攻击的步骤如图13-3所示。
图13-3 用于毒害代理服务器缓存的HTTP响应分割攻击涉及的步骤
要防止HTTP消息头注入漏洞,最有效方法是杜绝将用户控制的输入插入到应用程序返回的HTTP消息头中。如我们在介绍任意重定向漏洞时所述,通常可以用一些较为安全的方法代替这种行为。
如果不可避免地要在HTTP消息头中插入用户控制的数据,那么应用程序应采取以下双重深层防御方法防止漏洞产生。
输入确认。应用程序应根据情形,对插入的数据进行尽可能严格的确认。例如,如果根据用户输入设定一个cookie值,那么应将这个值限制为仅包含字母字符,最大长度为6字节。
输出确认。应对插入到消息头中的所有数据进行过滤,检测可能的恶意字符。实际上,任何ASCII码小于0x20的字符都应被视为可疑的恶意字符,应用程序应拒绝包含这些字符的请求。
只有应用程序在其SSL终止符后未使用缓存反向代理服务器,它才能通过对所有应用程序内容使用HTTPS,防止攻击者利用任何残留的消息头注入漏洞“毒害”代理服务器缓存。
在cookie攻击中,攻击者利用应用程序功能或浏览器行为的某种特性,在受害用户的浏览器中设置cookie,或修改该cookie。
攻击者可以通过各种方式实施cookie注入攻击。
某些应用程序的功能在请求参数中使用一个名称和值,并在响应的cookie中设置该名称和值。保存用户首选项大多属于此类功能。
如前所述,如果存在HTTP消息头注入漏洞,就可以利用此漏洞注入任意Set-Cookie消息头。
可以利用相关域中的XSS漏洞在目标域上设置一个cookie。目标域的任何子域,以及目标域的父域及其子域,都可以通过这种方式加以利用。
可以利用主动中间人攻击(例如,针对公共无线网络中的用户)在任意域上设置cookie,即使目标应用程序仅使用HTTPS并且将其cookie标记为安全。我们将在本章后面部分详细介绍这种攻击。
如果攻击者可以设置任意cookie,他就可以利用该cookie以各种方式攻击目标用户:
在某些应用程序中,设置一个特殊的cookie可能会破坏应用程序的逻辑,给用户造成不利影响(例如,UseHttps=false)。
由于cookie通常仅由应用程序本身设置,因此它们会受客户端代码信任。该代码可能会以各种危险的方式(对攻击者可控制的数据而言)处理cookie值,导致基于DOM的XSS或JavaScript注入。
除将反CSRF令牌与用户会话关联外,一些应用程序还在cookie和请求参数中放置该令牌,
然后对它们的值进行比较,以防止CSRF攻击。如果攻击者可以控制cookie和参数值,就能够避开这种防御。
如本章前面部分所述,攻击者可以利用某个永久性XSS漏洞,通过针对登录功能的CSRF攻击使用户登录攻击者的账户,并因此访问XSS有效载荷。如果登录页面能够有效防范CSRF,这种攻击将无法奏效。但是,如果攻击者能够在用户的浏览器中设置任意cookie,他就可以直接向用户传送自己的会话令牌,从而成功实施攻击,而不必实施针对登录功能的CSRF攻击。
设置任意cookie可以对会话固定漏洞加以利用(将在下一节介绍)。
会话固定
如果应用程序在用户首次访问它时为每一名用户建立一个匿名会话,这时往往就会出现会话固定漏洞。如果应用程序包含登录功能,这个匿名会话将在用户登录前创建,然后,一旦用户登录,该会话即升级为通过验证的会话。最初,会话令牌并未被赋予任何访问权限,但当用户通过验证后,这个令牌也具有了该用户的访问权限。
在标准的会话劫持攻击中,攻击者必须使用某种方法截获一名应用程序用户的会话令牌。另一方面,在会话固定攻击中,攻击者首先从应用程序中直接获得一个匿名令牌,然后使用某种方法将这个令牌“固定”在受害者的浏览器中。用户登录后,攻击者就可以使用该令牌劫持这名用户的会话。
成功实施这种攻击所需的步骤如图13-4所示。
图13-4 实施会话固定攻击所需的步骤
当然,在这个攻击中,最关键的阶段应该是攻击者向受害者传送他获得的会话令牌,并令受害者的浏览器使用这个令牌。实现这一目标的方法因传送会话令牌所采用的机制而异。
如果使用HTTP cookie,攻击者可以尝试使用上一节介绍的某种cookie注入技巧。
如果在URL参数中传送会话令牌,则攻击者只需向受害者传递应用程序向其发布的同一URL:
一些应用程序服务器接受在URL中使用它们以分号分隔的会话令牌。一些应用程序默认这样做,而其他应用程序则直接以这种方式使用令牌,即使这并非服务器的默认行为:
如果应用程序使用HTML表单中的隐藏字段来传送会话令牌,攻击者可以利用CSRF攻击在用户的浏览器中插入他的令牌。
并不提供登录机制的应用程序中也可能存在会话固定漏洞。例如,某应用程序可能允许匿名用户浏览产品目录、在购物篮中添加商品、通过提交个人数据与支付细节进行结算,然后在“确认订单”页面上审核这些信息。在这种情况下,攻击者就可以将一个匿名会话令牌固定到受害者的浏览器中,等待该用户提交订单并输入敏感信息,然后使用该令牌访问“确认订单”页面,截获该用户的信息。
一些Web应用程序与Web服务器接受用户提交的任意令牌,即使这些令牌并不是由服务器在此前发布的。如果收到一个不被认可的令牌,服务器会直接为这个令牌建立一个新会话,并把它当做服务器生成的新令牌处理。过去,Microsoft IIS与Allaire ColdFusion服务器都存在这种缺陷。
如果一个应用程序或服务器以这种方式运作,它就非常容易受到会话固定攻击,因为攻击者根本不必采取任何措施确保固定在目标用户的浏览器中的令牌当前有效。攻击者只需选择任意一个令牌,将其尽可能广地进行分发(例如,通过电子邮件向个体用户、邮件列表等发送一个包含该令牌的URL),然后定期访问应用程序中的某个受保护页面(如“用户资料”),检查受害者何时使用这个令牌登录。即使目标用户几个月都没有访问这个URL,但蓄意破坏的攻击者仍然有可能劫持该用户的会话。
查找并利用会话固定漏洞
如果应用程序支持身份验证,则应该检查它如何处理与登录有关的会话令牌。在下面两种情况下,应用程序可能易于受到攻击。
应用程序向每名未通过验证的用户发布一个匿名会话令牌。在用户登录后,它并不发布新令牌,相反,他们现有的会话被升级为通过验证的会话。使用应用程序服务器的默认会话处理机制的应用程序常常采用这种行为。
应用程序并不向匿名用户发布令牌;只有用户成功登录后,应用程序才向该用户发布令牌。但是,如果用户使用通过验证的令牌访问登录功能,并使用不同的证书登录,则应用程序并不发布新令牌;相反,与之前通过验证的会话关联的用户身份将转换为第二名用户的身份。