【Academy】HTTP Host 标头攻击 ------ HTTP Host header attacks

发布于:2025-03-10 ⋅ 阅读:(13) ⋅ 点赞:(0)


1. 什么是 HTTP Host 标头?

HTTP Host 标头是自 HTTP/1.1 起的必需请求标头。它指定客户端要访问的域名。例如,当用户访问 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 标头来确定预期的后端并相应地转发请求。


2. 什么是 HTTP Host 标头攻击?

HTTP Host 标头攻击利用易受攻击的网站,这些网站以不安全的方式处理 Host 标头的值。如果服务器隐式信任 Host 标头,并且无法正确验证或转义它,则攻击者可能能够使用此输入注入操纵服务器端行为的有害负载。涉及将有效负载直接注入 Host 标头的攻击通常称为“Host 标头注入”攻击。

现成的 Web 应用程序通常不知道它们部署在哪个域上,除非在设置过程中在配置文件中手动指定。当他们需要知道当前域时,例如,要生成电子邮件中包含的绝对 URL,他们可能会求助于 Host 标头中检索域:

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

header 值还可用于网站基础设施的不同系统之间的各种交互。

由于 Host 标头实际上是用户可控制的,因此这种做法可能会导致许多问题。如果输入没有正确转义或验证,则 Host 标头是利用一系列其他漏洞的潜在载体,最明显的是:

  • Web 缓存中毒
  • 特定功能中的业务逻辑缺陷
  • 基于路由的 SSRF
  • 典型的服务器端漏洞,例如 SQL 注入

3. HTTP Host 标头漏洞是如何产生的?

HTTP Host 标头漏洞通常是由于错误地假设标头不是用户可控制的而引起的。这会在 Host 标头中创建隐式信任,并导致其值验证不充分或转义,即使攻击者可以使用 Burp Proxy 等工具轻松修改它。

即使 Host 标头本身得到了更安全的处理,根据处理传入请求的服务器的配置,也可能通过注入其他标头来覆盖 Host。有时,网站所有者不知道这些标头默认受支持,因此,它们可能不会受到相同级别的审查。

事实上,其中许多漏洞的出现不是因为编码不安全,而是因为相关基础设施中一个或多个组件的配置不安全。出现这些配置问题的原因是 Web 站点将第三方技术集成到其架构中,而不一定了解配置选项及其安全影响。


4. 如何测试 HTTP Host 标头漏洞

要测试网站是否容易受到 HTTP Host 标头的攻击,您需要一个拦截代理,例如 Burp Proxy,以及 Burp Repeater 和 Burp Intruder 等手动测试工具。

简而言之,您需要确定是否能够修改 Host 标头,并且仍然能够使用您的请求到达目标应用程序。如果是这样,您可以使用此标头来探测应用程序并观察这对响应的影响


4.1 提供任意 Host 标头

在探测 Host 标头注入漏洞时,第一步是测试当您通过 Host 标头提供任意的、无法识别的域名时会发生什么情况。

一些拦截代理直接从 Host 标头派生目标 IP 地址,这使得这种测试几乎是不可能的;您对标头所做的任何更改都只会导致请求被发送到完全不同的 IP 地址。但是,Burp Suite 会准确地保持 Host 标头和目标 IP 地址之间的分离。这种分离允许您提供所需的任何任意或格式错误的 Host 标头,同时仍确保将请求发送到预期目标。

Tip
目标 URL 显示在面板顶部(对于 Burp Repeater 和Proxy interception)或 Burp Intruder 的“Target”(目标)选项卡上。您可以通过点击铅笔图标手动编辑目标。

有时,即使您提供了意外的 Host 标头,您仍然能够访问目标网站。这可能有多种原因。例如,服务器有时会配置默认或回退选项,以防它们收到不认识的域名请求。如果您的目标网站恰好是默认网站,那么您很幸运。在这种情况下,您可以开始研究应用程序对 Host 标头执行的作以及此行为是否可被利用。

