以下文章来源于骨哥说事 ,作者骨哥说事
这是一枚弱加密配合IDOR利用,从而导致完全接管他人帐户的漏洞。
为了方便称呼,以后咱们就统一叫白帽子小哥为“小白”好了。
最近小白同学经常读到一些帐户接管漏洞的文章,他们通常是利用“X-Forwarded-Host”头来窃取用户Token从而进行账户接管,于是乎小白也想着动手尝试尝试,他在某个漏洞赏金平台中接受了一项赏金任务,并尝试寻找帐户接管漏洞。当然,他成功了!
漏洞存在于“密码重置”功能,通过该功能可以完全接管任意帐户,且无需用户进行任何交互。
第1步:
用户通过"example.com/php/login_or_password_forget",在输入用户个人ID和姓名后,开始请求重置密码;
第2步:
他们的用户ID和姓名得到验证后,将生成一个“state”参数,像下面这样:
STATE=eJxdkN1OwzAMhd8lDzA1XffT9GpMDE2gdmKTuIxM4paILilJJhBo747DfjRxlfhzYp9zGpHPBduaryiXzqN8wdeVhz1%2BOv8utxEiMsHFTxATwcJfWYEoEpgKppxtTZfIOJGSSG%2FQRmkGVgXBC8H4ZDYq8hHnfMSnZaL0r3cKekwFTUUrH%2B7SnXT0YLsDdP9aRxo1E6y96hrAR4ueVY3Iy1v1i81abk7Ny8loIWkjKQcLe1bVNDrPBHuDIHuEYGwnyUf0oCKrXkWWhFPfo3KdNd%2Bob6k0FiOt34cLJTvy4wD9FZANCVp7DCFtO4vfPS%2Fq7WK5Wze13DWP93WyOM4FgxJn7VgrBS2fTzVqzDLFVY4cs2Le6vSuTMmESL5P0RT8bHrjXWt68j0M8sl1xjZ%2BAyFQSHrlfOdidJbyO%2F4CvKKcYg%3D%3D55840ad4a2f32819aa5da2cf48288290
第3步:
在这一步中,厂商将向用户注册的电子邮箱发送密码重置链接,如下所示:
https://example.com/php/login_or_password_forgotten?k=789c0dc8610a80200c06d0bbec049bc9d26f870921834192a4ffa2bbd7fbf90a029e810c9adeea98a5753287a844e16555b1016150bfafc3cfbaf94eff2450e494a2e640f67ebc89137aade927d25a020ab2535ab4b5c9dc4fd1
第4步:
用户通过点击重置链接后跳转至修改密码界面进行密码更改。
这个“?k”参数看起来有不是有点眼熟?小白将其粘贴至CyberChef(经常打CTF比赛的一定对这款工具不陌生吧)中,小白惊讶的发现它确实是一个加密+压缩的字符串:
这段字符串首先使用zlib压缩,然后再进行16进制转换。
经过CyberChef解密后的字符串中,小白发现了两个重要变量“profile_id”和“timeStamp”,于是小白立即建立了另一个账号,尝试伪造第二个账户令牌,以期望重置这个账户的密码,伪造的字符串如下:
789c0dc8510a85201005d0bdcc0ac6f25da6eb62427806034992fe457bb7df93b9f0e9dc28c36be923d726c919107ec0aa40ea0c4a69f775f85976ffcb2746891a610693f44ebe171387
但是很遗憾,点击重置链接后,提示该链接不可用。
如果仔细观察,我们会发现原始令牌和伪造的令牌长度是不一致的:
原始令牌和伪造的令牌相差了32个字符,这是一个很大的问题,因为服务器肯定不会接受任意32个字符,但是两个令牌被解密后,却是相同的值,即:
“a:2:{s:9:”timestamp”;i:1614104013;s:10:”profile_id”;s:8:”40884692";}”.
这让小白同学非常沮丧😫😫,于是他开始查看更多关于Zlib压缩的文章,在经历了2小时的各种阅读后,小白同学发现Zlib包含了一个ADLER32校验值,如果你在使用Adler-32_checksum()函数后,将会得到“BC89137A”,并且这个校验值会存在于原始令牌中,在Zlib中,该校验值之后的所有内容都不是压缩流的一部分,因此将会被忽略,这就是为什么两个令牌即使在长度不同,也会产生相同结果的原因!
所以是时候挑战这个32位的字符串了,因为所有与令牌相关的工作一般都会客户端进行,所以小白同学尝试在JS文件中寻找线索。
在查看了几个小时的JS文件后,小白发现了一处“/php/user”的URL,于是他尝试爆破目录,最终小白找到了“https://example.com/php/user/example/”,该URL有一个名为“transctionToken”的字符串,实际上这正是要找的最后32位字符串的内容。
是时候将字符串进行拼接了,由于每次刷新页面时“Transaction _Token”都会发生变化,于是小白同学写了一个Python脚本来自动化整个过程,于是他成功的生成了“受害者“账户的令牌,并利用重置链接,更改了该用户的密码。
如果有令牌,那么就存在被破解的可能
不要忘记JS文件,因为这些文件往往包含了有关Web的重要信息
试着在一些社区询问技术细节,有时会有你惊喜的结果
相信你的直觉,比别人多做一点!
PS:这位白帽同学的推特是:https://twitter.com/mayank_pandey01
本文作者:贝塔安全实验室
本文为安全脉搏专栏作者发布,转载请注明:https://www.secpulse.com/archives/190272.html