乐趣区

关于http:Web-安全-之-HTTP-Host-header-attacks

HTTP Host header attacks

在本节中,咱们将探讨谬误的配置和有缺点的业务逻辑如何通过 HTTP Host 头使网站蒙受各种攻打。咱们将概述辨认易受 HTTP Host 头攻打的网站的高级办法,并演示如何利用此办法。最初,咱们将提供一些无关如何爱护本人网站的个别倡议。

什么是 HTTP Host 头

从 HTTP/1.1 开始,HTTP Host 头是一个必须的申请头,其指定了客户端想要拜访的域名。例如,当用户拜访 https://portswigger.net/web-security 时,浏览器将会收回一个蕴含 Host 头的申请:

GET /web-security HTTP/1.1
Host: portswigger.net

在某些状况下,例如当申请被中介零碎转发时,Host 值可能在达到预期的后端组件之前被更改。咱们将在上面更具体地探讨这种场景。

HTTP Host 头的作用是什么

HTTP Host 头的作用就是标识客户端想要与哪个后端组件通信。如果申请没有 Host 头或者 Host 格局不正确,则把申请路由到预期的应用程序时会呈现问题。

历史上因为每个 IP 地址只会托管单个域名的内容,所以并不存在模糊性。然而现在,因为基于云的解决方案和相干架构的一直增长,使得多个网站和应用程序在同一个 IP 地址拜访变得很常见,这种形式也越来越受欢迎,局部起因是 IPv4 地址耗尽。

当多个应用程序通过同一个 IP 地址拜访时,通常是以下状况之一。

虚拟主机

一种可能的状况是,一台 web 服务器部署多个网站或应用程序,这可能是同一个所有者领有多个网站,也有可能是不同网站的所有者部署在同一个共享平台上。这在以前不太常见,但在一些基于云的 SaaS 解决方案中依然会呈现。

在这种状况下,只管每个不同的网站都有不同的域名,然而他们都与服务器共享同一个 IP 地址。这种单台服务器托管多个网站的形式称为“虚拟主机”。

对于拜访网站的普通用户来说,通常无奈辨别网站应用的是虚拟主机还是本人的专用服务器。

通过中介路由流量

另一种常见的状况是,网站托管在不同的后端服务器上,然而客户端和服务器之间的所有流量都会通过两头零碎路由。两头零碎可能是一个简略的负载均衡器或某种反向代理服务器。当客户端通过 CDN 拜访网站时,这种状况尤其广泛。

在这种状况下,即便不同的网站托管在不同的后端服务器上,然而他们的所有域名都须要解析为两头零碎这个 IP 地址。这也带来了一些与虚拟主机雷同的挑战,即反向代理或负载平衡服务器须要晓得怎么把每个申请路由到哪个适合的后端。

HTTP Host 头如何解决这个问题

解决上述的状况,都须要依赖于 Host 头来指定申请预期的接管方。一个常见的比喻是给住在公寓楼里的某个人写信的过程。整栋楼都是同一个街道地址,然而这个街道地址前面有许多个不同的公寓房间,每个公寓房间都须要以某种形式承受正确的邮件。解决这个问题的一个办法就是简略地在地址中增加公寓房间号码或收件人的姓名。对于 HTTP 音讯而言,Host 头的作用与之相似。

当浏览器发送申请时,指标 URL 将解析为特定服务器的 IP 地址,当服务器收到申请时,它应用 Host 头来确定预期的后端并相应地转发该申请。

什么是 HTTP Host 头攻打

HTTP Host 头攻打会利用以不平安的形式解决 Host 头的破绽网站。如果服务器隐式信赖 Host 标头,且未能正确验证或本义它,则攻击者可能会应用此输出来注入无害的无效负载,以操纵服务器端的行为。将无害负载间接注入到 Host 头的攻打通常称为 “Host header injection”(主机头注入攻打)。

现成的 web 利用通常不晓得它们部署在哪个域上,除非在装置过程中手动配置指定了它。此时当他们须要晓得以后域时,例如要生成电子邮件中蕴含的 URL,他们可能会从 Host 头检索域名:

<a href="https://_SERVER['HOST']/support">Contact support</a>

标头的值也能够用于基础设施内不同零碎之间的各种交互。

因为 Host 头实际上用户能够管制的,因而可能会导致很多问题。如果输出没有正确的本义或验证,则 Host 头可能会成为利用其余破绽的潜在载体,最值得注意的是:

  • Web 缓存中毒
  • 特定性能中的业务逻辑缺点
  • 基于路由的 SSRF
  • 典型的服务器破绽,如 SQL 注入