另一方面,由于 Host 标头是网站运行方式的基本组成部分,因此篡改它通常意味着您根本无法访问目标应用程序。收到您的请求的前端服务器或负载均衡器可能根本不知道将其转发到何处,从而导致某种类型的“Invalid Host header”错误。如果您的目标通过 CDN 访问,则尤其可能出现这种情况。在这种情况下,您应该继续尝试下面概述的一些技术。


4.2 检查有缺陷的验证

您可能会发现您的请求由于某种安全措施而被阻止,而不是收到 “Invalid Host header” 响应。例如,某些网站将验证 Host 标头是否与 TLS 握手的 SNI 匹配。这并不一定意味着它们不受 Host 标头攻击。

您应该尝试了解 Web 站点如何解析 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 标头解析错误的内容。


4.3 发送不明确的请求

验证主机的代码和对主机执行易受攻击的操作的代码通常驻留在不同的应用程序组件中,甚至位于不同的服务器上。通过识别和利用它们检索 Host 标头的方式中的差异,您可以发出一个不明确的请求,该请求似乎具有不同的主机,具体取决于正在查看它的系统。

以下是如何创建不明确请求的几个示例。

注入重复的 Host 标头
一种可能的方法是尝试添加重复的 Host 标头。诚然,这通常只会导致您的请求被阻止。但是,由于浏览器不太可能发送此类请求,因此您偶尔可能会发现开发人员没有预料到这种情况。在这种情况下,您可能会暴露一些有趣的行为怪癖。

不同的系统和技术会以不同的方式处理这种情况,但通常会优先考虑两个 Headers 中的一个,从而有效地覆盖其值。当系统对哪个标头是正确的标头存在分歧时,这可能会导致您可以利用的差异。请考虑以下请求:

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

假设前端优先使用 Headers 的第一个Host实例,但后端优先使用后一个Host实例。在这种情况下,您可以使用第一个标头来确保将请求路由到预期目标,并使用第二个标头将有效负载传递到服务器端代码中。

提供绝对 URL
尽管请求行通常指定所请求域上的相对路径,但许多服务器也被配置为理解对绝对 URL 的请求。

同时提供绝对 URL 和 Host 标头所导致的歧义也可能导致不同系统之间的差异。正式地说,在路由请求时应优先考虑请求行,但在实践中,情况并非总是如此。您可以利用这些差异的方式与利用重复的 Host 标头大致相同。

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

请注意,您可能还需要尝试不同的协议。服务器的行为有时会有所不同,具体取决于请求行是包含 HTTP 还是 HTTPS URL。

添加换行
您还可以通过使用空格字符缩进 HTTP 标头来发现古怪的行为。一些服务器会将缩进的 Headers 解释为换行,因此将其视为前一个 Headers 值的一部分。其他服务器将完全忽略缩进的 Headers。

由于此案例的处理高度不一致,因此处理您的请求的不同系统之间经常会出现差异。例如,请考虑以下请求:

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

该网站可能会阻止具有多个 Host 标头的请求,但您可以通过像这样缩进其中一个标头来绕过此验证。如果前端忽略了缩进的 header,则该请求将作为vulnerable-website.com 请求处理。现在,假设后端忽略了前导空格,并在重复的情况下优先于第一个 Headers。这种差异可能允许您通过 “wrapped” Host 标头传递任意值。

其他技术
这只是发出有害、模棱两可的请求的众多可能方法中的一小部分。例如,您还可以采用许多 HTTP 请求走私技术来构建 Host 标头攻击。请查阅专门的HTTP请求走私的相关内容。


4.4 注入主机覆盖标头

即使您无法使用不明确的请求覆盖 Host 标头,也有其他可能性可以覆盖其值,同时保持其完整。这包括通过其他几个 HTTP 标头之一注入您的有效负载,这些标头旨在实现此目的,尽管是用于更无害的用例。

