logo NodeSeekbeta

对 ping0.cc 利用 WebRTC 静默上报用户真实 IP 的分析

观前提醒:
本篇仅分析了一个接口,不知道接口有什么作用,更不知道这个接口如何影响封控值和共享人数,仅作为风险提醒与数据参考。
不要访问本文的任何链接。

最近刷到了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(

  • 珍愛 IP,遠離 ping0。

  • 以下是针对普通人的详细影响分析:

    1. 你的“伪装”可能完全失效

    技术背景: 帖中提到的 WebRTC 是一种网页实时通信技术。

    对你的影响: 很多普通用户为了隐私或访问特定网站,会使用代理工具(俗称“科学上网”)。你以为你在网站面前显示的 IP 是在国外的服务器,但这段代码利用 WebRTC 协议的特性,直接穿透你的代理,抓取你电脑在电信/联通/移动网络下的真实公网 IP。

    • 后果: 即使你开了代理,网站后端依然知道你人在哪里、真实身份是谁。

    1. 账号关联与“精准画像”

    技术背景: 帖中提到它还收集了 size(浏览器窗口大小)。

    对你的影响: 单纯一个 IP 可能还不够精准,但加上“浏览器窗口大小”,就形成了一个简单的设备指纹。

    • 后果: 如果你在该网站查询过多个 IP,或者在不同时间访问,网站可以通过这些特征把这些访问记录串联起来,判断出“这几个人其实是同一个人”。这对于想要保持匿名访问的用户来说是致命的。

    1. 数据被定向收集的风险

    技术背景: 该行为是在 created() 生命周期钩子中静默发生的。

    对你的影响: 你只要打开网页,不需要点击任何按钮,你的真实 IP 就已经被上报到了对方的服务器(POST 请求)。

    • 风险: * 隐私泄露: 如果该网站数据库泄露或被恶意利用,你的真实地理位置信息可能会被公开。

    • 追踪欺诈: 某些广告商或恶意机构可能通过这些数据对你进行跨站追踪。

    1. 信任崩塌

    对普通人的心理影响: ping0.cc 本身是一个帮助用户检测“我的 IP 够不够纯净”、“我有没泄露隐私”的工具网站。

    • 讽刺点: 一个标榜检测隐私泄露的工具,竟然在后台偷偷记录你的隐私。这会让普通用户在选择网络检测工具时产生不信任感。

    给普通人的建议

    如果你经常需要使用这类 IP 检测工具,又担心真实 IP 泄露,可以采取以下措施:

    1. 禁用 WebRTC: 在浏览器(如 Chrome, Edge)中安装插件(如 WebRTC Leak Prevent)或使用 Firefox 在设置中手动关闭 WebRTC 功能。

    2. 使用隐身模式: 虽然不能完全防御,但可以减少部分指纹关联。

    3. 更换工具: 尽量使用更透明、口碑更好的检测网站(如 ip.gs, ip.sb 等),或者使用开源的检测脚本。

    4. 警惕“指纹”: 尽量不要在缩放比例奇特的窗口下访问敏感网站,因为那是非常独特的身份标记。

    总结: 这个帖子提醒我们,“检测隐私的人可能正在偷窥你的隐私”。对于普通人来说,最直接的影响就是你的真实上网位置可能已经被该网站记录并存档了。

  • 其实我是能理解它在干嘛的
    首先他们官网本身有一个这样的功能,需要webrtc
    https://ipv4.ping0.cc/ipleak
    然后ping0本身通过访问来判定共享用户数的这个方式也要webrtc佐证
    就是 你开着这个IP+Webrtc泄露 = 人数+1
    但是这种基于“全网用户都会来访问ping0”的前提来做风控真的挺啥比的

    开车的人记得屏蔽ping0,这样ping0就会一直干净,也能避免小白车友天天来问你为啥ping0红了

  • @ICMP不可达喵 #45 发现大佬,太恶心了,只要你created了直接给你上传 实在难绷

  • xhj002

  • 这狗东西

  • 幸亏不用这玩意

  • xhj017 xhj011

  • 可怕

  • 越测试风险越高,越描越黑

  • 标记一下,以后再也不用了。

  • 哦豁,信用崩塌

你好啊,陌生人!

我的朋友,看起来你是新来的,如果想参与到讨论中,点击下面的按钮!

📈用户数目📈

目前论坛共有52573位seeker

🎉欢迎新用户🎉