javascript - 覆盖 RTCPeerConnection 回调 'onicecandidate'
问题描述
我试图欺骗从 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 的方法是尝试建立连接,然后在 'oniceccandidate' 事件上设置回调,事件信息包含真实 IP 信息。
我想做的是覆盖'oniceccandidate'分配的'set'函数,因此它将被我自己的钩子函数替换,并且在“更改”IP地址之后,钩子将调用指纹脚本设置的真实接收器。
在我的测试中:我可以观察到,在从控制台执行我的代码后, RTCPeerConnection.prototype 已被覆盖,如果我为 RTCPeerConnection.oniceccandidate 分配了一个函数,控制台将打印“hook set”,因此似乎覆盖成功,也如果我调用 RTCPeerConnection.oniceccandidate(xxx) mannullay,我的钩子函数和原始函数都被执行,它按预期工作。但是,当我像粘贴上面那样在真实指纹脚本中使用时,此代码不起作用。在应用覆盖后,永远不会触发 onececandidate 事件。
我是 javascript 的初学者,希望有人能解释我的困惑。
先感谢您。
解决方案
如果不评论为什么这不起作用,仅此一项并不能帮助您对抗使用 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。
推荐阅读
- java - 我们可以在Java中的枚举中的常量内有空间吗
- python - pip:根据包名称选择索引 url?
- javascript - 在我 ajax 一个 rails 表单后没有显示验证错误
- react-native - Share 在 iOS 13 上不起作用。 Expo 模块
- python - 只要数字是,就可以循环继续
- python - 向 Python 提供站点包的其他位置
- r - 如何解决数据密度图的错误消息“提供给连续比例的离散值”;差异功能?
- ios - 如何在不为 AppStore 切片的情况下为 iOS 创建通用框架
- java - 如何使用 Math.pow 计算 bmi
- javascript - json object deserialize issue typescript