1 基本概念
WebRTC(Web Real-Time Communication)網頁實時通信,允許網絡應用不借助中間媒介情況下建立P2P(Peer-to-Peer)連接,實現
視頻流或其它任意數據傳輸[1]。因此需要使用NAT穿越技術。在WebRTC使用了ICE協議框架,裏面提到了STUN和TURN兩個協議,而
NAT穿越實現就是由這兩個協議共同協調完成的。這裏涉及了ICE、STUN、NAT、NAT、TURN、SDP等概念具體可以查看參考資料一。
它的工作流程可以簡述爲基於ICE協議框架(整合了STUN與TURN),本地服務向stun服務器發送請求,stun服務器將本地服務器的ip端口
等信息填入candidate中,並回傳本地服務,通過stun服務器來判斷NAT的類型。從而決定後續是否需要使用turn服務器進行p2p通信。
2 chrome中通過WebRTC獲取本地IP
下面的代碼摘自參考8,本文測試如下代碼使用的chrome版本爲Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3669.0 Safari/537.36。如果用到其它版本chrome瀏覽器獲取ip失敗可參照參考6的方法進行排查分析。其獲取思路即獲取本地SDP信息並從中摘取candidate部分拿到本地IP。
// ice配置信息,指定了stun server地址
var servers = {
iceServers: [{
urls: "stun:stun.l.google.com:19302?transport=udp"
}]
};
// 構建 RTC connection對象,創建peer端
var pc = new RTCPeerConnection({servers});
//創建一個數據傳輸通道
pc.createDataChannel("");
// 生成本地SDP
pc.createOffer(function(result) {
pc.setLocalDescription(result, function() { console.log("success");
}, function(e) {
console.log(e);
});
}, function() {});
//listen for candidate events
pc.onicecandidate = function(ice) {
//skip non-candidate events
if (ice.candidate) {
handleCandidate(ice.candidate.candidate);
}
};
//等待一段時間後讀取本地sdp
setTimeout(function() {
try {
var lines = pc.localDescription.sdp.split('\n');
console.log(pc.localDescription.sdp);
lines.forEach(function(line) {
if (line.indexOf('a=candidate:') === 0)
handleCandidate(line);
});
} catch (err) {
console.log(err);
}
}, 100);
// 解析ip
function handleCandidate(candidate) {
//match just the IP address
var ip_regex = /([0-9]{1,3}(\.[0-9]{1,3}){3}|[a-f0-9]{1,4}(:[a-f0-9]{1,4}){7})/
var ip_addr = ip_regex.exec(candidate)[1];
//remove duplicates
if (ip_dups[ip_addr] === undefined)
callback(ip_addr);
ip_dups[ip_addr] = true;
}
IP通過candidate獲取,樣例如下。解析代碼解析candidate所在行,實現獲取IP。
a=candidate:735671172 1 udp 2113937151 172.30.23.16 60444 typ host generation 0 network-cost 999
v=0
o=- 4472746833261312439 2 IN IP4 127.0.0.1
s=-
t=0 0
a=group:BUNDLE data
a=msid-semantic: WMS
m=application 60444 DTLS/SCTP 5000
c=IN IP4 192.168.199.106
a=candidate:735671172 1 udp 2113937151 192.168.199.106 60444 typ host generation 0 network-cost 999
a=ice-ufrag:24I4
a=ice-pwd:PDshREZzi1C39qwm9Q17XeUx
a=ice-options:trickle
a=fingerprint:sha-256 3E:F0:EF:B2:9E:93:02:80:DE:FA:3F:E8:EF:29:7D:D6:CF:11:5D:90:8E:DB:FC:7F:91:BA:52:DC:41:AB:6C:B5
a=setup:actpass
a=mid:data
a=sctpmap:5000 webrtc-datachannel 1024
獲取IP的兩個點分別在onicecandidate事件處理與讀取本地sdp信息兩個位置。這兩個信息分別屬於RTCPeerConnection對象的localDescription.sdp屬性,RTCIceCandidate對象的屬性candidate(onicecandidate回調函數中接收的參數類型是RTCIceCandidate)。
因此若要改變那麼調整這兩個對象對應的屬性即可。
RTCIceCandidate.prototype,"candidate"
RTCPeerConnection.prototype, "localDescription"
candidate即前文中的單行數據
a=candidate:735671172 1 udp 2113937151 172.30.23.16 60444 typ host generation 0 network-cost 999
localDescription的格式如下
{
type: "offer",
sdp: `v=0
o=- 6840727536538077826 2 IN IP4 127.0.0.1
s=-
t=0 0
a=group:BUNDLE data
a=msid-semantic: WMS
m=application 49212 DTLS/SCTP 5000
c=IN IP4 192.168.3.16
a=candidate:735671172 1 udp 2113937151 172.30.23.16 49212 typ host generation 0 network-cost 999
a=ice-ufrag:O7iV
a=ice-pwd:XtQuXGYaS+fudhdv3NBbIRiu
a=ice-options:trickle
a=fingerprint:sha-256 AC:03:C1:45:9E:A5:23:8D:FB:C6:63:38:C2:69:B5:65:C9:7B:64:B3:68:FF:A3:4E:42:50:CC:AD:0F:FC:DD:3C
a=setup:actpass
a=mid:data
a=sctpmap:5000 webrtc-datachannel 1024`
}
3 總結
反爬中利用WebRtc收集本地IP並作爲指紋的一個計算維度可提高識別率。但某些瀏覽器下會出現無法獲取的情況。此外收集IP屬於泄漏用戶信息,不少大廠網站現在都在收集,所以使用chrome或ff一定要屏蔽相關功能防止隱私泄漏。
4 參考
[1].WebRTC基本概念,https://developer.mozilla.org/zh-CN/docs/Web/API/WebRTC_API
[2]RTCSessionDescription,https://developer.mozilla.org/en-US/docs/Web/API/RTCSessionDescription
[3]RTCPeerConnection,https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection
[4]sdp,https://developer.mozilla.org/en-US/docs/Web/API/RTCSessionDescription/sdp
[5]setLocalDescription,https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/setLocalDescription
[6]連接錯誤的處理方式,https://blog.csdn.net/qq_40033374/article/details/87868275
[7]NAT穿越原理,https://www.jianshu.com/p/84e8c78ca61d
[8]WebRtc獲取本地IP,https://github.com/diafygi/webrtc-ips