HTTP Host 破绽是如何产生的

HTTP Host 破绽的产生通常是基于存在缺点的假如,即误认为 Host 头是用户不可管制的。这导致 Host 头被隐式信赖了,其值未进行正确的验证或本义,而攻击者能够应用工具轻松地批改 Host。

即便 Host 头自身失去了平安的解决,也能够通过注入其余标头来笼罩 Host,这取决于解决传入申请的服务器的配置。有时网站所有者不晓得默认状况下这些能够笼罩 Host 的标头是受反对的,因而,可能不会进行严格的审查。

实际上,许多破绽并不是因为编码不平安,而是因为相干基础架构中的一个或多个组件的配置不平安。之所以会呈现这些配置问题,是因为网站将第三方技术集成到其体系架构中,而未齐全理解配置选项及其平安含意。

利用 HTTP Host 头破绽

具体内容请查阅本章下文。

如何进攻 HTTP Host 头攻打

进攻 HTTP Host 头攻打最简略的办法就是防止在服务端代码中应用 Host 头。仔细检查下每个 URL 地址是否真的相对须要,你常常会发现你能够用一个绝对的 URL 地址代替。这个简略的扭转能够帮忙你进攻 web 缓存中毒。

其余进攻措施有:

爱护相对的 URL 地址

如果你必须应用相对的 URL 地址,则应该在配置文件中手动指定以后域名并援用此值,而不是 Host 头的值。这种办法将打消明码重置中毒的威逼。

验证 Host 头

如果必须应用 Host 头,请确保正确验证它。这包含对照容许域的白名单进行查看,回绝或重定向无奈辨认的 Host 的任何申请。你应该查阅所应用的框架的相干文档。例如 Django 框架在配置文件中提供了 ALLOWED_HOSTS 选项,这将缩小你蒙受主机标头注入攻打的危险。

不反对可能重写 Host 的头

查看你是否不反对可能用于结构攻打的其余标头,尤其是 X-Forwarded-Host,牢记默认状况下这些头可能是被容许的。

应用外部虚拟主机时要小心

应用虚拟主机时,应防止将外部网站和应用程序托管到面向公开内容的服务器上。否则,攻击者可能会通过 Host 头来拜访外部域。


如何辨认和利用 HTTP Host 头破绽

在本节中,咱们将更认真地理解如何辨认网站是否存在 HTTP Host 头破绽。而后,咱们将提供一些示例,阐明如何利用此破绽。

如何应用 HTTP Host 头测试破绽

要测试网站是否易受 HTTP Host 攻打,你须要一个拦挡代理(如 Burp proxy)和手动测试工具(如 Burp Repeater 和 Burp intruiter)。

简而言之,你须要可能批改 Host 标头,并且你的申请可能达到指标应用程序。如果是这样,则能够应用此标头来探测应用程序,并察看其对响应的影响。

提供一个任意的 Host 头

在探测 Host 头注入破绽时,第一步测试是给 Host 头设置任意的、无奈辨认的域名,而后看看会产生什么。

一些拦挡代理间接从 Host 头连贯指标 IP 地址,这使得这种测试简直不可能;对报头所做的任何更改都会导致申请发送到齐全不同的 IP 地址。然而,Burp Suite 准确地放弃了主机头和指标 IP 地址之间的拆散,这种拆散容许你提供所需的任意或格局谬误的主机头,同时依然确保将申请发送到预期指标。

有时,即便你提供了一个意外的 Host 头,你依然能够拜访指标网站。这可能有很多起因。例如,服务器有时设置了默认或回退选项,以解决无奈辨认的域名申请。如果你的指标网站碰巧是默认的,那你就背运了。在这种状况下,你能够开始钻研应用程序对 Host 头做了什么,以及这种行为是否可利用。

另一方面,因为 Host 头是网站工作的根本局部,篡改它通常意味着你将无法访问指标应用程序。接管到你的申请的反向代理或负载平衡器可能基本不晓得将其转发到何处,从而响应 “Invalid Host header” 这种谬误。如果你的指标很可能是通过 CDN 拜访的。在这种状况下,你应该持续尝试上面概述的一些技术。

查看是否存在验证缺点

你可能会发现你的申请因为某种安全措施而被阻止,而不是收到一个 “Invalid Host header” 响应。例如,一些网站将验证 Host 头是否与 TLS 握手的 SNI 匹配。这并不意味着它们对 Host 头攻打免疫。

