迄今为止,我们在这一章和上一章介绍的攻击主要与利用应用程序的某种行为特征攻破应用程序用户有关。虽然某些攻击技巧需要利用特定浏览器的怪癖,但跨站点脚本、跨站点请求仿造以及JavaScript劫持之类的攻击全都源于特定Web应用程序中的漏洞。
另一类针对用户的攻击并不依赖于特定应用程序的行为。相反,这些攻击主要利用浏览器的行为特征,或者核心Web技术本身的设计缺陷。这些攻击可能由任何恶意网站或任何本身已被攻破的“良性”站点实施。介绍Web应用程序攻击的书籍通常都没有涉及这类攻击。但是,我们有必要简单了解这些攻击,部分是因为它们与利用应用程序特定功能的攻击的某些特点相同。通过展示在不存在任何应用程序特定漏洞的情况下,攻击者可以达到什么目的,这些攻击还为我们了解各种应用程序行为的影响提供了相关信息。
以下各部分的介绍相对比较简单。有关这方面的主题,可以写成一本书。拥有大量空余时间的准作者可以向Wiley提交出版The Browser Hacker’s Handbook 的提议。
JavaScript可在浏览器窗口处于激活状态时监控用户按下的所有键,包括密码、私人消息和其他个人信息。下面的概念验证脚本将截获Internet Explorer中的所有键击,并在浏览器的状态栏中显示全部内容:
只有当运行上述代码的框架处于激活状态时,这些攻击才能捕获键击。但是,如果在自身页面的框架内嵌入了第三方小组件或广告小程序,某些应用程序可能易于受到键击记录攻击。在所 谓的“逆向键击劫持”攻击中,在子框架中运行的恶意代码能够夺取顶层窗口的控制权,因为同源策略并不能阻止这种操作。恶意代码可以通过处理onkeydown事件来捕获键击,并且能够将单独的onkeypress事件传递给顶层窗口。这样,输入的文本仍然会在顶层窗口中正常显示。通过在暂停输入时暂时放弃激活状态,恶意代码甚至可以在顶层窗口内的正常位置保留显示闪烁的光标。
JavaScript可用于实施蛮力攻击,查明用户最近访问的第三方站点以及他们在常用搜索引擎上执行的查询。在介绍蛮力攻击(实施此攻击的目的,是为了确定可在其他域上使用的有效反CSRF令牌)时,我们已经讨论了这种技巧。攻击者可以动态创建常用Web站点以及搜索查询的超链接,并使用getComputedStyle API检查这些链接是否以彩色标记为“已被访问”,从而完成这项任务。而且,攻击者可以迅速检查大量可能的目标,而不会给用户造成很大的影响。
JavaScript可用于确定用户当前是否登录到第三方Web应用程序。大多数应用程序都包含只有登录用户可查看的页面,如“用户资料”页面。如果未通过验证的用户请求这个页面,将会收到错误消息,或者一个转向登录页面的重定向链接。
通过对受保护的页面执行跨域脚本包含,并运行定制的错误处理程序来处理脚本错误,种行为可确定用户是否已经登录第三方Web应用程序:
当然,无论受保护的页面处于什么状态,由于它仅包含HTML内容,因此这时将会出现一个JavaScript错误。重要的是,根据实际返回的HTML文档,该错误将包含不同的行号与错误类型。接下来,攻击者可以运行错误处理程序(在fingerprint函数中),检查用户登录时产生的行号与错误类型。尽管应用程序实施了同源策略,但攻击者的脚本仍然能够推断出受保护页面的状态。
确定用户当前登录哪些常用的第三方应用程序后,攻击者就可以执行针对性极强的跨站点请求伪造攻击,以被攻破的用户身份在应用程序中执行任意操作。
JavaScript可对用户本地网络或其他可访问的网络上的主机进行端口扫描,以确定可被利用的服务。如果用户受到企业或家庭防火墙的保护,攻击者将能够到达无法通过公共互联网访问的服务。如果攻击者扫描客户端计算机的回环接口,就能够避开用户安装的任何个人防火墙。
基于浏览器的端口扫描可使用Java applet确定用户的IP地址(可能进行了网络地址转换),从而推断出本地网络的IP范围。然后,脚本尝试与任意主机和端口建立连接,以测试连通性。如前所述,同源策略阻止脚本处理这些请求的响应。但是,在检测登录状态时使用的相似技巧也可用 于测试网络连通性。这时,攻击者的脚本尝试从每个目标主机和端口动态加载并执行一段脚本。如果那个端口上有Web服务器正在运行,它将返回HTML或其他一些内容,生成端口扫描脚本能够检测到的JavaScript错误。否则,连接尝试将会超时或不返回任何数据,在这种情况下不会导致错误。因此,尽管应用程序实施同源限制,端口扫描脚本仍然能够确定任意主机和端口的连通性。
请注意,大多数浏览器都在可以使用HTTP访问的端口上实施了限制,并阻止了其他主要服务常用的端口(如用于SMTP的端口25)。但是,通过利用相关漏洞,可以突破这些浏览器实施的限制。
成功使用端口扫描确定其他主机后,就可以使用一段恶意脚本尝试标识每一个发现的服务,然后通过各种方法实施攻击。
许多Web服务器包含位于特殊URL位置的图像文件。下面的代码检查一幅与一系列常用DSL路由器有关的图像:
如果notNetgear函数未被调用,则说明服务器已被成功标识为NETGEAR路由器。接下来,脚本可通过利用特定软件中任何已知的漏洞,或执行请求伪造攻击,继续攻击Web服务器。在本示例中,攻击者可以尝试使用默认证书登录路由器,并对路由器进行重新配置,以打开其外部接口上的其他端口,或向外界披露它的管理功能。注意,许多这种非常有效的攻击只需要提出任意请求,而不需要处理它们的响应,因此不会受到同源策略的限制。
在某些情况下,攻击者可以利用DNS重新绑定(DNS rebinding)技巧违反同源策略,从本地网络中的Web服务器中检索内容。这些攻击将在本章后面讨论。
除针对Web服务器实施攻击外,有些情况下还可以利用用户的浏览器、针对可以从用户的计算机访问的非HTTP服务实施攻击。只有所攻击的服务接受必然会在每个请求的开头出现的HTTP消息头,攻击者就可以在消息主体中发送任意二进制内容,从而与非HTTP服务进行交互。实际上,许多网络服务都接受无法识别的输入,并仍然处理随后针对相关协议而构造的输入。
我们已在第12章介绍了一种跨域发送任意消息主体的技巧,该技巧使用HTML表单(其enctype属性设置为text/plain)向易受攻击的应用程序发送XML内容。下面的论文介绍了实施这类攻击的其他技巧:
www.ngssoftware.com/research/papers/InterProtocolExploitation.pdf
这类协议间攻击可对目标服务实施未授权操作,或利用该服务内的代码级漏洞来攻破目标服务器。
此外,在某些情况下,还可以对非HTTP服务行为加以利用,针对在同一服务器上运行的Web应用程序实施XSS攻击。要实施这种攻击,必须满足以下条件。
非HTTP服务必须在未被浏览器阻止的端口上运行(如前所述)。
非HTTP必须接受浏览器发送的意外HTTP消息头,而不仅仅是在出现这种情况时关闭网络连接。许多服务都接受意外HTTP消息头,特别是那些基于文本的服务。
非HTTP服务必须在其响应中(如在错误消息中)回显一部分请求内容。
浏览器必须接受不包含有效HTTP消息头的响应,并且必须将一部分响应作为HTML处理(如果响应中包含HTML)。实际上,在收到合适的非HTTP响应时,所有最新版本的浏览器都以这种方式进行处理(可能是为了向后兼容)。
在隔离域源访问cookie时,浏览器必须忽略端口号。确实,在处理cookie时,当前浏览器会忽略端口。
如果满足这些条件,攻击者就可以构建针对非HTTP服务的XSS攻击。要实施这种攻击,需要以正常方式在URL或消息主体中发送专门设计的请求。然后,请求中包含的脚本代码将被回显,并在用户的浏览器中执行。该代码可以从非HTTP服务所在的域中读取用户的cookie,然后将这些cookie传送给攻击者。
如果用户的浏览器或任何安装的扩展存在漏洞,攻击者就可以通过恶意JavaScript或HTML代码利用这些漏洞。某些情况下,攻击者可以利用Java虚拟机之类的扩展中的漏洞、与本地计算机或其他位置上的非HTTP服务进行双向二进制通信。这样,攻击者就可以利用通过端口扫描确定的存在于其他服务中的漏洞。许多软件产品(包括并非基于浏览器的产品)还安装了可能包含漏洞的ActiveX控件。
DNS重新绑定(DNS rebinding)是一种在某些情况下可部分违反同源策略,从而允许恶意Web站点与其他域进行交互的技术。之所以能够实施这种攻击,是因为同源策略主要基于域名进行隔离,而最终传送HTTP请求则需要将域名转换为IP地址。
整体看来,这种攻击的过程如下。
用户访问攻击者域上的恶意Web页面。为检索此页面,用户的浏览器会将攻击者的域名解析为攻击者的IP地址。
攻击者的Web页面向攻击者的域提出Ajax请求(同源策略允许这种行为)。攻击者利用DNS重新绑定确保浏览器再次解析攻击者的域,在这次解析过程中,域名将解析为攻击者所针对的第三方应用程序的IP地址。
随后针对攻击者的域名提出的请求将被发送到目标应用程序。由于这些请求与攻击者的原始页面在同一个域上,因此,同源策略允许攻击者的代码检索目标应用程序返回的请求的内容,并将这些内容返还给攻击者(可能位于受其控制的其他域上)。
实施这种攻击将面临各种阻碍,包括一些浏览器为继续使用以前解析的IP地址(即使域已被 重新绑定到其他地址)而采用的机制。此外,浏览器发送的Host消息头仍然会引用攻击者的域,而不是可能会导致问题的目标应用程序的域。之前,攻击者可以利用一些方法在各种浏览器上突破这些阻碍。除浏览器外,还可以针对浏览器扩展和Web代理实施DNS重新绑定攻击,不过浏览器扩展和Web代理的运行机制可能会有所不同。
请注意,在DNS重新绑定攻击中,就浏览器而言,针对目标应用程序的请求仍然在攻击者的域中提出。因此,这些请求中不会包含目标应用程序所在的域的任何cookie。为此,攻击者可以通过DNS重新绑定从目标应用程序检索到的内容,与任何可以直接向目标应用程序提出请求的用户能够检索到的内容相同。因此,这种技巧在目标应用程序已实施了其他控制来防止攻击者直接与其进行交互的情况下尤其有用。例如,如果用户处在无法通过互联网直接访问的组织内部网络中,攻击者可以诱使该用户从所在网络的其他系统中检索内容,并将这些内容传送给攻击者。
人们已开发出各种框架,用以演示和利用各种针对因特网终端用户的攻击。这些框架通常需要通过某种漏洞(如XSS),在受害者的浏览器中放入一个JavaScript钩子(hook)。放置钩子后,浏览器就会与攻击者控制的服务器建立联系。浏览器会定期访问这个服务器,向攻击者提交数据,同时提供一个控制信道,方便接收攻击者发出的命令。
注解
尽管同源策略实施了各种限制,但在这种情况下,攻击者仍然可以利用各种技巧、通过已注入到目标应用程序中的脚本与其控制的服务器进行双向异步交互。一种简单的方法是对自己的域实施动态跨域脚本包含。这些请求能够向攻击者提交截获的数据(在URL查询字符串中),并接收有关应执行的操作的指令(在返回的脚本代码中)。
以下是可以在这种类型的框架中执行的一些操作:
记录键击并向攻击者发送这些内容;
劫持用户访问易受攻击的应用程序的会话;
“指纹”识别受害者的浏览器,从而利用已知的浏览器漏洞;
对其他主机(位于被攻破的用户浏览器能够访问的私有网络中)进行端口扫描,并向攻击者传送扫描结果;
通过迫使浏览器发送恶意请求,可对借助被攻破的用户浏览器访问的其他Web应用程序实施攻击;
对用户的浏览历史记录实施蛮力攻击,并将结果送交给攻击者。
BeEF是一个典型的综合型浏览器利用框架,它由Wade Alcon开发,能够执行上述功能。图13-8说明了BeEF如何截取一名被攻破用户的信息,包括计算机的相关资料、当前显示的URL与页面内容,以及用户输入的键击。
图13-9显示BeEF正对受害用户的计算机进行端口扫描。
图13-9 BeEF正对一名被攻破的用户计算机进行端口扫描
XSS Shell是另外一个功能非常强大的浏览器利用框架,它由Ferrruh Mavituna开发。这个框架提供一系列功能,可控制通过XSS攻破的僵尸主机(zombie host),包括截获键击、剪贴板内容、鼠标移动、屏幕截图、URL历史记录,以及注入任意JavaScript命令。即使导航到应用程序的其他页面,它还会驻留在用户的浏览器中。
我们在前几章中讲到,如果应用程序使用未加密HTTP通信,则位于适当位置的攻击者可以通过各种方式拦截敏感数据,如密码和会话令牌。更令人惊奇的是,即使应用程序使用HTTPS传输所有敏感数据,并且目标用户始终验证是否正确使用了HTTPS,攻击者仍然能够实施一些严重的攻击。
这类攻击称为“中间人”攻击。这类攻击者不只是被动监视其他用户的流量,而且会动态更改某些流量。这类攻击往往更加复杂,但确实可以在各种常见的情形(包括无线公共热点和共享的办公网络)中实施。
许多应用程序使用HTTP传输非敏感数据,如产品说明和帮助页面。如果这些内容使用绝对URL实现任何脚本包含,攻击者就可以利用主动中间人攻击攻破同一域上受HTTPS保护的请求。例如,某应用程序的帮助页面可能包含以下代码:
目前,许多知名Web应用程序都采用这种行为,即使用绝对URL包含通过HTTP传送的脚本。在这种情况下,活跃的中间人攻击者当然可以通过修改任何HTTP响应来执行任意脚本代码。但是,由于同源策略通常会将通过HTTP和HTTPS加载的内容视为属于不同来源,攻击者并不能利用这种攻击截获使用HTTPS访问的内容。
为克服这种障碍,攻击者可以通过修改任何HTTP响应来构建重定向,或在其他响应中重写链接目标,从而诱使用户通过HTTPS加载同一页面。当用户通过HTTPS加载帮助页面时,其浏览器将使用HTTP执行指定的脚本包含。令人遗憾的是,一些浏览器在这种情况下并不显示任何警告。然后,攻击者可以在包含脚本的响应中返回任意脚本代码。该脚本将在HTTPS响应中执行,允许攻击者截获通过HTTPS访问的所有内容。
即使所攻击的应用程序并不使用普通HTTP传送任何内容,但攻击者仍然可以通过向任何其他域提出HTTP请求来返回重定向,从而诱使用户使用普通HTTP向目标域提出请求。虽然应用程序本身可能不会监听端口80上的HTTP请求,但攻击者可以拦截这些诱发的请求,并在这些请求的响应中返回任意内容。在这种情况下,攻击者可以采用各种技巧来攻击应用程序域的HTTPS来源。
首先,如介绍cookie劫持攻击时所述,攻击者可以使用通过普通HTTP传送的响应来设置或更新HTTPS请求使用的cookie值。即使cookie最初通过HTTPS设置并被标记为安全,攻击者仍然可以这样做。如果有任何cookie值由在HTTPS来源中运行的脚本代码以危险的方式进行处理,攻击者就可以利用cookie注入攻击、通过该cookie来实施XSS攻击。
其次,我们在前面讲到,一些浏览器扩展并不能正确隔离通过HTTP和HTTPS加载的内容,并将这些内容视为属于同一来源。这时,攻击者的脚本(由诱发的HTTP请求的响应返回)就可以利用此类扩展来读取或写入用户使用HTTPS访问的页面的内容。
要实施上述攻击,需要通过某种方法,如从用户向任何其他域提出的HTTP请求返回重定向响应,诱使用户向目标域提出任意HTTP请求。你可能认为极为注重安全的用户并不会受到上述攻击。假设用户一次仅访问一个Web站点,并在访问每个新站点之前重新启动浏览器。假设他使用全新的浏览器登录自己的银行应用程序,并且该程序仅使用HTTPS传输数据。他是否会受到中间人攻击呢?
令人担心的是答案是肯定的,他可能会受到攻击。今天的浏览器会在后台提出各种普通HTTP请求,而不论用户访问哪一个域。常见的例子包括反钓鱼列表、版本ping以及针对RSS源的请求。这时,攻击者可以通过HTTP,用指向目标域的重定向来响应其中的任何请求。如果浏览器直接 访问该重定向,攻击者就可以实施上述某种攻击,首先攻破目标域的HTTP来源,然后将攻击扩展到HTTPS来源。
注重安全的用户如果需要通过不可信网络访问受HTTPS保护的敏感内容,可以将浏览器的代理配置设置为“对除HTTPS以外的所有协议使用无效的本地端口”,从而在一定程度上阻止上述攻击。即使这样做,他们仍然需要当心针对SSL的主动攻击(该主题不属于本书的讨论范围)。