文章目录
一、HTTP Host请求
1、什么是HTTP Host 请求头?
Host 是 HTTP 1.1 协议中新增的一个请求头,它指定客户端要访问的域名。
例如,当用户访问时https://www.baidu.com,域名和浏览器就组成一个包含Host标头的请求,如下所示:
GET / HTTP/1.1
Host: www.baidu.com
在某些情况下,例如当请求已由中介系统转发时,主机值可能会在到达预期的后端组件之前进行更改。
2、HTTP Host标头的目的是什么?
HTTP Host标头的目的是帮助识别客户端要通信的后端组件。如果请求不包含Host标头,或者Host标头以某种方式格式不正确,则在将请求传入到预期的应用程序时可能会导致问题。
基于云的解决方案和许多相关体系结构外包的不断增长,通常可以在同一IP地址访问多个网站和应用程序。这种方法的普及有部分原因是由于IPv4地址耗尽所致。
当可以通过同一IP地址访问多个应用程序时,最常见的原因是以下情况之一。
①虚拟主机
一种可能的情况是,单个Web服务器托管多个网站或应用程序,这可能是具有单个所有者的多个网站,也可能是将具有不同所有者的网站托管在单个共享平台上,在某些基于云的SaaS解决方案中仍然会发生。尽管这些不同的网站中的每一个都具有不同的域名,但是它们都与服务器共享一个公共IP地址,以这种方式在单个服务器上托管的网站称为“虚拟主机”。
对于访问该网站的普通用户而言,虚拟主机通常与托管在其专用服务器上的网站是无法区分的。
②通过中介路由流量
另一个常见的情况是,网站托管在不同的后端服务器上,但是客户端和服务器之间的所有流量都通过中介系统进行路由,这可能是一个简单的负载平衡器或某种反向代理服务器,在客户通过内容分发网络(CDN)访问网站的情况下,这种设置尤其普遍。
在这种情况下,即使网站托管在单独的后端服务器上,它们的所有域名也都解析为中间组件的单个IP地址。这带来了与虚拟主机相同的挑战,因为反向代理或负载平衡器需要将每个请求路由到适当的后端。
3、HTTP Host标头如何解决此问题?
当浏览器发送请求时,目标URL将解析为特定服务器的IP地址。当该服务器接收到请求时,它参考主机头来确定预期的后端并相应地转发该请求。
二、HTTP Host 攻击
1、什么是HTTP主机标头攻击?
HTTP Host 攻击利用易受攻击的网站,这些网站以不安全的方式处理主机请求头的值,如果服务器默认信任Host,但未能正确验证或转义它,则攻击者可能通过更改Host的值注入有害的有效负载,以此来操纵服务器端的行为。
涉及直接将有效负载注入主机Host的攻击称为“HTTP Host 注入”攻击。
标头值还可以用于网站基础结构的不同系统之间的各种交互。
由于Host请求头是用户可控制的,如果没有正确地对输入进行转义或验证,可能会导致许多问题。
Host标头是一系列其他漏洞的潜在利用载体,最值得注意的是:
①Web缓存中毒
②特定功能中的 业务逻辑缺陷
③基于路由的SSRF
④经典的服务器端漏洞,例如SQL注入
2、HTTP Host Header漏洞如何产生?
HTTP Host Header漏洞通常是由于错误的假设而造成的,即该标头不可由用户控制。即使攻击者可以使用Burp Proxy之类的工具轻松地修改主机标头,这也会在Host标头中创建隐式信任,并导致其验证或转义不足。
即使可以更安全地处理Host标头本身,具体取决于处理传入请求的服务器的配置,也可以通过注入其他标头来覆盖Host。有时,网站所有者不知道默认情况下支持这些标头,因此,它们可能不会受到相同级别的审查。
实际上,这些漏洞中大部分并不是由于编码不安全,而是由于相关基础架构中一个或多个组件的配置不安全,由于网站将第三方技术集成到其体系结构中,而不了解配置选项及其安全隐患,因此发生这些配置问题。
三、如何识别HTTP Host标头漏洞
使用到的工具主要是burpsuite之类的抓包工具。
在我们抓到请求包之后,需要确定是否可以修改Host头,并且是否可以通过修改后的请求到达目标应用程序,并观察其对响应的影响。
1、提供一个任意的主机头
在探查主机头注入漏洞时,第一步是测试当修改Host为任意域名时发生的情况。
一些拦截代理直接从Host标头获取目标IP地址,这时便无法测试,因为对标头所做的任何更改都只会导致将请求发送到完全不同的IP地址。但是,Burp Suite可以准确地保持主机标头和目标IP地址之间的分隔,这种分隔可以帮助我们在将Host修改为任意或格式不正确的Host标头,仍可以将请求发送到预期的目标。
有时,即使提供了意外的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标头解析错误。
2、发送不明确的请求
验证主机的代码和对其进行脆弱处理的代码通常位于不同的应用程序组件中,甚至位于单独的服务器上。通过识别和利用它们在检索主机标头方面的差异,我们可以发出一个模棱两可的请求,该请求似乎具有不同的主机,具体取决于正在查看的系统。
①注入重复的主机头
尝试添加重复的Host标头,这种方法通常只会导致请求被阻止,但是,由于浏览器不太可能发送此类请求,因此有时可能会发现开发人员没有预料到的情,在这种情况下,系统可能会返回一些意料之外的内容。
不同的系统和技术将以不同的方式处理这种情况,但是通常会给两个标头界定优先级,从而有效地覆盖优先级较低的host,但是当系统不确定哪个标头是正确的标头时,这可能会导致差异,出现意外情况。
考虑以下请求:
GET /example HTTP/1.1
Host: vulnerable-website.com
Host: bad-stuff-here
假设前端将优先级设置为标头的第一个实例,但后端则优先选择最终实例。在这种情况下,可以使用第一个标头来确保将请求发送到预期的目标,并使用第二个标头将有效负载传递到服务器端代码中。
②提供一个绝对URL
同时提供绝对URL和Host标头引起的歧义也可能导致不同系统之间的差异,造成响应出现问题。
GET https://vulnerable-website.com/ HTTP/1.1
Host: bad-stuff-here
有时,服务器的行为会有所不同,可能还需要尝试不同的协议,具体取决于请求行包含HTTP还是HTTPS URL。
③添加换行
通过缩进带有空格字符的HTTP标头。某些服务器会将缩进的标头解释为换行,因此将其视为前一个标头值的一部分,其他服务器将完全忽略缩进的标头。
由于这种情况的处理方式非常不一致,因此处理请求的不同系统之间通常也会存在差异。
例如:
GET /example HTTP/1.1
Host: bad-stuff-here
Host: vulnerable-website.com
该网站可能会阻止带有多个主机标头的请求,但是可以通过缩进其中的一个缩略来绕过此验证。如果前端忽略缩进的标头,则该请求将作为的普通请求进行处理vulnerable-website.com。现在,假设后端在重复的情况下优先使用第一个标头,这种差异可能导致可以通过包装后的主机标头传递任意值。
3、注入主机覆盖头
即使不能使用歧义的请求覆盖Host标头,也有其他方法可以覆盖它的值,同时保持Host原封不动。这包括通过旨在满足此目的而设计的其他几个HTTP标头,通过这几个标头注入有效负载。
通常可以通过某种中间系统(例如负载平衡器或反向代理)访问网站。在这种体系结构中,后端服务器接收的Host标头可能包含这些中间系统之一的域名。
为了解决此问题,前端可以注入X-Forwarded-Host标头,其中包含来自客户端初始请求的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主机标头攻击
1、为了防止HTTP Host标头攻击,最简单的方法是避免在服务器端代码中完全使用Host标头。仔细检查每个URL是否确实需要绝对的。经常发现,只能使用相对URL,这个简单的更改可以帮助防止Web缓存中毒漏洞。
2、保护绝对网址
当必须使用绝对URL时,应要求在配置文件中手动指定当前域,并引用此值而不是Host标头。这种方法将消除密码重置中毒的威胁。
3、验证主机头
如果必须使用Host标头,请确保正确验证它。包括对照允许的域白名单检查它,以及拒绝或重定向对无法识别的主机的任何请求。查阅框架的文档以获取有关执行此操作的指导。例如,Django框架ALLOWED_HOSTS在设置文件中提供了该选项。这种方法将减少遭受主机标头注入攻击的风险。
4、不支持主机替代标头
要检查是否不支持可能用于构造这些攻击的其他标头,尤其是X-Forwarded-Host。请记住,默认情况下可能支持这些功能。
5、将允许的域名列入白名单
为了防止对内部基础结构进行基于路由的攻击,将负载平衡器或任何反向代理配置为仅将请求转发到允许域的白名单。
6、注意仅限内部使用的虚拟主机
使用虚拟托管时,应避免将面向内部的网站和应用程序与面向公众的内容托管在同一服务器上。否则,攻击者可能可以通过主机标头操纵来访问内部域。
参考:https://portswigger.net/