你应该试着了解网站是如何解析 Host 头的。这有时会暴露出一些能够用来绕过验证的破绽。例如,一些解析算法可能会疏忽主机头中的端口,这意味着只有域名被验证。只有你提供一个非数字端口,放弃域名不变,就能够确保你的申请达到指标应用程序,同时能够通过端口注入无害负载。

GET /example HTTP/1.1
Host: vulnerable-website.com:bad-stuff-here

某些网站的验证逻辑可能是容许任意子域。在这种状况下,你能够通过注册任意子域名来齐全绕过验证,该域名以白名单中域名的雷同字符串结尾:

GET /example HTTP/1.1
Host: notvulnerable-website.com

或者,你能够利用曾经泄露的不平安的子域:

GET /example HTTP/1.1
Host: hacked-subdomain.vulnerable-website.com

无关常见域名验证缺点的进一步示例,请查看咱们无关躲避常见的 SSRF 进攻和 Origin 标头解析谬误的内容。

发送不明确的申请

验证 Host 的代码和易受攻击的代码通常在应用程序的不同组件中,甚至位于不同的服务器上。通过辨认和利用它们解决 Host 头的形式上的差别,你能够收回一个不置可否的申请。

以下是几个示例,阐明如何创立不置可否的申请。

注入反复的 Host 头

一种可能的办法是尝试增加反复的 Host 头。诚然,这通常只会导致你的申请被阻止。然而,因为浏览器不太可能发送这样的申请,你可能会偶然发现开发人员没有预料到这种状况。在这种状况下,你可能会发现一些乏味的行为怪癖。

不同的零碎和技术将以不同的形式解决这种状况,但具体应用哪个 Host 头可能会存在差别,你能够利用这些差别。思考以下申请:

GET /example HTTP/1.1
Host: vulnerable-website.com
Host: bad-stuff-here

假如转发服务优先应用第一个标头,然而后端服务器优先应用最初一个标头。在这种状况下,你能够应用第一个报头来确保你的申请被路由到预期的指标,并应用第二个报头将你的无效负载传递到服务端代码中。

提供一个相对的 URL 地址

尽管申请行通常是指定申请域上的相对路径,但许多服务器也被配置为了解相对 URL 地址的申请。

同时提供相对 URL 和 Host 头所引起的歧义也可能导致不同零碎之间的差别。标准而言,在路由申请时,应优先思考申请行,但实际上并非总是如此。你能够像反复 Host 头一样利用这些差别。

GET https://vulnerable-website.com/ HTTP/1.1
Host: bad-stuff-here

请留神,你可能还须要尝试不同的协定。对于申请行是蕴含 HTTP 还是 HTTPS URL,服务器的行为有时会有所不同。

增加 line wrapping

你还能够给 HTTP 头增加空格缩进,从而发现奇怪的行为。有些服务器会将缩进的标头解释为换行,因而将其视为前一个标头值的一部分。而其余服务器将齐全疏忽缩进的标头。

因为对该场景的解决极不统一,解决你的申请的不同零碎之间通常会存在差别。思考以下申请:

GET /example HTTP/1.1
 Host: bad-stuff-here
Host: vulnerable-website.com

网站可能会阻止具备多个 Host 标头的申请,然而你能够通过缩进其中一个来绕过此验证。如果转发服务疏忽缩进的标头,则申请会被当做拜访 vulnerable-website.com 的一般申请。当初让咱们假如后端疏忽前导空格,并在呈现反复的状况下优先解决第一个标头,这时你就能够通过 “wrapped” Host 头传递任意值。

其余技术

这只是公布无害且不置可否的申请的许多可能办法中的一小部分。例如,你还能够采纳 HTTP 申请走私技术来结构 Host 头攻打。申请走私的具体内容请查看该主题文章。

注入笼罩 Host 的标头

即便不能应用不明确的申请重写 Host 头,也有其余在放弃其残缺的同时重写其值的可能。这包含通过其余的 HTTP Host 标头注入无效负载,这些标头的设计就是为了达到这个目标。

正如咱们曾经探讨过的,网站通常是通过某种中介零碎拜访的,比方负载均衡器或反向代理。在这种架构中,后端服务器接管到的 Host 头可能是这些两头零碎的域名。这通常与申请的性能无关。

为了解决这个问题,前端服务器(转发服务)能够注入 X-Forwarded-Host 头来表明客户端初始申请的 Host 的原始值。因而,当 X-Forwarded-Host 存在时,许多框架会援用它。即便没有前端应用此标头,也能够察看到这种行为。