正如我们已经讨论过的,网站通常是通过某种中介系统访问的,例如负载均衡器或反向代理。在这种体系结构中,后端服务器接收的 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

Tip
在 Burp Suite 中,你可以使用 Param Miner 参数挖掘器扩展的“猜测标头”功能,通过其广泛的内置单词列表自动探测受支持的标头。

从安全角度来看,请务必注意,某些网站(甚至可能是您自己的网站)无意中支持此类行为。这通常是因为在它们使用的某些第三方技术中默认启用了这些标头中的一个或多个。


5. 如何利用 HTTP Host 标头漏洞

一旦您确定可以将任意主机名传递给目标应用程序,您就可以开始寻找利用它的方法。


5.1 密码重置中毒

密码重置中毒是一种技术,攻击者通过这种技术操纵易受攻击的网站生成指向其控制下的域的密码重置链接。可以利用此行为来窃取重置任意用户密码所需的秘密令牌,并最终破坏他们的帐户。

密码重置如何工作?
几乎所有需要登录的网站都实现了允许用户在忘记密码时重置密码的功能。有几种方法可以做到这一点,具有不同程度的安全性和实用性。最常见的方法之一是这样的:

  1. 用户输入其用户名或电子邮件地址并提交密码重置请求。
  2. 该网站检查此用户是否存在,然后生成一个临时的、唯一的、高熵的令牌,该令牌与后端的用户帐户相关联。
  3. 该网站会向用户发送一封电子邮件,其中包含用于重置其密码的链接。用户的唯一重置令牌作为查询参数包含在相应的 URL 中:
https://normal-website.com/reset?token=0a1b2c3d4e5f6g7h8i9j
  1. 当用户访问此 URL 时,网站会检查提供的令牌是否有效,并使用它来确定正在重置的帐户。如果一切正常,则用户可以选择输入新密码。最后,令牌被销毁。

与其他一些方法相比,此过程足够简单且相对安全。但是,它的安全性依赖于以下原则:只有目标用户才能访问其电子邮件收件箱,因此才能访问其唯一令牌。密码重置中毒是一种窃取此令牌以更改其他用户密码的方法。


如何构建密码重置中毒攻击
如果发送给用户的 URL 是基于可控输入(如 Host 头)动态生成的,则有可能构建如下重置密码中毒攻击:

  1. 攻击者根据需要获取受害者的电子邮件地址或用户名,并代表他们提交密码重置请求。在提交表单时,他们拦截生成的 HTTP 请求并修改 Host 标头,使其指向他们控制的域。在此示例中,我们将使用 evil-user.net
  2. 受害者直接从该网站收到一封真正的密码重置电子邮件。这似乎包含一个用于重置其密码的普通链接,并且至关重要的是,它包含与其帐户关联的有效密码重置令牌。但是,URL 中的域名指向攻击者的服务器:
https://evil-user.net/reset?token=0a1b2c3d4e5f6g7h8i9j
  1. 如果受害者点击此链接(或以其他方式获取,例如,通过防病毒扫描程序获取),密码重置令牌将被传送到攻击者的服务器。
  2. 攻击者现在可以访问易受攻击网站的真实 URL,并通过相应的参数提供受害者被盗的令牌。然后,他们将能够将用户的密码重置为他们喜欢的任何密码,然后登录他们的帐户。

例如,在真正的攻击中,攻击者可能会通过首先使用虚假的泄露通知来预热受害者,从而增加受害者点击链接的可能性。

即使您无法控制密码重置链接,您有时也可以使用 Host 标头将 HTML 注入敏感电子邮件。请注意,电子邮件客户端通常不执行 JavaScript,但其他 HTML 注入技术(如悬挂标记攻击)可能仍然适用


5.2 Web 缓存中毒

