|
|
|
联系客服020-83701501

利用HTTP host头攻击的技术

联系在线客服,可以获得免费在线咨询服务。 QQ咨询 我要预约
操作HTTP host头攻打的技术手段

个别通用网站步骤模范是如果想晓得网站域名不是一件复杂的事变,如果用一个固定的URI来作为域名会有各类贫苦。开发职员个别是托付HTTP Host header(譬喻在php里是_SERVER[“HTTP_HOST”] ),而这个header良多状况下是靠不住的。而良多使用是直接把这个值不做html编码便输出到了页面中,譬喻:

Default
1 <link href="http://_SERVER['HOST']"    (Joomla)

另有之处还网罗有secret key和token,

Default
1 <a href="http://_SERVER['HOST']?token=topsecret">  (Django, Gallery, others)

如许处置惩罚惩罚标题个别会很繁冗遭遇到两种思空见贯的攻打:缓存传染和密码重置。缓存传染是指攻打者通过管教一个缓存系统来将一个歹意网站的页面返回给用户。密码重置这类攻打次如果由于发送给用户的模式是概略传染的,也就是说概略间接的劫持邮件发送模式。

0x01 密码重置传染攻打

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

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

当用户点击重置密码的链接时,注定概略阐明点的是本身的账户。

这个地方的裂痕是: url::abs_site 这一部分使用的Host header是来自用户重置密码的请求,那末攻打者概略通过一个受他管教的链接来传染密码重置的邮件。

Default
1234 > POST /password/reset HTTP/1.1> Host: evil.com> ...> csrf=1e8d5c9bceb16667b1b330cc5fd48663&name=admin

这个裂痕在Django,Piwik 和Joomla中都具有,另有一些此外的使用,框架和类库。

尽管这类攻打行动一定要能坑骗用户点击访问这个受传染的链接,如果用户防备了不有点击,那末攻打就会腐朽。尽管你本身也概略配合一些社会工程学的门径来包管攻打的告捷率。

另有一些状况,Host大约会被url编码后直接放到email的header外表形成header注入。通过这个,攻打者概略很繁冗的就能劫持用户的账户。

0x02 缓存传染

通过Host header来传染缓存的攻扣门径结尾是Carlos Beuno 在2008年提出来的。但是在此刻的网络架构中,这类攻打还是比较艰难的,由于此刻的缓存装备都也许识别Host。譬喻关于下面的这两种状况他们绝对不会弄殽杂:

Default
12 > GET /index.html HTTP/1.1       > GET /index.html HTTP/1.1> Host: example.com              > Host: evil.com

于是为了能使缓存能将传染后的response返回给用户,我们还必须让缓存处事器看到的host header 和使用看到的host header 不异样。譬喻说关于Varnish(一个颇有名的缓存处事软件),概略使用一个复制的Host header。Varnish是通过劈脸到达的请求的host header来辨别host的,而Apache则是看部门请求的host,Nginx则只是看末端一个请求的host。这就象征着你概略通过下面这个请求 来诱骗Varnish到达传染的目标:

Default
123 > GET / HTTP/1.1> Host: example.com> Host: evil.com

使用自己的缓存也大约受到传染。譬喻Joomla就将失掉的host值不经html编码便写进轻易页面,而它的缓存则对这些不有任何处置惩罚惩罚。譬喻概略通过下面的请求来写入一个存储型的xss:

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

现实上的请求是如许的:

Default
12 > GET / HTTP/1.1> Host: cow"onerror=\'alert(1)\'rel=\'stylesheet\'

响应其实已卖力到传染:

Default
123 <link href="http://cow"onerror='alert(1)'rel='stylesheet'/" rel="canonical"/> 这时只必要浏览首页看能否有弹窗就晓得缓存能否曾经被传染了。

这时只必要浏览首页看能否有弹窗就晓得缓存能否曾经被传染了。

0x03 安全的设置装备摆设

在这里我假设你概略通过任何类型的使用来发动一个http请求,而host header也是概略轻易编辑的。诚然在一个http请求里,host header是用来呈报网站server该请求该当转发给哪个网站,但是事实上,这个header的传染感动大约说侵占并不止云云。

