浅谈“HTTP Host头攻击”

一:漏洞名称:

HTTP Host头攻击

描述:

为了方便的获得网站域名,开发人员一般依赖于HTTP Host header。 例如,在php里用$_SERVER["HTTP_HOST"]。而这个header很多情况下是靠不住的。而很多应用是直接把这个值不做html编码便输出到了页面中,

比如:

    (Joomla)

还有的地方还包含有secret key和token:

  (Django, Gallery, others)

这样处理问题一般会很容易遭遇到两种常见的攻击:缓存污染和密码重置。

1、缓存污染是指攻击者通过控制一个缓存系统来将一个恶意站点的页面返回给用户。

2、密码重置这种攻击主要是因为发送给用户的内容是可以污染的,也就是说可以间接的劫持邮件发送内容。

检测条件:

1.被测网站使用了依赖HTTP Host header的功能。

2.网站具有密码重置,发送邮件功能

检测方法:

摘自https://www.fujieace.com/hacker/http-host-header.html

一、密码重置污染攻击

拿 Gallery 这个站来做例子。当我们进行密码重置的时候,网站会给我们发送一个随机的key:

$user -> hash random::hash() ;
$message -> confirm_url = url::abs_site("password/do_reset?key=$user->hash") ;

当用户点击重置密码的链接时,肯定可以说明点的是自己的账户。

 

浅谈“HTTP Host头攻击”_第1张图片

这个地方的漏洞是: url::abs_site 这一部分使用的Host header是来自用户重置密码的请求,那么攻击者可以通过一个受他控制的链接来污染密码重置的邮件。

  1. POST /password/reset HTTP/1.1
  2. > Host: evil.com
  3. > ...
  4. csrf=1e8d5c9bceb16667b1b330cc5fd48663&name=admin

这个漏洞在Django,Piwik 和Joomla中都存在,还有一些其他的应用,框架和类库。

当然这种攻击方式一定要能骗取用户点击访问这个受污染的链接,如果用户警觉了没有点击,那么攻击就会失败。当然你自己也可以配合一些社会工程学的方法来保证攻击的成功率。

还有一些情况,Host可能会被url编码后直接放到email的header里面造成header注入。通过这个,攻击者可以很容易的就能劫持用户的账户。

二、缓存污染

通过Host header来污染缓存的攻击方法最初是Carlos Beuno 在2008年提出来的。但是在现在的网络架构中,这种攻击还是比较困难的,因为现在的缓存设备都能够识别Host。比如对于下面的这两种情况他们绝对不会弄混淆:

  1. GET /index.html HTTP/1.1       > GET /index.html HTTP/1.1
  2. > Host: example.com              > Host: evil.com

因此为了能使缓存能将污染后的response返回给用户,我们还必须让缓存服务器看到的host header 和应用看到的host header 不一样。

比如说对于Varnish(一个很有名的缓存服务软件),可以使用一个复制的Host header。Varnish是通过最先到达的请求的host header来辨别host的,而Apache则是看所有请求的host,Nginx则只是看最后一个请求的host。这就意味着你可以通过下面这个请求 来欺骗Varnish达到污染的目的:

  1. > GET / HTTP/1.1
  2. > Host: example.com
  3. > Host: evil.com

应用本身的缓存也可能受到污染。比如Joomla就将取得的host值不经html编码便写进任意页面,而它的缓存则对这些没有任何处理。比如可以通过下面的请求来写入一个存储型的xss:

curl -H "Host: cow\"onerror=\'alert(1)\'rel=\'stylesheet\'" http://example.com/ | fgrep cow\"

实际上的请求是这样的:

  1. > GET / HTTP/1.1
  2. > Host: cow"οnerrοr=\'alert(1)\'rel=\'stylesheet\'

响应其实已经受到污染:

这时只需要浏览首页看是否有弹窗就知道缓存是否已经被污染了。

三、跳转钓鱼 (摘自https://www.cnblogs.com/KevinGeorge/p/8254452.html)

web开发程序重定向时候:

例如未登录访问页面会跳转回登录页面,而开发人员是无法得知自己开发的站点上线后的域名的,所以一般都是host获取。如果你重定向到登录页面所使用的HOST被攻击者污染了,改成了他的,很相似的域名,也转到仿造的一模一样的页面,用户再次输入密码,就会被盗取。

漏洞修复:

 

 

1.服务器方面:

  1. 由于http请求的特点,host header的值其实是不可信的。唯一可信的只有SERVER_NAME,这个在Apache和Nginx里可以通过设置一个虚拟机来记录所有的非法host header。在Nginx里还可以通过指定一个SERVER_NAME名单,Apache也可以通过指定一个SERVER_NAME名单并开启UseCanonicalName选项。建议两种方法同时使用。
  2. Varnish很快会发布一个补丁。在官方补丁出来前,可以通过在配置文件里加入:
import std;
        sub vcl_recv {
                std.collect(req.http.host);
        }

2、应用方面:

解决这个问题其实是很困难的,因为没有完全自动化的方法来帮助客户识别哪些host 的值是值得信任的。虽然做起来有点麻烦,但是最安全的做法是:在网站安装和初始化的时候,要求管理员提供一个可信任的域名白名单。如果这个实现起来比较困难,那至少也要保证使用SERVER_NAME而不是host header,也就是取得HOST值并保存设为常量并且鼓励用户使用安全配置做的比较好的站点。

其它补充说明:

详情漏洞原理课参考这篇文章:

HTTP HOST头攻击技术解析及防御

 

你可能感兴趣的:(Web安全之杂项类)