你有时能够用 X-Forwarded-Host 绕过 Host 头的任何验证的并注入歹意输出。

GET /example HTTP/1.1
Host: vulnerable-website.com
X-Forwarded-Host: bad-stuff-here

只管 X-Forwarded-Host 是此行为的理论规范,你可能也会遇到其余具备相似用处的标头,包含:

  • X-Host
  • X-Forwarded-Server
  • X-HTTP-Host-Override
  • Forwarded

从平安角度来看,须要留神的是,有些网站,甚至可能是你本人的网站,无心中反对这种行为。这通常是因为在它们应用的某些第三方技术中,这些报头中的一个或多个是默认启用的。

如何利用 HTTP Host 头

一旦确定能够向指标应用程序传递任意主机名,就能够开始寻找利用它的办法。

在本节中,咱们将提供一些你能够结构的常见 HTTP Host 头攻打的示例。

  • 明码重置中毒
  • Web 缓存中毒
  • 利用典型的服务器端破绽
  • 绕过身份验证
  • 虚拟主机暴力破解
  • 基于路由的 SSRF

明码重置中毒

攻击者有时能够应用 Host 头进行明码重置中毒攻打。更多内容参见本系列相干局部。

通过 Host 头的 Web 缓存中毒

在探测潜在的 Host 头攻打时,你常常会遇到看似易受攻击但并不能间接利用的状况。例如,你可能会发现 Host 头在没有 HTML 编码的状况下反映在响应标记中,甚至间接用于脚本导入。反射的客户端破绽(例如 XSS)由 Host 标头引起时通常无奈利用。攻击者没法强制受害者的浏览器申请不正确的主机。

然而,如果指标应用了 web 缓存,则能够通过缓存向其余用户提供中毒响应,将这个无用的、反射的破绽转变为危险的存储破绽。

要构建 web 缓存中毒攻打,须要从服务器获取反映已注入负载的响应。不仅如此,你还须要找到其余用户申请也同时应用的缓存键。如果胜利,下一步是缓存此歹意响应。而后,它将被提供给任何试图拜访受影响页面的用户。

独立缓存通常在缓存键中蕴含 Host 头,因而这种办法通常在集成的应用程序级缓存上最无效。也就是说,后面探讨的技术有时甚至能够毒害独立的 web 缓存零碎。

Web 缓存中毒有一个独立的专题讨论。

利用典型的服务端破绽

每个 HTTP 头都是利用典型服务端破绽的潜在载体,Host 头也不例外。例如,你能够通过 Host 头探测试试平时的 SQL 注入。如果 Host 的值被传递到 SQL 语句中,这可能是可利用的。

拜访受限性能

某些网站只容许外部用户拜访某些性能。然而,这些网站的访问控制可能会做出谬误的假如,容许你通过对 Host 头进行简略的批改来绕过这些限度。这会成为其余攻打的切入点。

暴力破解应用虚拟主机的外部网站

公司有时会犯这样的谬误:在同一台服务器上托管可公开拜访的网站和公有的外部网站。服务器通常有一个公共的和一个公有的 IP 地址。因为外部主机名可能会解析为公有的 IP 地址,因而仅通过查看 DNS 记录无奈检测到这种状况:

www.example.com:12.34.56.78
intranet.example.com:10.0.0.132

在某些状况下,外部站点甚至可能没有与之关联的公开 DNS 记录。尽管如此,攻击者通常能够拜访他们有权拜访的任何服务器上的任何虚拟主机,前提是他们可能猜出主机名。如果他们通过其余形式发现了暗藏的域名,比方信息透露,他们就能够间接发动申请。否则,他们只能应用诸如 Burp intruiter 这样的工具,通过候选子域的简略单词表对虚拟主机进行暴力破解。

基于路由的 SSRF

有时还可能应用 Host 头发起高影响、基于路由的 SSRF 攻打。这有时被称为 “Host header SSRF attacks”。

经典的 SSRF 破绽通常基于 XXE 或可利用的业务逻辑,该逻辑将 HTTP 申请发送到从用户可管制的输出派生的 URL。另一方面,基于路由的 SSRF 依赖于利用在许多基于云的架构中风行的两头组件。这包含外部负载均衡器和反向代理。

只管这些组件部署的目标不同,但基本上,它们都会接管申请并将其转发到适当的后端。如果它们被不平安地配置,转发未验证 Host 头的申请,它们就可能被操纵以将申请谬误地路由到攻击者抉择的任意零碎。

