我正试图欺骗从WebRTC泄漏的IP地址,所以我想重写'onicecandidate'回调函数,但是下面的代码不起作用,我无法弄清楚为什么。
Object.defineProperty(RTCPeerConnection.prototype, 'onicecandidate', {
set: function (eventHandler) {
console.log('hook set');
this._onicecandidateEventHandler = eventHandler;
this._onicecandidate = function (event) {
console.log('hook');
this._onicecandidateEventHandler.apply(this, arguments);
};
},
get: function () {
return this._onicecandidate;
}
})
上面的代码应该钩住“指纹脚本”分配的接收器功能。
一个指纹脚本示例如下:
function findIP() {
var myPeerConnection = window.RTCPeerConnection || window.mozRTCPeerConnection || window.webkitRTCPeerConnection;
var pc = new myPeerConnection({iceServers: [{urls: "stun:stun.l.google.com:19302"}]}),
noop = function() {},
localIPs = {},
ipRegex = /([0-9]{1,3}(\.[0-9]{1,3}){3}|[a-f0-9]{1,4}(:[a-f0-9]{1,4}){7})/g,
key;
function ipIterate(ip) {
if (!localIPs[ip]) {console.log('got ip: ', ip);}
localIPs[ip] = true;
}
pc.createDataChannel("");
pc.createOffer(function(sdp) {
sdp.sdp.split('\n').forEach(function(line) {
if (line.indexOf('candidate') < 0) return;
line.match(ipRegex).forEach(ipIterate);
});
pc.setLocalDescription(sdp, noop, noop);
}, noop);
pc.onicecandidate = function(ice) {
if (!ice || !ice.candidate || !ice.candidate.candidate || !ice.candidate.candidate.match(ipRegex)) return;
ice.candidate.candidate.match(ipRegex).forEach(ipIterate);
};
}
如您所见:从webRTC获取真实IP的方法是尝试建立连接,然后在“ onicecandidate”事件上设置回调,该事件信息包含真实的IP信息。
我想做的是覆盖“ onicecandidate”分配的“ set”功能,以便将其替换为我自己的钩子函数,并且在“更改” ip地址之后,该钩子将调用由指纹脚本。
在我的测试中:我可以观察到,从控制台执行我的代码后,RTCPeerConnection.prototype已被覆盖,如果我为RTCPeerConnection.onicecandidate分配了一个函数,则控制台将显示“ hook set”,因此出现覆盖是成功,如果我调用RTCPeerConnection.onicecandidate(xxx)mannullay,钩子函数和原始函数都将被执行,它将按预期工作。但是,当我在真实的指纹脚本中使用上述代码时,此代码无法正常工作。应用覆盖后,永远不会触发onicecandidate事件。
我是javascript的初学者,希望有人可以解释我的困惑。
先谢谢您。
答案 0 :(得分:1)
没有评论为什么它不起作用,仅此一项就无法帮助您克服使用addEventListener('icecandidate')的脚本。
adapter.js包含处理两个变体的“ wrapPeerConnectionEvent”帮助程序函数。有了该帮助器,它就变得非常简单:
wrapPeerConnectionEvent(window, 'icecandidate', (e) => {
if (e.candidate) {
const parts = e.candidate.candidate.split(' ');
parts[4] = '127.0.0.1'; // replace the real ip with 127.0.0.1
e.candidate.candidate = parts.join(' ');
}
return e;
});
有关完整示例,请参见https://jsfiddle.net/krgz5qu1/。 请注意,您可能需要注意服务器自反和中继候选者的relAddr字段中的ip。