浅谈HTTP响应拆分攻击及防范措施

核子可乐 发表于:11年10月14日 14:00 [转载] 51CTO

  • 分享:
[导读]在本文中,我们将探讨何谓HTTP响应拆分以及攻击行为是怎样进行的。一旦彻底理解了其发生原理(该原理往往被人所误解),我们就可以探究如何利用响应拆分执行跨站点脚本(简称XSS)。

通过响应拆分实现跨站点脚本

在这里需要指出,我并不打算详细解释跨站点脚本及其具体类型。网上可以轻易找到大量讨论这方面话题的文章(我会在结尾处提供一些参考链接),通过阅读大家完全能够透彻理解这一概念。

现在我们已经对响应拆分相当熟悉,那么接下来该从攻击者的视角出发,以获得进一步的收获。我们能够通过响应拆分在目标计算机上运行 JavaScript,并尝试且最终获取对其浏览器的完全控制权吗?答案是肯定的,只要对我们此前所给出的例子进行些许扩展,这一目标就可以顺利实现。

大家应该还记得,我们在前文中所设计的第二轮恶意响应只是利用简单的页面告知用户"你已然中招了"。而要实现更邪恶的目的,我们要编写一些 JavaScript代码来代替原本的简单页面。与仅仅能够实现显示功能的页面不同,JavaScript能够切实运行于用户的浏览器之中。而攻击者对于目标用户浏览器的控制能力完全取决于JavaScript代码的内容。因此,如果要对前文中所设计的例子加以扩展,攻击者会设计出如下的URL:

https://www.abc.com/index.php?lang=german%0d%0aContent- Length:%200%0d%0aHTTP/1.1%20200%20OK%0d%0aContent-Type:%20text/html%0d%0aContent- Length:%20%0d%0aalert('在你的计算机上运行JavaScript')

然后他会像以前那样向branches.html发送请求,该包含恶意JavaScript内容的请求自然会被映射至第二轮响应中。代理缓存将同原先一样受到感染,而使用着同一款代理服务器的其他用户在访问branches.html时,该JavaScript代码就会侵入他的计算机。

如果目标站点在XSS方面存在漏洞,那么我们完全可以用同样的逻辑对其展开攻击。只是在这种情况下,漏洞参数才是脚本的主体,因此我们需要利用其替换掉前一个例子中的JavaScript部分。

在我所举的例子中,JavaScript内容非常直观,结果也只是弹出一个小小的警告框。事实上JavaScript完全可以编写得更为复杂,并使攻击者获得可以完全掌控目标用户浏览器并最终控制计算机的能力。一款名为BeeF的开发框架能够为攻击者帮上大忙,只需编写一小段JavaScript再将其导入BeeF控制器,受害者的计算机就在劫难逃了。

通过响应拆分实现跨站点请求伪造

与前面一样,我不打算在这里详述CSRF攻击的来龙去脉。大家还是从文末的参考资料汇总那里去获得相关的细节信息吧。简单来说,CSRF攻击的受害者会在不知情的状态下执行某些"隐性"操作。需要强调的是,这些操作基本上都是受害者打死也不想去执行的类型。

作为CSRF攻击发生的先决条件,受害人需要首先登录到操作执行的站点上。因此如果攻击者打算诱导受害者执行的操作是"删除我的谷歌个人资料",那么用户必须要先登录到相应的谷歌系统中,操作才能顺利执行。另外,攻击者必须能够对包括参数值在内的确切结构进行预测。以银行转账操作为例,具体数额必须准确有效,如:GET /transfer/php?acc1=1000&acc2=2000&amt=900。这样只要用户在登录至www.abc.com之后发出类似的GET指令,由acc1指向acc2的转账行为将自动执行。

在CSRF攻击当中,攻击者总会使出某种花招诱导用户点击链接,或是采取社交角度的心理战术、或是让用户访问某个处于攻击者控制之下的页面;总之尽管理论上用户是自主发出的请求,但实际上后台到底执行了什么内容受害者并不知情。