在探测潜在的 Host 标头攻击时,您经常会遇到看似易受攻击但无法直接利用的行为。例如,您可能会发现 Host 标头反映在响应标记中,没有 HTML 编码,甚至直接在脚本导入中使用。反射的客户端漏洞(如 XSS)通常由 Host 标头引起时不可利用。攻击者无法强制受害者的浏览器以有用的方式发出错误的Host。

但是,如果目标使用 Web 缓存,则有可能通过说服缓存向其他用户提供中毒响应,将这个无用的反射漏洞变成危险的存储漏洞

要构建网页缓存中毒攻击,你需要从服务器引出一个反映注入有效载荷的响应。挑战在于在保留一个仍将映射到其他用户请求的缓存键的同时做到这一点。如果成功,下一步是让这个恶意响应被缓存。然后,它将被提供给任何试图访问受影响页面的用户。

独立缓存通常在缓存键中包含 Host 标头,因此此方法通常最适合集成的应用程序级缓存。也就是说,前面讨论的技术有时甚至可以使您毒害独立的 Web 缓存。


5.3 利用经典的服务器端漏洞

每个 HTTP 标头都是利用经典服务器端漏洞的潜在载体,Host 标头也不例外。例如,您应该尝试通过 Host 标头进行常用的 SQL 注入探测技术。如果将标头的值传递到 SQL 语句中,则可能会利用此漏洞。


5.4 Host标头身份验证绕过

访问受限功能
出于相当明显的原因,网站通常将某些功能的访问权限限制为仅内部用户。但是,某些网站的访问控制功能做出了有缺陷的假设,允许您通过对 Host 标头进行简单的修改来绕过这些限制。这可能会为其他漏洞暴露更大的攻击面。


5.5 使用虚拟主机暴力破解访问内部网站

公司有时会犯错误,将可公开访问的网站和私有的内部站点托管在同一台服务器上。服务器通常同时具有公共 IP 地址和私有 IP 地址。由于内部主机名可能解析为私有 IP 地址,因此仅通过查看 DNS 记录并不总是能检测到这种情况:

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

在某些情况下,内部站点甚至可能没有与之关联的公有 DNS 记录。尽管如此,攻击者通常可以访问他们有权访问的任何服务器上的任何虚拟主机,前提是他们能够猜到主机名。如果他们通过其他信息泄露等其他方式发现了隐藏的域名,他们可以直接提出请求。否则,他们可以使用 Burp Intruder 等工具,使用候选子域的简单单词列表来暴力破解虚拟主机。


5.6 基于路由的 SSRF

有时还可以使用 Host 标头来发起影响较大的基于路由的 SSRF 攻击。这些有时被称为“Host标头 SSRF 攻击”。

经典的服务器端请求伪造(SSRF)漏洞通常基于可扩展标记语言外部实体**(XXE)或可利用的业务逻辑**,这些逻辑会向源自用户可控制输入的 URL 发送 HTTP 请求。另一方面,基于路由的 SSRF 依赖于利用在许多基于云的架构中普遍存在的中间组件。这包括内部负载均衡器和反向代理。

虽然这些组件被部署用于不同的目的,但从根本上说,它们接收请求并将其转发到适当的后端。如果它们被不安全地配置为基于未经验证的 Host 标头转发请求,那么它们可能会被操纵,将请求错误路由到攻击者选择的任意系统。

这些系统是极好的攻击目标。它们处于特权网络位置,允许直接从公共网络接收请求,同时也能访问大部分(如果不是全部)内部网络。这使得主机头成为服务端请求伪造(SSRF)攻击的有力载体,有可能将一个简单的负载均衡器转变为通往整个内部网络的网关

您可以使用 Burp Collaborator 来帮助识别这些漏洞。如果您在 Host 标头中提供协作者的域,并随后收到来自目标服务器或其他路径内系统的 DNS 查询,则表明您可以将请求路由到任意域。

