浅谈HTTP响应拆分攻击(二)

简介:
通过响应拆分实现跨站点脚本 
在这里需要指出,我并不打算详细解释跨站点脚本及其具体类型。网上可以轻易找到大量讨论这方面话题的文章(我会在结尾处提供一些参考链接),通过阅读大家完全能够透彻理解这一概念。 
现在我们已经对响应拆分相当熟悉,那么接下来该从攻击者的视角出发,以获得进一步的收获。我们能够通过响应拆分在目标计算机上运行JavaScript,并尝试且最终获取对其浏览器的完全控制权吗?答案是肯定的,只要对我们此前所给出的例子进行些许扩展,这一目标就可以顺利实现。 
大家应该还记得,我们在前文中所设计的第二轮恶意响应只是利用简单的页面告知用户"你已然中招了"。而要实现更邪恶的目的,我们要编写一些JavaScript代码来代替原本的简单页面。与仅仅能够实现显示功能的页面不同,JavaScript能够切实运行于用户的浏览器之中。而攻击者对于目标用户浏览器的控制能力完全取决于JavaScript代码的内容。因此,如果要对前文中所设计的例子加以扩展,攻击者会设计出如下的URL: 
http://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中会包含一个小型镜像,并随同该页面一同被载入。该镜像的<IMG SRC>标签将向 www.abc.com 网站的服务器发送内容为/transfer/php?acc1=1000&acc2=2000&amt=900的请求。 
因此在执行响应拆分攻击时,整个恶意URL的内容如下所示: 
http://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),其中包含了允许用户选择语言种类的下拉菜单。具体内容如下: 
<HTML>
<BODY> 
<FORM NAME="form" action="respsplit1.php" method="GET"> 
<select name="lang"> 
<option value="EN">English</option> 
<option value="GER">German</option> 
</select> 
<INPUT TYPE="submit" name="Submit" value=Submit></INPUT> 
</FORM> 
</BODY> 
</HTML> 
选择想要的语言类型后,大家当然会点击提交按钮,而这一输入行为将被提交至名为respsplit1.php的PHP文件处。上述所有代码的功能是截获我们的输入内容,并利用其建立一个用于重新指向的URL,再将其发送至302重新指向响应处。Respsplit1.php文件的内容如下所示: 
<?php 
$lang = $_GET['lang'] 
header("Location: http://localhost/respsplit2.php?lang=$lang"); 
?> 
在浏览器中打开该HTML文件并将其置于Burp或是任何其它类型的代理编辑器中。这时请留意我们在头一个页面点击提交后所产生的响应。大家会清楚地发现,自己在下拉菜单中选择的项目实际上是本机302响应中的响应头。因此如果各位想对此进行修改,那就必须得在请求到达服务器端之前,对lang参数的值利用恶意字符串进行编辑(也就是达到我们前面所说的一项请求两次响应)。 
respsplit2.php所做的仅仅是将大家所选择的语言种类显示出来,除此无它。 
<?php 
$a=$_GET['lang']; 
if (strcmp($a,'EN') == 0) 
echo "Language selected is English"; 
elseif (strcmp($a,'GER') == 0) 
echo "Language selected is German"; 
else 
echo "No valid language selected "; 
?> 
现在当我打算进行上试测试时,我自己的PHP框架会从响应头中把%0d%0a字符串除去,这种默认设置实际上起到了保护作用。不过如果大家所使用的是版本较老的框架,那么默认设置将不会实施保护,进而导致代码极易在CRLF处发生问题。这里所提到的过滤功能如下图所示: 
<?php 
$pattern1 = "/\%0d/"; 
$pattern2 = "/\%0a/"; 
$lang = $_GET['lang']; 
$r = preg_match($pattern1 , $lang); 
$s = preg_match($pattern2 , $lang); 
if (($r > 0) || ($s > 0)){ 
echo 'Carriage Return found in user input'; 
echo "<BR>"; 

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

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

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


本文转自    geekwolf   51CTO博客,原文链接:http://blog.51cto.com/linuxgeek/998967


相关文章
|
2月前
Servlet 教程 之 Servlet 服务器 HTTP 响应 2
Servlet教程讲解了如何通过HttpServletResponse设置HTTP响应,包括编码URL、添加cookie、设置报头、控制缓冲区、发送错误或重定向响应。方法如encodeURL、addCookie、sendError、sendRedirect等,涉及状态码、报头、字符编码和内容长度的管理。
32 2
|
2月前
|
XML Java 数据格式
Servlet 教程 之 Servlet 服务器 HTTP 响应 3
`Servlet`教程示例展示了如何创建一个HTTP响应,使用`@WebServlet(&quot;/Refresh&quot;)`的`Refresh`类继承`HttpServlet`。在`doGet`方法中,设置了`Refresh`头以每5秒自动刷新,并用`setContentType(&quot;text/html;charset=UTF-8&quot;)`设定内容类型。还使用`Calendar`和`SimpleDateFormat`获取并格式化当前时间显示。相应的`web.xml`配置指定了Servlet路径。当访问此Servlet时,页面将每5秒更新一次显示的系统时间。
37 4
|
2月前
状态码对于理解HTTP请求和响应的流程,以及调试网络问题非常重要
【5月更文挑战第15天】HTTP状态码由三位数字表示,分为1xx-5xx五类。1xx为信息响应,2xx表示成功,如200(请求成功)、201(创建成功)。3xx是重定向,如301(永久移动)、302(临时重定向)。4xx表示客户端错误,如400(坏请求)、404(未找到)。5xx是服务器错误,包括500(内部服务器错误)和503(服务不可用)。这些状态码用于理解请求响应流程和调试网络问题。
33 1
|
8天前
|
Shell Python
`pytest-httpserver`是一个pytest插件,它允许你在测试期间启动一个轻量级的HTTP服务器,并模拟HTTP请求和响应。
`pytest-httpserver`是一个pytest插件,它允许你在测试期间启动一个轻量级的HTTP服务器,并模拟HTTP请求和响应。
|
10天前
|
JSON 网络协议 数据格式
网络协议基础:HTTP请求与响应详解
【7月更文挑战第11天】HTTP协议作为Web通信的核心,其请求与响应机制是理解网络通信的关键。本文详细介绍了HTTP请求与响应的格式、过程以及常用的请求方法,帮助读者更好地理解HTTP协议的工作原理和应用场景。在实际应用中,HTTP协议的可定制性和灵活性使其能够适应多种
|
27天前
|
XML 开发框架 前端开发
http请求响应的contentType
http请求响应的contentType
25 5
|
28天前
|
缓存
HTTP响应首部字段释义
【6月更文挑战第23天】响应首部字段是由服务器端向客户端返回响应报文中所使用的字段。
|
1月前
|
XML JSON 前端开发
HTTP 请求参数与响应参数的关键区别
在 Web 的开发领域,无论你是前端开发还是后端开发人员,把握请求与响应参数的核心差异是极其重要的。这些参数在客户端和服务器之间的互动中扮演着关键角色。
|
2月前
|
存储 缓存
ETag的值是如何在HTTP响应中传递给客户端的
ETag的值是如何在HTTP响应中传递给客户端的
|
2月前
|
JSON JavaScript 中间件
使用 Node.js 开发一个简单的 web 服务器响应 HTTP get 请求
使用 Node.js 开发一个简单的 web 服务器响应 HTTP get 请求