来源: https://www.nodeseek.com/post-674661-1
观前提醒:
本篇仅分析了一个接口,不知道接口有什么作用,更不知道这个接口如何影响封控值和共享人数,仅作为风险提醒与数据参考。
不要访问本文的任何链接。
最近刷到了ICMP不可达喵的帖子 历时两个月的ping0实验终于有了结果,正好没什么意思,简单做一个小分析。
首先使用 Reqable 工具抓包,先找可疑请求(即请求体中含有 IP 的请求)。
结果非常 Amazing 啊,发现一请求如下(省略请求头):
POST https://ping0.cc/ip/peer HTTP/2
{
“ip”: “xxx.xxx.xxx.xxx”, # IP 地址
“size”: “879-769” # 浏览器窗口大小
}
--- 返回: HTTP/2 204
看了下启动器,是由 https://cdn.ping0.cc/js/check.js 启动的。
下载下来,发现经过 jsjiami.com.v7 混淆,一般吧,在 AI 时代没啥好说的。
这个方法原文如下:
'peer'() {
const _0x240196 = _0x35e62e,
_0x4a0fc3 = {
'qnArj': function (_0x1b0c8c, _0x599205) {
return _0x1b0c8c === _0x599205;
},
'CfeTI': _0x240196(0x2a1, '&]9^'),
'uxcbk': function (_0x47aa75, _0xb926d0) {
return _0x47aa75 === _0xb926d0;
},
'saKfi': _0x240196(0x1bf, 'l5GL'),
'KxNbH': function (_0x3ad146, _0x30d0ae) {
return _0x3ad146 + _0x30d0ae;
},
'Ahaer': _0x240196(0x208, 'EHcf'),
'FCfGW': _0x240196(0x23f, 'p7Wb'),
'gpjRN': function (_0x1758b5, _0x5b3737) {
return _0x1758b5 === _0x5b3737;
},
'DrvIp': _0x240196(0x2a8, 'H@6r')
},
_0x213f70 = window[_0x4a0fc3[_0x240196(0x2b7, 'H)5x')]];
if (_0x4a0fc3[_0x240196(0x1ef, '2RVF')](_0x213f70, undefined)) {
this[_0x240196(0x1c9, 'nGax')] = window[_0x240196(0x1a3, '[1jt')];
return;
}
const _0x475906 = new _0x213f70({
'iceServers': [{
'urls': _0x4a0fc3[_0x240196(0x2b6, 'fr9d')]
}]
});
_0x475906[_0x240196(0x239, 'M0YP')] = _0x365e93 => {
const _0x507ee3 = _0x240196;
if (_0x365e93[_0x507ee3(0x1ad, 'YS0[')]) {
if (_0x4a0fc3[_0x507ee3(0x1f1, '4Qn*')](_0x4a0fc3[_0x507ee3(0x2a7, 'tqEz')], _0x4a0fc3[_0x507ee3(0x29a, 'J^P0')])) {
const _0x22ec76 = _0x365e93[_0x507ee3(0x1c7, 'nGax')][_0x507ee3(0x2b1, 'H)5x')][_0x507ee3(0x1ff, 'ni%P')](' ')[0x4];
if (_0x4a0fc3[_0x507ee3(0x252, '3LK)')](_0x22ec76[_0x507ee3(0x1a5, '[1jt')](_0x4a0fc3[_0x507ee3(0x248, '#IR7')]), -0x1) && !this[_0x507ee3(0x2a3, '$aHF')](_0x22ec76)) {
const _0x13b720 = _0x4a0fc3[_0x507ee3(0x1e0, '*qsc')](_0x4a0fc3[_0x507ee3(0x28c, 'l5GL')](window[_0x507ee3(0x1e1, '[1jt')], '-'), window[_0x507ee3(0x2b3, 'iMDv')]);
axios[_0x507ee3(0x1d3, '4Qn*')](_0x4a0fc3[_0x507ee3(0x23e, 'ZAzr')], {
'ip': _0x22ec76,
'size': _0x13b720
});
}
} else _0x2588e5[_0x507ee3(0x213, 'SZ(Q')](_0x390073);
}
}, _0x475906[_0x240196(0x1b6, 'f01U')]({
'offerToReceiveAudio': !![]
})[_0x240196(0x1b2, 'H)5x')](_0x2c7a44 => _0x475906[_0x240196(0x24b, 'J^P0')](_0x2c7a44));
}
反混淆清理一下,变成这样:
peer() {
const RTCPeerConnection = window.RTCPeerConnection;
if (RTCPeerConnection === undefined) {
this.newaddr = window.ip;
return;
}
const pc = new RTCPeerConnection({
iceServers: [{ urls: 'stun:stun.l.google.com:19302' }]
});
pc.onicecandidate = (event) => {
if (event.candidate) {
// 死代码分支(混淆器添加的永真条件)
if (true) {
// 从 candidate 字符串中提取第5个字段(IP地址)
const ip = event.candidate.candidate.split(' ')[4];
// 检查:包含点号(IPv4)且不是保留地址
if (ip.indexOf('.') !== -1 && !this.isreserve(ip)) {
// 构造 size 参数
const size = window.innerWidth + '-' + window.innerHeight;
// POST 上报
axios.post('/ip/peer', { ip: ip, size: size });
}
}
}
};
// 触发 ICE 候选收集
pc.createOffer({ offerToReceiveAudio: true })
.then(offer => pc.setLocalDescription(offer));
}
是不是一眼就知道这段代码在干嘛了,利用 WebRTC 技术绕过代理,获取用户的真实公网 IP 地址,并结合浏览器的窗口尺寸信息,将其发送到后端服务器。
那么这段逻辑在什么时候会触发呢?
Vue的 created() hook
只要你打开就静默发生捏。
你要是让我评价这段行为在干嘛,我只能说你都收集浏览器大小了作为指纹了,那还说啥了,难道收集浏览器大小是为了帮你检查一下 WebRTC 有没有 leak?
本篇内容仅供参考,可以自己读一下源码,不长。
本篇内容的任何观点仅代表作者个人看法,并非客观事实,仅供参考。
二编:
用过的大佬们也不用那么焦虑哇,你如果有好好开着 TUN 一点事没有的,不会泄漏你的IP。
就是会收集你的浏览器视图大小作为指纹,可能用于封控值和共享人数的判断,脏掉你的IP(