在确认您可以成功纵中间系统以将您的请求路由到任意公共服务器之后,下一步是查看是否可以利用此行为来访问仅限内部的系统。为此,您需要确定目标内部网络上正在使用的私有 IP 地址。除了应用程序泄露的任何 IP 地址外,您还可以扫描属于该公司的主机名,以查看是否有任何主机名解析为私有 IP 地址。如果所有其他方法都失败了,您仍然可以通过简单地暴力破解标准私有 IP 范围(如 192.168.0.0/16)来识别有效的 IP 地址。

CIDR 表示法
IP 地址范围通常使用 CIDR 表示法表示,例如 192.168.0.0/16

IPv4 地址由四个 8 位十进制值(称为“八位字节”)组成,每个值由一个点分隔。每个八位字节的值范围为 0 到 255,这意味着可能的最低 IPv4 地址为 0.0.0.0最高为 255.255.255.255

在 CIDR 表示法中,该范围内的最低 IP 地址被显式写入,后跟另一个数字,该数字表示从给定地址的开头开始有多少位在整个范围内是固定的。例如,10.0.0.0/8 表示前 8 位是固定的(第一个八位字节)。换句话说,此范围包括从 10.0.0.0 到 10.255.255.255 的所有 IP 地址。


5.7 连接状态攻击

出于性能原因,许多 Web 站点会使用同一客户端在多个请求/响应周期中重复使用连接。实现不佳的 HTTP 服务器有时基于一个危险的假设工作,即某些属性(例如 Host 标头)对于通过同一连接发送的所有 HTTP/1.1 请求都是相同的。对于浏览器发送的请求来说,这可能是正确的,但对于从 Burp Repeater 发送的一系列请求来说,情况不一定如此。这可能会导致许多潜在问题。

例如,您可能偶尔会遇到仅对通过新连接收到的第一个请求执行彻底验证的服务器。在这种情况下,您可以通过发送一个看似无辜的初始请求,然后通过同一连接跟进您的恶意请求来绕过此验证。

许多反向代理使用 Host 标头将请求路由到正确的后端。如果它们假设连接上的所有请求都针对与初始请求相同的主机,则可以为许多 Host 标头攻击提供有用的向量,包括基于路由的 SSRF、密码重置中毒和缓存中毒。


5.8 基于格式错误的请求行的 SSRF

自定义代理有时无法正确验证请求行,这可能会让您提供不寻常的、格式错误的输入,从而产生不幸的结果。

例如,反向代理可能会从请求行获取路径,为其添加http://backend-server,然后将请求路由到该上游 URL。如果路径以 / 字符开头,这很好用,但如果以 @ 字符开头呢?

GET @private-intranet/example HTTP/1.1

生成的上游 URL 将是http://backend-server@private-intranet/example,大多数 HTTP 库将其解释为使用用户名backend-server访问private-intranet的请求。


6. 防止 HTTP Host 标头攻击的方法

保护绝对 URL
当您必须使用绝对 URL 时,您应该要求在配置文件中手动指定当前域,并引用此值而不是 Host 标头。例如,这种方法将消除密码重置中毒的威胁。

验证 Host 标头
如果必须使用 Host 标头,请确保正确验证它。这应该包括根据允许的域白名单进行检查,并拒绝或重定向对无法识别的主机的任何请求。您应该查阅框架的文档,以获取有关如何执行此操作的指导。例如,Django 框架在配置文件中提供了 ALLOWED_HOSTS 选项。此方法将减少您遭受 Host 标头注入攻击的风险。

不要支持 Host override 标头
还需要检查确保你不支持可能用于构造这些攻击的其他标头,特别是X-Forwarded-Host。请记住,这些标头可能在默认情况下是受支持的。

将允许的域列入白名单
为了防止对内部基础设施进行基于路由的攻击,您应该将负载均衡器或任何反向代理配置为仅将请求转发到允许的域白名单。

小心仅限内部的虚拟主机
使用虚拟主机时,您应该避免将仅限内部的网站和应用程序与面向公众的内容托管在同一台服务器上。否则,攻击者可能能够通过 Host 标头操作访问内部域。