什么?Host头攻击?怎么攻击?又进入梨子知识盲区了,同样一脸懵逼的小伙伴快带着问题跟着梨子一起看看怎么回事吧!!!
声明
该系列共三篇,26个专题(截止2023.8.10),其中有21个专题的大部分内容已于2021年7-9月首发于安全客,由于某些原因,该系列后续更新部分梨子打算转投Freebuf社区(下称"社区")。因后续更新部分的部分内容为这21个专题中的,故在转投社区时会将更新部分一并加入对应的专题中,所以会与发布于安全客的版本略有出入,会更完整,望周知。
本系列介绍
PortSwigger是信息安全从业者必备工具burpsuite的发行商,作为网络空间安全的领导者,他们为信息安全初学者提供了一个在线的网络安全学院(也称练兵场),在讲解相关漏洞的同时还配套了相关的在线靶场供初学者练习,本系列旨在以梨子这个初学者视角出发对学习该学院内容及靶场练习进行全程记录并为其他初学者提供学习参考,希望能对初学者们有所帮助。
梨子有话说
梨子也算是Web安全初学者,所以本系列文章中难免出现各种各样的低级错误,还请各位见谅,梨子创作本系列文章的初衷是觉得现在大部分的材料对漏洞原理的讲解都是模棱两可的,很多初学者看了很久依然是一知半解的,故希望本系列能够帮助初学者快速地掌握漏洞原理。
高级漏洞篇介绍
相对于服务器端漏洞篇和客户端漏洞篇,高级漏洞篇需要更深入的知识以及更复杂的利用手段,该篇也是梨子的全程学习记录,力求把漏洞原理及利用等讲的通俗易懂。
什么是HTTP Host头?
从HTTP/1.1开始,HTTP Host头是强制性的请求头。它指定客户端要访问的域名或IP。例如
GET /web-security HTTP/1.1
Host: portswigger.net
我们在前面的专题有讲过我们可以通过一些其他HTTP请求头覆盖Host的值以向指定的新的域名或IP发出该请求。
设置HTTP Host头有什么作用?
现在的互联网规模这么大,为了节约资源,会选择将多个应用程序部署在同一个IP上。HTTP Host头就是用来区分用户欲请求的是哪个应用程序。目前有以下几种情况是需要使用这种办法的。
虚拟主机
虚拟主机就是将一台物理服务器虚拟成多台服务器用于部署不同的应用程序。这种情况有时会出现在SaaS中。对于访问应用程序的用户来说,他们可能并不能察觉到这些应用程序是部署在同一个IP上的。
通过中转路由流量
另一种情况是不同的应用程序部署在不同的物理服务器上,但是所有的流量都会经过一个中转进行流量路由,一般通过负载均衡或反向代理的技术实现的。这种技术一般应用于CDN中。
那HTTP Host头是如何解决这个问题的呢?
这两种情况都依赖Host头来指定预期的接收者。这就像你们都住同一栋楼,需要一个更细致的编号去区分你是哪一层哪一间房的住客。Host头就是做这个用的。
当浏览器发送请求时,目标URL将解析为特定服务器的IP地址。当该服务器收到请求时,它会参考Host头来确定预期的后端并相应地转发请求。
什么是HTTP Host头攻击?
应用程序有时会将Host值拼接到某些地方,但是由于Host的值是可以通过burp手动修改的,所以就可能会导致一些恶意的拼接,HTTP Host头攻击可以发动这些攻击
Web缓存投毒
特定功能点的商业逻辑漏洞
基于路由的SSRF
经典服务器端漏洞,如Sql注入等
HTTP Host头漏洞是如何产生的?
服务器端一般觉得用户不会修改Host头从而默认信任Host头,就会导致验证不足或转义其值,我们就可以轻松地在burp中修改它从而构造某种攻击行为。
即使Host头本身的处理更加安全,根据处理传入请求的服务器的配置,Host也可能通过注入其他头来覆盖。有时,管理员不知道默认支持这些头,因此,它们可能不会经过严格的过滤措施。
事实上,许多此类漏洞的出现并不是因为后端代码不安全,而是因为相关基础设施中一个或多个组件的配置不安全。这些配置问题可能会发生,因为网站集成了很多第三方组件,开发人员可能并不会了解全部组件的细节。
如何测试使用HTTP Host头的漏洞?
提供任意的HTTP Host头
这一步很明显,就是我们尝试将Host头修改成任意域名或IP,比如我们常用的度度,然后观察响应是否会有变化,以此来检测是否存在HTTP Host头攻击。
检查有缺陷的验证点
有的是否应用程序并不会直接返回Invalid Host header,而是有一些其他的处理措施。有些对Host头的验证点的解析规则是有缺陷的,比如仅会验证域名而不验证端口号。这个知识点其实我们在Web缓存投毒专题中介绍过,通过把payload附在端口号中从而将其反馈到响应中。例如
GET /example HTTP/1.1
Host: vulnerable-website.com:bad-stuff-here
有的应用程序只会验证是否以允许的子域结尾,但是我们让Host以它结尾即可,例如
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头的值,例如
GET /example HTTP/1.1
Host: vulnerable-website.com
Host: bad-stuff-here
如果服务器端会将第二个Host头优先于第一个Host头,就会覆盖掉它的值,然后中转组件会因为第一个Host头指定了正确的目标而照常转发这个请求包,这样就能保证它可以顺利到达服务器。
提供绝对URL
正常情况下请求行采用的是相对地址,但是也是允许使用绝对地址的,就是将原本的Host值拼接到相对地址前面构成绝对地址,这时我们将Host头值替换为payload就可能会发生不可思议的事,例如
GET https://vulnerable-website.com/ HTTP/1.1
Host: bad-stuff-here
有时还可以修改一下URL的协议观察一下有没有什么差异,比如把HTTPS换成HTTP等。
添加换行
有的时候我们还可以通过添加空格缩进来触发某种解析差异,它们会把空格缩进解析成换行从而忽略该Host头,例如
GET /example HTTP/1.1
Host: bad-stuff-here
Host: vulnerable-website.com
虽然有的应用程序不会接受多个Host头的请求,但是因为会忽略掉一个而成功发出请求。该请求到达后端后还是会正常处理第一个Host头,这样就可以利用这种差异注入payload。
其他技术
旅行者,你的等级还不够,我们以后再来探索这里吧。
注入可覆盖Host的请求头
前面的专题中也有介绍过,有一些请求头的值是可以覆盖Host的值的,比如X-Forwarded-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
我们可以通过前面介绍过的Param Miner插件的Guess headers功能发现这些奇奇怪怪的头
HTTP Host头有哪些利用?
密码重置投毒
密码重置是怎么样的过程?
大部分的应用程序都提供了密码重置功能。比较常见的密码重置流程是这样的
用户输入他们的用户名或电子邮件地址并提交密码重置请求
如果用户名或电子邮件地址存在的话就会将其与一个Token绑定
然后用户接收到一个附有这个Token的重置密码链接
用户点击以后就可以修改与该Token绑定的用户的密码,修改完密码以后Token就会随之销毁。
理论上只有用户本人会接收到这个链接,但是通过密码重置投毒可以窃取到这个链接。
如何构造密码重置投毒攻击?
如果应用程序根据Host头记录接收密码重置链接的地址,则可以通过密码重置投毒攻击获取到指定用户的密码重置链接,下面我们介绍一下构造过程。
我们修改提交密码重置请求中的Host为目标的域
这时候该用户会收到一封密码重置链接的邮件,但是这条链接会请求刚才Host设置的域,而不是真正用于密码重置的域
如果受害者点击该链接,攻击者就能获得与用户绑定的密码重置操作的Token
攻击者向真正密码重置的域发出请求并附上刚才获取到的Token即可成功重置受害者用户的密码了
为了增加受害者点击链接的可能性,我们可以利用一些暗示。如果这种攻击方式不成功还可以尝试使用悬挂标记攻击窃取Token。
配套靶场1:基础密码重置投毒
首先我们找到密码重置点
然后我们点到重置密码的页面
我们输入要伪造的用户名carlos然后抓包
然后我们进到Exploit Server查看我们要伪造的邮件服务器域名
然后把Host字段改成这个,然后放包,再进到Exploit Server的Access Log里面看获取到的重置密码Token
然后把这个Token构造进重置密码链接里面进行密码重置
重置密码成功后成功登录carlos的账户
配套靶场2:通过悬挂标记的密码重置投毒
这一关我们发现Host没有对端口号进行鉴别,导致我们可以把任意字符串拼接到端口号后面,这样应该算是一种HTTP走私攻击了,术语里面叫HTTP头部污染,因为这一关是系统那边给我们分配密码,所以只能通过这种方法把分配的密码带出来,于是我们这么伪造Host
成功登录carlos用户
通过Host头的Web缓存投毒
在上一个专题Web缓存投毒中我们其实也讲了这种攻击手段,当时是利用Web缓存投毒发动XSS攻击。这种攻击手段可以让本来无法通过Host让目标用户遭受攻击的情况重新可以让目标用户接收到恶意响应缓存。
配套靶场:通过模棱两可的请求的Web缓存投毒
这里我们可以再加一个Host字段覆盖掉原来的Host字段
然后我们到Exploit Server伪造一个我们的/resources/js/tracking.js
然后产生Web缓存,访问主页的人就会接收到投毒缓存了
触发经典的服务器端漏洞
经典的服务器端漏洞大部分都是由于含有payload的请求头导致的,当然,Host头也是,有时候可以通过向Host注入payload触发如Sql注入之类的漏洞。
访问受限的功能
有的功能点被限制为只允许内部用户访问,但是有时候通过简单修改Host头就可以绕过这种限制。
配套靶场:Host头验证绕过
打开robots.txt找到了管理页面
然后进到管理页面发现以下提示
这里提示我们只有本地用户才能访问,那么我们就在Host字段中伪造我们是本地用户
然后我们成功访问到管理页面,然后成功删除Carlos用户
利用爆破虚拟主机访问内部网站
有的网站运营者会把对外和对内的网站部署在同一台服务器上,但是内部网站往往无法通过DNS查询到内部IP,但是可以通过如信息泄漏、暴力破解的方式知道其内部IP。
基于路由的SSRF
基于路由的SSRF是利用负载均衡或者反向代理的特性发动的攻击。因为负载均衡和反向代理的作用都是中转流量,会根据Host去路由,但是如果没有进行严格的限制,可能会仅仅通过修改Host就让它们将请求包转发到其他域。并且它们既可以接收来自外部网络的请求,还能请求大部分的内部网络,所以经常它们会被当成攻击目标。我们可以通过先将请求转发到burp collaborator来探测是否存在该漏洞。
配套靶场1:基于路由的SSRF
基于路由的SSRF典型利用点是修改Host,首先我们先测试一下能不能向外发请求,打开我们的burp collaborator client,把Host替换为生成的地址,然后发包
然后我们在burp collaborator client点poll now等着接收
成功接收,说明服务器是可以向任意地址发出请求的,然后我们爆破一下admin在哪台主机下,把Host改成192.168.0.0然后发到Intruder里面将最后一个0设置为变量,Payload type改成numbers,设置从0到255,递进1
然后Start Attack,然后按状态码排序得到admin在192.168.0.3
然后把包传到Repeater里,跳转以后把Host手动改成192.168.0.3(不然会返回404)
然后我们找到了提交删除用户表单的地方,需要构造两个参数
然后在request栏右键change request method以后将两个参数csrf和username及它们的值写在body里,发包
成功删除用户
配套靶场2:利用请求解析缺陷的SSRF
首先我们试一下修改Host为burp collaborator的地址看看服务端允不允许访问
发现修改Host会被禁止,那我们试试把URL换成靶机的绝对地址试试
从图中发现URL换成绝对地址就可以让服务端向外根据Host发出请求,然后把Host改成192.168.0.0,然后发到Intruder里面爆破一下,还是numbers类型
爆破出来192.168.0.26是后台地址,发到repeater里追踪一下重定向
跳转到管理后台的时候别忘了URL用绝对地址,Host改成192.168.0.26,然后根据页面信息构造删除请求
最好是先把参数写在URL里然后再右键转换请求方法,这样会自动计算Content-Length,成功删除角色
连接状态攻击
这一小节大概在讲漏洞利用分页的基于路由的SSRF后面。出于性能原因,许多网站会对同一个客户端的多个请求/响应周期重用连接。实施不当的HTTP服务器(中间件)有时会在危险的假设下运行,即某些属性(比如Host头)对于通过同一连接发送的所有HTTP/1.1请求都是相同的。这可能适用于浏览器发送的请求,但不一定适用从Repeater发送的一系列请求。这就可能导致很多潜在的问题。
例如,我们可能会偶尔遇到仅对通过新连接收到的第一个请求执行全面验证的服务器。在这种情况下,我们可以通过发送一个看起来无害的初始请求然后在同一连接中跟着恶意请求来绕过校验。
许多反向代理使用Host头将请求路由到正确的后端。如果他们假设连接上的所有请求都针对与初始请求相同的主机,这可以为许多Host头攻击提供有用的向量,包括基于路由的 SSRF、密码重置投毒和缓存投毒。
配套靶场:通过连接状态攻击绕过Host验证
题目说存在一个通过Host头的基于路由的SSRF,服务器只会检测同一连接的第一个请求,并且对同一连接的后续请求的Host假设与第一个请求是相同的。题目是来源于一篇真实的漏洞研究报告:Browser-Powered Desync Attacks: A New Frontier in HTTP Request Smuggling。题目的目标是访问管理员后台192.168.0.1/admin
并且删除用户carlos。我们先看一下直接修改URI和Host头看看会怎么样。
新版的burp默认会用http2,但是这道题又要用http1.1,所以我们需要修改一下设置。
然后我们复制一个标签页,并且把这两个标签页组合成一个标签组。然后选择标签组里的第一个标签,将URI和Host改回去。
然后点击Send
按钮旁边的下拉箭头,选择Send group in sequence (single connection)
,这样我们就可以在同一个连接中按顺序发送两个包了。为什么这些功能离我这么近我却从来没用过!burp真的会总是给我惊喜,我哭死。
然后我们点击发送按钮,发现第二个包已经成功进入管理后台了,说明我们成功绕过了Host验证。
于是我们在第二个包里构造一下删除用户的请求包。
成功绕过Host验证删除了carlos,解题成功!好好玩啊这道题!
利用错误格式的请求行的SSRF
反向代理会将请求行的路径与后端主机名拼接进行路由。但是如果我们提交一个错误格式的请求行呢,例如
GET @private-intranet/example HTTP/1.1
这次拼接后可能会变成如http://backend-server@private-intranet/example 的形式,就可能会被某些HTTP库解释为使用用户名backend-server访问内部网站。
如何缓解HTTP Host头攻击?
限制使用绝对地址
验证Host头
限制覆盖Host头
设置白名单域
留意仅限内部访问的虚拟主机
总结
以上就是梨子去上PortSwigger网络安全学院系列之高级漏洞篇 - HTTP Host头攻击专题的全部内容啦,本专题主要讲了HTTP Host头攻击的原理、识别方法、利用及防护等,感兴趣的同学可以在评论区和梨子讨论哦,嘻嘻嘻。