譬喻如果Apache接收到一个带有犯科host header的请求,它会将此请求转发给在 httpd.conf 里定义的第一个虚拟主机。于是,Apache颇有大约将带有轻易host header的请求转发给使用。而Django曾经熟悉到了这个短处,所以它倡始用户此外构建一个默认的虚拟主机,用来蒙受这些带有犯科host header的请求,以包管Django本身的使用不蒙受到这些请求。

不外概略通过X-Forwarded-Host 这个header就概略绕过。Django特别清楚缓存传染的侵占,而且在2011年的9月份就通过默认禁用X-Forwarded-Host这个 header来修复此标题。Mozilla却在addons.mozilla.org网站忽视了此标题,我在2012年的4月创作发清楚此标题:

Default
123 > POST /en-US/firefox/user/pwreset HTTP/1.1> Host: addons.mozilla.org> X-Forwarded-Host: evil.com

即便Django给出了补丁,但是依然具有侵占。Webserver许诺在host header外表指定端口,但是它并不能通过端口来识别请求是对应的哪个虚拟主机。概略通过下面的门径来绕过:

Default
12 > POST /en-US/firefox/user/pwreset HTTP/1.1> Host: addons.mozilla.org:@passwordreset.net

这直接会导致生成一个密码重置链接:
https://addons.mozilla.org:@passwordreset.net/users/pwreset/3f6hp/3ab-9ae3db614fc0d0d036d4

当用户点击这个链接的时分就会创作发明,其实这个key曾经被发送到passwordreset.net这个网站了。在我报告了此标题后,Django 又推出了一个补丁:https://www.djangoproject.com/网站log/2012/oct/17/security/

不幸的是,这个补丁只是复杂的通过黑名单行动来复杂的过滤掉了@和此外一些字符。而由于密码重置链接是以纯文本而不是html的行动发送的,所以此补丁只必要增加一个空格就概略绕过:

Default
12 > POST /en-US/firefox/users/pwreset HTTP/1.1> Host: addons.mozilla.org: www.securepasswordreset.com

Django的后续补丁规定规矩了host header的端口部分只能是含有数字,以躲避此标题。但是在RFC2616文档中规定规矩了,如果请求URI是一个绝对的URI,那末host是Request-URI的一部分。在请求中的任何Host header值必须被忽略。

也就是说,在Apache和Nginx(只如果遵守此文档的网站server)中,概略通过绝对uri向轻易使用发送一个网罗有轻易host header的请求:

Default
12 > POST https://addons.mozilla.org/en-US/firefox/users/pwreset HTTP/1.1> Host: evil.com

这个请求在SERVER_NAME外表的值是addons.mozilla.org,而不是host里的evil.com。使用概略通过使用 SERVER_NAME而不是host header来躲避此侵占,但是如果不有配合特殊设置装备摆设的网站server,这个侵占依然具有。概略在这里 http://stackoverflow.com/questions/2297403/http-host-vs-server-name /2297421#2297421看看 HTTP_HOST 和SERVER_NAME 的分辨。Django官方在2013年的仲春通过逼唆使用一个host白名单来修复了此标题。尽管云云,在良多此外的wen使用上,这类攻打行动依然屡试 不爽。

0x04 处事器方面必要做的

由于http请求的特点,host header的值其实是不可托的。独一可托的只要SERVER_NAME,这个在Apache和Nginx里概略通过设置一个虚拟机来记录部门的犯科host header。在Nginx里还概略通过指定一个SERVER_NAME名单,Apache也概略通过指定一个SERVER_NAME名单并封锁UseCanonicalName选项。倡始两种门径同时使用。

Varnish很快会颁布一个补丁。在官方补丁出来前,概略通过在设置装备摆设文件里染指:

Default
12345 import std;         sub vcl_recv {                std.collect(req.http.host);        }

来防护。

0x05 使用自己必要做的

图谋这个标题其实是很艰难的,由于不有完全踊跃化的门径来帮忙站长识 别哪些host 的值是值得信赖的。诚然做起来有点贫苦,但是最安全的做法是:效仿Django的门径,在网站部署和初始化的时分,乞请办理员供给一个可托任的域名白名 单。如果这个实现起来比较艰难,那至少也要包管使用SERVER_NAME而不是host header,而且鞭笞用户使用安全设置装备摆设做的比较好的网站。

via@ http://www.skeletonscribe.net/2013/05/practical-http-host-header-attacks.html

ps:未找到原作者链接,请作者看见本文后留言联系,我们将第一时间标注版权。

数安新闻+更多

证书相关+更多