如何识别和利用HTTP Host标头漏洞
如何测试HTTP Host头漏洞
基本测试
将Host头设置为任意无法识别的域名,观察返回结果。
如若返回正常,可以查找下响应是否有直接调用了Host的值,以此来判断如何利用。
检查验证错误
-
仅验证域名,未验证端口,端口尝试非数字是否可行
GET /example HTTP/1.1 Host: vulnerable-website.com:bad-stuff-here
-
正则匹配域名
-
您可以通过注册一个以与白名单中相同的字符序列结尾的任意域名来完全绕过验证:
GET /example HTTP/1.1 Host: notvulnerable-website.com
-
如果存在一个子域有其他漏洞比如SSRF,则可以结合起来利用
GET /example HTTP/1.1 Host: hacked-subdomain.vulnerable-website.com
-
-
提交两个Host头混淆
假设前端将优先级设置为标头的第一个实例,但后端优先选择最终实例。
在这种情况下,您可以使用第一个标头来确保将请求路由到预期的目标,并使用第二个标头将有效负载传递到服务器端代码中。GET /example HTTP/1.1 Host: vulnerable-website.com Host: bad-stuff-here
-
提供一个绝对URL
虽然请求行通常指定被请求域上的相对路径,但许多服务器也被配置为理解对绝对url的请求。
同时提供绝对URL和主机标头造成的歧义也会导致不同系统之间的差异。正式地说,在路由请求时应该优先考虑请求行,但在实践中,情况并非总是如此。您可以像使用重复主机头一样利用这些差异。
GET https://vulnerable-website.com/ HTTP/1.1 Host: bad-stuff-here
这里注意您可能还需要试验不同的协议。服务器有时会根据请求行是否包含HTTP或HTTPS URL而表现不同。
-
注入其他头覆盖Host头
一般发生在中间件解析
GET /example HTTP/1.1 Host: vulnerable-website.com X-Forwarded-Host: bad-stuff-here
X-Host
X-Forwarded-Server
X-HTTP-Host-Override
Forwarded
密码重置攻击
如果发送给用户的URL是基于可控输入(例如Host标头)动态生成的,则可能会构成如下的密码重置中毒攻击:
- 攻击者根据需要获取受害者的电子邮件地址或用户名,并代表他们提交密码重置请求。
- 提交表单时,他们将拦截生成的HTTP请求并修改Host标头,使其指向他们控制的域。
- 受害人收到密码重置的链接,携带有密码重置的令牌。
- 如果受害者单击此链接(或以其他方式(例如,通过防病毒扫描程序获取),则密码重置令牌将被传递到攻击者的服务器。
- 攻击者现在可以访问易受攻击的网站的真实URL,并通过相应的参数提供受害者的被盗令牌。
然后,他们将能够将用户的密码重置为所需的密码,然后登录到其帐户。
web缓存投毒
主机头身份验证绕过
有些web应用程序通过Host头来限制身份,比如管理界面只允许本地用户登录,身份验证只是简单的通过判断Host头是否为localhost。绕过方法为:直接将Host头改为Host: localhost
即可。
如何避免Host头攻击
绝对网址
当必须使用绝对URL时,应要求在配置文件中手动指定当前域,并引用此值而不是Host标头。这种方法将消除密码重置中毒的威胁。
验证主机头
如果必须使用Host标头,请确保正确验证它。
这应该包括对照允许域的白名单检查它,以及拒绝或重定向对无法识别的主机的任何请求。
您应查阅框架文档以获取有关执行此操作的指导。
例如,Django框架在设置文件中提供了ALLOWED_HOSTS选项。
这种方法将减少您遭受主机标头注入攻击的风险。
禁用主机替代标头
同样重要的是要检查您是否不支持可能用于构造这些攻击的其他标头,尤其是X-Forwarded-Host。
请记住,默认情况下可能支持这些功能。
将允许的域名列入白名单
为了防止对内部基础结构进行基于路由的攻击,应将负载平衡器或任何反向代理配置为仅将请求转发到允许域的白名单。
注意仅限内部使用的虚拟主机
使用虚拟托管时,应避免将面向内部的网站和应用程序与面向公众的内容托管在同一服务器上。
否则,攻击者可能可以通过主机标头操纵来访问内部域。