这篇文章将介绍作者在 Hackerone 的私人项目中发现的一个漏洞,该漏洞允许我接管任何用户的账户。
在开始之前,我想先提供一些关于 Host 头的小基础知识。
HTTP Host 头是 HTTP/1.1 中的必需请求头,它指定了用户希望访问的域名。
例如,如果用户访问 https://example.com,那么他们的浏览器将发出如下所示的请求,其中包含 Host 头:
GET / HTTP/1.1
Host: example.com
现在让我们开始
几天前,我收到了 Hackerone 的通知,说我被邀请加入了一个私密项目。
我接受了邀请,并开始在这个私密项目中进行漏洞挖掘。
刚开始进行漏洞挖掘的前几天,我花了 5 到 6 天时间,发现了跨站脚本攻击(XSS)、IDOR、SQL 注入、登录页面漏洞、信息泄露和子域名接管等问题,但始终没有找到什么特别的漏洞。
经过几个小时的休息后,我再次开始在该域名上进行漏洞挖掘。
这个时候,我发现了一个上次没注意到的有趣功能。
这个有趣的功能就是“密码重置功能”。
于是我心想,为什么不试试这个密码重置功能呢?
由于这是一个私密项目,我不能公开目标的名称。
所以,让我们假设目标是 site.com。他们的密码重置功能大致是这样的:
我注意到,每当我们输入电子邮件并点击“重置密码”时,我们会收到一封包含密码重置令牌链接的电子邮件。
密码重置令牌链接如下所示:
https://site.com/action-token?key=eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICIzZWM2ODU2Z
这次,我决定拦截密码重置请求,并且启动了我的 ngrok 服务器。
原始请求大致如下所示:
然后,我在原始请求中添加了另一个头部 X-Forwarded-Host
,并将其设置为我的 ngrok 服务器域名。
现在修改后的请求大致如下所示:
然后这次,我收到了一个更改密码的电子邮件,但其中的密码重置令牌链接指向了我的 ngrok 服务器域名。
密码重置令牌链接看起来如下所示:
https://95saf4ct71g.ngrok.io/action-token?key=wia2lkIiA6ICciOiJIUzI1NiIsInR5cCIgODU2ZeyJhbGiA
你可以看到,我成功地通过在密码重置请求中添加 X-Forwarded-Host 头部来更改了主机。
接着,我注意到,如果我在密码重置页面中输入受害者的电子邮件并拦截请求,再添加一个包含我恶意域名的 X-Forwarded-Host 头部,受害者将会收到一个带有我恶意域名的密码重置令牌链接。
当受害者点击该链接时,他们将被重定向到我的网站,并且所有的令牌都会泄漏给我。
然后,我可以使用泄漏的令牌来更改受害者的密码。
是的,这个漏洞的影响就是完整的账户接管。
所以,现在我可以完全接管任何在 site.com 上拥有账户的人的账户,只要通过重置他们的密码。
因此,我毫不浪费时间,成功提交了这个漏洞,并附上了完整的概念验证。
随后,Hackerone 的私人项目团队奖励了我 1000 美金。
这个漏洞非常经典,漏洞成因可以追溯为系统架构过于复杂,存在多层转发,进而易诱发配置不当的情况。
我们可以假设重置密码是一个后台服务,那么它是无法知道用户访问的入口域名是什么的,这种情况一般就是代码直接获取 Host 头(正常人写法),但是这个 Host 头可能会被前置的中间件如 nginx 进行重写,而重写的规则可能就是获取 X-Forwarded-Host(类似 X-Forwarded-Ip)
如果是上述情况,通过在用户端X-Forwarded-Host覆盖重写的值就会导致这个漏洞产生。
如果你是一个长期主义者,欢迎加入我的知识星球,我们一起往前走,每日都会更新,精细化运营,微信识别二维码付费即可加入,如不满意,72 小时内可在 App 内无条件自助退款
本文算是一个合集系列,会收集各种经典 BugBounty 漏洞案例,分析形成的原因并归类探测方法。
后续可能会将这些成果转换为检测工具(Burp 插件)完成赋能,敬请各位观众老爷期待,感谢大家的阅读和支持。
Thanks https://saajanbhujel.github.io/bugbounty/blog/web/2021-02-26-password-reset-token-leak-via-x-forwarded-host