这些零碎是很好的指标,它们处于一个特权网络地位,这使它们能够间接从公共网络接管申请,同时还能够拜访许多、但不是全副的外部网络。这使得 Host 头成为 SSRF 攻打的弱小载体,有可能将一个简略的负载均衡器转换为通向整个外部网络的网关。

你能够应用 Burp Collaborator 来帮忙辨认这些破绽。如果你在 Host 头中提供 Collaborator 服务器的域,并且随后从指标服务器或其余门路内的零碎收到了 DNS 查问,则表明你能够将申请路由到任意域。

在确认能够胜利地操纵中介零碎以将申请路由到任意公共服务器之后,下一步是查看是否利用此行为拜访外部零碎。为此,你须要标识在指标外部网络上应用的公有 IP 地址。除了应用程序透露的 IP 地址外,你还能够扫描属于该公司的主机名,以查看是否有解析为公有 IP 地址的状况。如果其余办法都失败了,你依然能够通过简略地强制应用规范公有 IP 范畴(例如 192.168.0.0/16)来辨认无效的 IP 地址。

通过格局谬误的申请行进行 SSRF

自定义代理有时无奈正确地验证申请行,这可能会使你提供异样的、格局谬误的输出,从而带来可怜的后果。

例如,反向代理可能从申请行获取门路,而后加上了前缀 http://backend-server,并将申请路由到上游 URL。如果门路以 / 结尾,这没有问题,但如果以 @ 结尾呢?

GET @private-intranet/example HTTP/1.1

此时,上游的 URL 将是 http://backend-server@private-intranet/example,大多数 HTTP 库将认为拜访的是 private-intranet 且用户名是 backend-server


Password reset poisoning

明码重置中毒是一种技术,攻击者能够利用该技术来操纵易受攻击的网站,以生成指向其管制下的域的明码重置链接。这种行为能够用来窃取重置任意用户明码所需的机密令牌,并最终危害他们的帐户。

明码重置是如何工作的

简直所有须要登录的网站都实现了容许用户在遗记明码时重置明码的性能。实现这个性能有好几种办法,其中一个最常见的办法是:

  1. 用户输出用户名或电子邮件地址,而后提交明码重置申请。
  2. 网站查看该用户是否存在,而后生成一个长期的、惟一的、高熵的 token 令牌,并在后端将该令牌与用户的帐户相关联。
  3. 网站向用户发送一封蕴含重置明码链接的电子邮件。用户的 token 令牌作为 query 参数蕴含在相应的 URL 中,如 https://normal-website.com/reset?token=0a1b2c3d4e5f6g7h8i9j
  4. 当用户拜访此 URL 时,网站会查看所提供的 token 令牌是否无效,并应用它来确定要重置的帐户。如果一切正常,用户就能够设置新密码了。最初,token 令牌被销毁。

与其余一些办法相比,这个过程足够简略并且绝对平安。然而,它的安全性依赖于这样一个前提:只有指标用户能力拜访他们的电子邮件收件箱,从而应用他们的 token 令牌。而明码重置中毒就是一种窃取此 token 令牌以更改其余用户明码的办法。

如何结构一个明码重置中毒攻打

如果发送给用户的 URL 是基于可管制的输出(例如 Host 头)动静生成的,则能够结构如下所示的明码重置中毒攻打:

  1. 攻击者依据须要获取受害者的电子邮件地址或用户名,并代表受害者提交明码重置申请,然而这个申请被批改了 Host 头,以指向他们管制的域。咱们假如应用的是 evil-user.net
  2. 受害者收到了网站发送的实在的明码重置电子邮件,其中蕴含一个重置明码的链接,以及与他们的帐户相关联的 token 令牌。然而,URL 中的域名指向了攻击者的服务器:https://evil-user.net/reset?token=0a1b2c3d4e5f6g7h8i9j
  3. 如果受害者点击了此链接,则明码重置的 token 令牌将被传递到攻击者的服务器。
  4. 攻击者当初能够拜访网站的实在 URL,并应用盗取的受害者的 token 令牌,将用户的明码重置为本人的明码,而后就能够登录到用户的帐户了。

在真正的攻打中,攻击者可能会伪造一个假的正告告诉来进步受害者点击链接的概率。

即便不能管制明码重置的链接,有时也能够应用 Host 头将 HTML 注入到敏感的电子邮件中。请留神,电子邮件客户端通常不执行 JavaScript,但其余 HTML 注入技术如悬挂标记攻打可能依然实用。

退出移动版