现在,让我们回到响应拆分这一话题。大家应该还记得攻击者借助响应拆分特性感染branches.html页面,并向其中注入JavaScript 恶意内容以尝试在用户的浏览器上运行脚本的做法吧。而在CSRF攻击中,我们需要确保行为(例如前面提到的转账操作URL)在用户访问被感染页面时能够自动执行。换句话说,branches.html中会包含一个小型镜像,并随同该页面一同被载入。该镜像的标签将向www.abc.com网站的服务器发送内容为/transfer/php?acc1=1000&acc2=2000& amp;amt=900的请求。

因此在执行响应拆分攻击时,整个恶意URL的内容如下所示:

https://www.abc.com/index.php?lang=german%0d%0aContent- Length:%200%0d%0aHTTP/1.1%20200%20OK%0d%0aContent-Type:%20text/html%0d%0aContent- Length:%20%0d%0a< / body>< / html>

最终的结果是,每当用户通过代理访问受感染的页面(即branches.html),且在另一个浏览器选项卡中登录了www.abc.com站点,那么后台即会顺利地将款项转汇至攻击者指定的账户中。

示例代码:

现在让我们快速浏览一遍PHP中那些存在响应拆分漏洞的代码类型。对于初学者来说,我们以一个小型HTML文件为例(名称为respsplit1.html),其中包含了允许用户选择语言种类的下拉菜单。具体内容如下:


选择想要的语言类型后,大家当然会点击提交按钮,而这一输入行为将被提交至名为respsplit1.php的PHP文件处。上述所有代码的功能是截获我们的输入内容,并利用其建立一个用于重新指向的URL,再将其发送至302重新指向响应处。Respsplit1.php文件的内容如下所示:


在浏览器中打开该HTML文件并将其置于Burp或是任何其它类型的代理编辑器中。这时请留意我们在头一个页面点击提交后所产生的响应。大家会清楚地发现,自己在下拉菜单中选择的项目实际上是本机302响应中的响应头。因此如果各位想对此进行修改,那就必须得在请求到达服务器端之前,对lang参数的值利用恶意字符串进行编辑(也就是达到我们前面所说的一项请求两次响应)。

respsplit2.php所做的仅仅是将大家所选择的语言种类显示出来,除此无它。


现在当我打算进行上试测试时,我自己的PHP框架会从响应头中把%0d%0a字符串除去,这种默认设置实际上起到了保护作用。不过如果大家所使用的是版本较老的框架,那么默认设置将不会实施保护,进而导致代码极易在CRLF处发生问题。这里所提到的过滤功能如下图所示:

0) || ($s > 0)){ echo 'Carriage Return found in user input'; echo "

"; } else { header("Location: https://localhost/respsplit2.php?lang=$lang"); } ?>

我们可以自主编写更为高效的过滤器,例如将内容只包含字母及数字的项目列入白名单,并直接屏蔽掉其它一切类型;但这仅仅是防御性代码的一种使用范例。如果大家忘记编写这类过滤器,那么就等于将自己的命运完全交付给所使用的框架本身。如果各位与我使用的框架相似(Ubuntu 10.04内的APT库)还好,因为其中内置了保护机制…否则就等着为此而付出惨重代价吧。

目前已经被发现了为数不少的响应拆分类漏洞。我在文末的参考链接中提供了详细的清单

[责任编辑:黄辉]
大黄
以备份起家的CommVault近两年的解决方案不断向更全面的数据保护转型,并对数据管理、数据挖掘也有了一些关注。CommVault中国区技术总监蔡报永接受采访时表示CommVault将继续做一家专注做数据管理和信息管理的软件厂商。
官方微信
weixin
精彩专题更多
存储风云榜”是由DOIT传媒主办的年度大型活动。回顾2014年,存储作为IT系统架构中最基础的元素,已经成为了推动信息产业发展的核心动力,存储产业的发展迈向成熟,数据经济的概念顺势而为的提出。
华为OceanStor V3系列存储系统是面向企业级应用的新一代统一存储产品。在功能、性能、效率、可靠性和易用性上都达到业界领先水平,很好的满足了大型数据库OLTP/OLAP、文件共享、云计算等各种应用下的数据存储需求。
联想携ThinkServer+System+七大行业解决方案惊艳第十六届高交会
 

公司简介 | 媒体优势 | 广告服务 | 客户寄语 | DOIT历程 | 诚聘英才 | 联系我们 | 会员注册 | 订阅中心

Copyright © 2013 DOIT Media, All rights Reserved. 北京楚科信息技术有限公司 版权所有.