标题: WebRTC泄露源IP的防范措施 作者: 安全北北 & scz 创建: 2023-04-13 12:24 更新: 2023-09-14 14:53 链接: https://scz.617.cn/web/202304131224.txt -------------------------------------------------------------------------- 目录: ☆ 背景介绍 ☆ 测试WebRTC泄露源IP ☆ 阻止WebRTC泄露源IP 1) 浏览器扩展 1.1) WebRTC Leak Shield (推荐) 1.2) WebRTC Network Limiter (Google) 1.3) 其他扩展 2) 浏览器自带设置 2.1) Firefox 2.2) Safari (未实测) 2.2.1) on macOS 2.2.2) on iOS (before 11) 2.3) Edge (已过时) 2.4) Chrome 2.4.1) on Android 2.4.1.1) 安卓版Chrome的F12 2.4.2) on Win10 (无设置) 2.4.3) Chromium 2.5) Opera 2.6) 利用mDNS阻止泄露内网IP 3) iOS小火箭 ☆ WebRTC泄露源IP的基本原理 1) 简述 2) 真实世界中的WebRTC 3) 延伸阅读 3.1) 3.2) 3.3) 3.4) 3.5) 3.6) WebRTC通信的四种模式 4) WebRTC泄露源IP是否构成安全问题 ☆ JavaScript调用WebRTC API示例 1) STUN IP Address requests for WebRTC 2) 安全北北截图中的代码 2.1) hackjie网页内容分析 (404) 3) 极简示例 4) Public STUN Server List 5) mDNS安全改进 ☆ UDP层面的STUN通信报文 1) Wireshark抓包 2) XOR-MAPPED-ADDRESS 3) Message Cookie: 2112a442 4) 寻找STUN Server 5) PFW阻断周知STUN端口 6) Telegram get remote IP ☆ Media Device Fingerprinting ☆ 其他讨论 ☆ FAQ ☆ 后记 -------------------------------------------------------------------------- ☆ 背景介绍 参看 https://weibo.com/2635351511/MBMlNlhNq 2023.4.13,网友「安全北北」在微博上分享一则WEB安全相关的信息,以下是他的原 话:「今天看到同事说这个网站(略)可以获取到请求来源真实IP,我试了一下,确实, 无论是机场还是自建(包括gost tls),都可以被探测出源IP。研究了一下,应该是 WebRTC的问题,网站可以利用STUN服务器获取到本地的IP地址。简单解决方案,安装 WebRTC Leak Shield 扩展」 我不懂WEB安全,尤其不懂WEB前端安全,他说的WebRTC、STUN什么的,完全不懂。这 种你问ChatGPT,对于毫无此方向基础的人而言,意义不大,让我们换个更聚焦、更 吓人的方式科普。Chrome/Opera/Edge这些浏览器,很可能支持所谓WebRTC技术;假 设A机使用前述浏览器,挂了线路到B机,以B机为中转站访问C机,你以为C机只能看 到B机的IP,但C机通过WebRTC技术可以看到A机的IP。 完全小白的,看早期科普版本即可,其中有些错误,但大面上没问题 https://mp.weixin.qq.com/s/A5dd7WXojGBzsz52_iLtJQ ☆ 测试WebRTC泄露源IP 最初看到「安全北北」的分享,将信将疑。接完cby回家,赶紧在Win10上测试, Chrome/Opera/Edge不幸中招,Firefox ESR逃过此劫,我没有其他浏览器,据说 Safari在此问题上表现不错。测试方案很简单,打开浏览器,挂线路访问如下URL之 一 https://ip8.com/webrtc-test https://www.vpnmentor.com/tools/ip-leak-test-vpns-tor/ https://www.expressvpn.com/webrtc-leak-test https://www.hackjie.com/tracking (404) 社会可能毒打你。看到A、B机IP同时出现在C机页面上,内心是崩溃的,颠覆了我本 就不多的WEB安全认知,无知者无畏太可怕。 附送几个DNS泄露测试URL https://dnsleaktest.org/dns-leak-test https://www.expressvpn.com/dns-leak-test 检查出口源IP的URL到处都是,用自己常用的好了,给比我还白的小白写几个 https://ip4.me/ https://api.ipify.org (只返回源IP) http://checkip.dyndns.com https://ipinfo.io/ ☆ 阻止WebRTC泄露源IP 1) 浏览器扩展 1.1) WebRTC Leak Shield (推荐) 以下是Chrome/Edge/Firefox的"WebRTC Leak Shield"扩展所在URL,各自打开相应 URL安装即可,也可在扩展商店中搜索定位,Opera可以装Chrome扩展。装完立即生效, 可重新测试WebRTC泄露源IP情况,一般均被阻止了。 https://chrome.google.com/webstore/detail/webrtc-leak-shield/bppamachkoflopbagkdoflbgfjflfnfl https://microsoftedge.microsoft.com/addons/detail/pblfgfehcokbglafpcldgjpmknildihk https://addons.mozilla.org/en-US/firefox/addon/webrtc-leak-shield/ 根据我这儿的测试情况,Firefox ESR不装该扩展也不泄露源IP,保险起见,还是装 吧。粗略看了该插件js源码,试图理解某些代码逻辑。 若是Firefox,调 browser.privacy.network.peerConnectionEnabled.set({ value: false }) 这会禁用WebRTC PeerConnection。 若是Chrome,调 -------------------------------------------------------------------------- chrome.privacy.network.webRTCIPHandlingPolicy.set({ value: "disable_non_proxied_udp" }, function () { ... }); -------------------------------------------------------------------------- 该API第一形参可选值有 "default" "default_public_interface_only" "disable_non_proxied_udp" "disable_all_interfaces" 该API第二形参对应一个回调函数,不必理会。实际管事的是 chrome.privacy.network.webRTCIPHandlingPolicy.set({ value: "disable_non_proxied_udp" }) 禁止非代理的UDP通信。 参看 -------------------------------------------------------------------------- 《离线安装Chrome插件》 https://scz.617.cn/web/202205271527.txt 《如何查看Chrome插件js源码》 https://scz.617.cn/web/202305310924.txt -------------------------------------------------------------------------- 1.2) WebRTC Network Limiter (Google) https://chrome.google.com/webstore/detail/webrtc-network-limiter/npeicpdbkakmehahjeeohfdhnlpdklia 该扩展是Google自家的,可阻止WebRTC使用某些IP地址、协议 private IP addresses not visible to the public internet (e.g. addresses like 192.168.1.2) any public IP addresses associated with network interfaces that are not used for web traffic (e.g. an ISP-provided address, when browsing through a VPN) Require WebRTC traffic to go through proxy servers as configured in Chrome. Since most of the proxy servers don't handle UDP, this effectively turns off UDP until UDP proxy support is available in Chrome and such proxies are widely deployed. The extension may also disable non-proxied UDP, but this is not on by default and must be configured using the extension's Options page. This extension may affect the performance of applications that use WebRTC for audio/video or real-time data communication. Because it limits the potential network paths and protocols, WebRTC may pick a path which results in significantly longer delay or lower quality (e.g. through a VPN ) or use TCP only through proxy servers which is not ideal for real-time communication. 看其介绍,该扩展似乎有边际效应,防DNS泄露?因为不走代理的UDP被阻断。该扩展 只防IP泄露,并不彻底禁用WebRTC。 1.3) 其他扩展 下面这些扩展均未实测,仅供参考 -------------------------------------------------------------------------- WebRTC Control (在Edge版评论区有质疑评论,怀疑有猫腻) https://chrome.google.com/webstore/detail/webrtc-control/fjkmabmdepjfammlpliljpnbhleegehm WebRTC Protect - Protect IP Leak WebRTC Leak Prevent https://chrome.google.com/webstore/detail/webrtc-leak-prevent/eiadekoaikejlgdbkbdfeijglgfdalml uBlock Origin (不只是防IP泄露,可彻底禁用WebRTC) https://chrome.google.com/webstore/detail/ublock-origin/cjpalhdlnbpafiamejdnhcphjbkeiagm -------------------------------------------------------------------------- 禁用JavaScript可以阻止WebRTC泄露源IP,JavaScript真是万恶之源啊。不过,禁用 JavaScript的副作用太大,根据自己的实际需求决定吧。 -------------------------------------------------------------------------- NoScript https://addons.mozilla.org/firefox/addon/noscript/ ScriptSafe https://chrome.google.com/webstore/detail/scriptsafe/oiigbmnaadbkfbmpbfijlflahbdbdgdf -------------------------------------------------------------------------- 2) 浏览器自带设置 2.1) Firefox Firefox有个配置项 about:config media.peerconnection.enabled 据说从缺省的true设为false,会禁用WebRTC。但我这儿测下来,无论true还是false, Firefox ESR都没有泄露源IP。保险起见,将之设为false。另有"about:webrtc",可 以看看,在"本地SDP"中未见源IP。 Firefox有一些更细化的设置,不适用于普通用户,高级用户可以看看 https://tools.ietf.org/html/draft-ietf-rtcweb-ip-handling-06 -------------------------------------------------------------------------- media.peerconnection.ice.default_address_only setting this to true essentially provides mode 2 media.peerconnection.ice.no_host setting this and the default_address_only provides mode 3 media.peerconnection.ice.proxy_only setting this to true forces mode 4, disabling UDP -------------------------------------------------------------------------- 若你的Firefox非ESR版本,实测确实泄露了NAT出口IP,可以考虑最后这个设置,强 制使用模式4,此时未禁用WebRTC,同时阻止WebRTC泄露NAT出口IP。 2.2) Safari (未实测) 2.2.1) on macOS Safari->Preferences->Advanced->Show Develop menu in menu bar Develop->WebRTC->Enable Legacy WebRTC API (禁用它) Develop->Experimental Features->Remove Legacy WebRTC API (选中它) 二者并不同时存在,有哪个用哪个。 2.2.2) on iOS (before 11) iOS 11及之前版本可以禁用WebRTC Settings->Safari->Advanced->Experimental Features->Remove Legacy WebRTC API (选中它) 从iOS 12开始,苹果移除了该设置 2.3) Edge (已过时) Edge过去有个配置,但现在已经不在了,此处记一笔 about:flags Hide my local IP over WebRTC connections 即使存在,应该只能阻止WebRTC泄露内网IP,不能阻止WebRTC泄露公网IP。 另有 edge://webrtc-internals/ 类似Firefox的"about:webrtc" 2.4) Chrome 2.4.1) on Android chrome://flags/#disable-webrtc WebRTC STUN origin header 禁用之 微博网友UID(7800576625)反馈,安卓版Chrome 112.0.5615.101已不可用前述设置。 2.4.1.1) 安卓版Chrome的F12 Is it possible to open developer tools console in Chrome on Android phone - [2016-05-16] https://stackoverflow.com/questions/37256331/is-it-possible-to-open-developer-tools-console-in-chrome-on-android-phone 2.4.2) on Win10 (无设置) Chrome未提供便捷配置禁用WebRTC,因为Google大力推介WebRTC以对抗Skype。 另有 chrome://webrtc-internals/ 类似Firefox的"about:webrtc" 2.4.3) Chromium 网友Welkin在公众号留言,Chromium参数"--disable-webrtc-encryption"可以阻止 WebRTC泄露源IP。Chromium与Chrome虽然有关联,但不是一个东西。在微博上请其他 网友验证这个说法,微博网友UID(7128188018、5245763474、7551644722)各自独立 测试,证实至少Chromium 108.0.5359.125及之后版本该参数有此效果,那些测试URL 确实没有显示源IP。前两位说是该参数导致无STUN通信报文,UID(7551644722)提供 了一批pcap文件做为对比,符合理论预期。我没有Chromium环境,未就此抓包分析。 2.5) Opera opera://config/ Privacy protection->Advanced->WebRTC->Disable non-proxied UDP 另有 opera://webrtc-internals/ 类似Firefox的"about:webrtc" 2.6) 利用mDNS阻止泄露内网IP Chrome/Opera/Edge有个配置项 chrome://flags/#enable-webrtc-hide-local-ips-with-mdns opera://flags/#enable-webrtc-hide-local-ips-with-mdns edge://flags/#enable-webrtc-hide-local-ips-with-mdns 显示的信息是 Anonymize local IPs exposed by WebRTC. Conceal local IP addresses with mDNS hostnames 2022年该配置缺省启用中,可以阻止WebRTC泄露内网IP,但不能阻止WebRTC泄露公网 IP。 3) iOS小火箭 微博网友UID(3717584663)提到,iOS小火箭-设置-UDP-禁用STUN,在各个浏览器测 试了,可以防源IP泄漏。 ☆ WebRTC泄露源IP的基本原理 1) 简述 SDP (Session Description Protocol)是一种用于描述媒体会话的协议,它包含有关 音视频编解码器、媒体格式、传输协议等信息。 当一个WebRTC客户端想要与另一个WebRTC客户端通信时,它会将自己的SDP信息提交 给信令服务器(Signaling Server)。信令服务器会将这些信息转发给对端。对端会解 析SDP信息,并生成自己的SDP信息,然后将其提交给信令服务器。信令服务器会将对 端SDP信息转发给发起端。通过交换SDP信息,双方客户端可以协商并建立点对点的音 视频通信。在SDP信息交换过程中,信令服务器类似于中继站,它负责转发SDP信息, 但不会参与实际的音视频数据传输。 STUN Server用于帮助WebRTC客户端发现其NAT (Network Address Translation)类型 和公网IP。WebRTC客户端与STUN Server通信,获取NAT出口IP,填写到SDP信息中。 SDP信息中可能包含多种IP地址,比如本机网卡绑定的公有和私有IP(称为"host candidate")、通过STUN (Session Traversal Utilities for NAT)协议获取的NAT出 口IP(称为"server reflexive candidate"),这些IP地址信息在WebRTC建立连接时被 对端获取。并非所有的SDP信息中都会提供"server reflexive candidate",取决于 WebRTC应用程序具体实现。 自2013年始,安全专家就开始担心WebRTC带来的内网信息泄露。在浏览器中进行音频 /视频通信、P2P文件共享,很可能用到WebRTC,很多手机APP也用。很多场景会用 WebRTC,包括但不限于 Google Meet and Google Hangouts Facebook Messenger Discord Amazon Chime 2015年《纽约时报》曾使用WebRTC收集访问者内网IP,被人给扒出来。 https://webrtchacks.com/dear-ny-times/ https://bloggeek.me/webrtc-new-york-times/ 2) 真实世界中的WebRTC 真实世界中的WebRTC STUN TURN and signaling - [2018-08-01] https://michaelyou.github.io/2018/08/01/%E7%9C%9F%E5%AE%9E%E4%B8%96%E7%95%8C%E4%B8%AD%E7%9A%84WebRTC/ 上文从正常开发者角度详解WebRTC相关组件、通信原理,虽然不直接涉及安全视角, 但明白原理后自然会有安全思考,推荐阅读。 3) 延伸阅读 3.1) https://www.expressvpn.com/webrtc-leak-test -------------------------------------------------------------------------- Web Real-Time Communication (WebRTC) is a collection of standardized technologies that allows web browsers to communicate with each other directly without the need for an intermediate server. Benefits of WebRTC include: faster speeds and less lag for web apps like video chat, file transfer, and live streaming. Any two devices talking to each other directly via WebRTC, however, need to know each other’s real IP addresses. In theory this could allow a third-party website to exploit the WebRTC in your browser to detect your real IP address and use it to identify you. This is what we call a WebRTC leak. WebRTC discovers IPs via the Interactive Connectivity Establishment (ICE) protocol. This protocol specifies several techniques for discovering IPs, two of which are covered below. STUN/TURN servers STUN/TURN servers play two key roles in WebRTC: They allow web browsers to ask the question "What are my public IPs?" and they also facilitate two devices talking to each other even if they are behind NAT firewalls. The former is the one that can affect your privacy. STUN/TURN servers discover your IPs much as a website sees your IPs when you visit it. Host candidate discovery Most devices have multiple IP addresses associated with their hardware. Usually these are hidden from websites and STUN/TURN servers via firewalls. However, the ICE protocol specifies that browsers can gather these IPs simply by reading them off your device. A malicious website could use STUN/TURN servers or host candidate discovery to trick your browser into revealing an IP address that could identify you, all without your knowledge. -------------------------------------------------------------------------- 3.2) https://www.vpnmentor.com/blog/disable-webrtc-in-seconds/ -------------------------------------------------------------------------- WebRTC works directly in the browser using JavaScript. A website's code can be written with scripts that open a WebRTC connection to any browser where it's actively running. This means that WebRTC can leak your IP address even if you've never used the technology for its intended purpose. It doesn't matter whether you've actually accepted a direct audio/video connection or not. As long as WebRTC is fully enabled in your browser, it's putting you at risk. -------------------------------------------------------------------------- https://www.vpnmentor.com/blog/ip-leaks-how-to-check-vpn/ -------------------------------------------------------------------------- The browsers that support WebRTC - like Chrome and Firefox - utilize a STUN server (Session Traversal Utilities for NAT) to obtain an external network address. A website that wants to know your real IP address can very easily conceal a piece of Javascript code to make UDP requests to this STUN server, which would then route these requests to all the available network interfaces. In this situation, both your real IP address and VPN IP address can be exposed, and it's worryingly easy to embed such a code in a supposedly innocent website. To make the situation worse, since these requests are not like typical HTTP requests, the developer console cannot detect them and so browser plugins cannot reliably block this kind of leak (even if they advertise such an ability). -------------------------------------------------------------------------- 3.3) WebRTC IP Leaks: Should You Still Be Worried - Gordon H [2022-11-28] https://getstream.io/blog/webrtc-ip-leaks -------------------------------------------------------------------------- How WebRTC works and how it determines the optimal route to connect two or more devices is quite complicated. Let's just assume that establishing a connection is a matter of exchanging connection information (IP addresses) between peers. This connection information is referred to as ICE ( Interactive Connectivity Establishment) candidates, a standard method of NAT (Network Address Translation) traversal used in WebRTC, which shows the available methods the peer can communicate through (directly or through a TURN server). There are three types of addresses that a WebRTC client tries to negotiate Local IP addresses Public IP addresses found through STUN servers Public IP addresses found through TURN servers. For peers to establish an optimal connection, this information is needed. For example, if two devices are connected to the same local network, they need access to each other's local IP addresses. While if they're not on the same network, they will need an accessible public IP. With modern browsers and the growing need to access resources such as devices' webcams and microphones, an easy-to-use API was needed. This is where WebRTC came in, a JavaScript library built into modern browsers and enabled by default. It provides a convenient API for developers to interact with and makes it easy to create a media connection between multiple peers. Part of this ease-of-use requires a way to retrieve the ICE candidates for the local device, as that information must be shared with any other peer to create a connection. As such, WebRTC exposes a convenient way to access ICE candidates and, indirectly, an easy way to access a device's local and public IP address. -------------------------------------------------------------------------- 3.4) PSA: mDNS and .local ICE candidates are coming - [2019-07-09] https://bloggeek.me/psa-mdns-and-local-ice-candidates-are-coming/ -------------------------------------------------------------------------- Why do we need a local IP address? If both machines that need to connect to each other using WebRTC sit within the same private network, then there's no need for the communication to leave the local network either. Why do we need a public IP address through STUN? If the machines are on different networks, then by punching a hole through the NAT/firewall, we might be able to use the public IP address that gets allocated to our machine to communicate with the remote peer. Why do we need a public IP address on a TURN server? If all else fails, then we need to relay our media through a "third party". That third party is a TURN (Traversal using Relays around NAT) server. -------------------------------------------------------------------------- WebRTC通信双方在同一子网时,各自需要对方的子网IP。通信双方位于不同子网时, 比如跨了NAT,各自需要对方的NAT出口IP,此时先各自通过"STUN Server"收集己方 NAT出口IP,再通过"Signaling Server"完成信息交换。前面两种情况都不可行时, 通信双方经"TURN Server"中转通信。 3.5) Why Doesn't Google Provide a Free TURN Server - [2017-04-03] https://bloggeek.me/google-free-turn-server/ 此文简介了STUN/TURN的作用 Neither Denied nor Exposed: Fixing WebRTC Privacy Leaks - [2020-04] https://www.mdpi.com/1999-5903/12/5/92 https://github.com/IncredibleMe/WebRTC-IP-Leak-Chrome-Extension https://github.com/IncredibleMe/WebRTC-IP-Leak-Gateways 信息量较大、较专业,有STUN/TURN的图解、JavaScript示例、媒体列表指纹的讨论。 3.6) WebRTC通信的四种模式 https://webrtchacks.com/so-your-vpn-is-leaking-because-of-webrtc/ https://tools.ietf.org/html/draft-ietf-rtcweb-ip-handling-06 -------------------------------------------------------------------------- Mode 1 Enumerate all addresses: WebRTC MUST use all network interfaces to attempt communication with STUN servers, TURN servers, or peers. This will converge on the best media path, and is ideal when media performance is the highest priority, but it discloses the most information. Mode 2 Default route + associated local addresses: WebRTC MUST follow the kernel routing table rules, which will typically cause media packets to take the same route as the application's HTTP traffic. In addition, the private IPv4 and IPv6 addresses associated with the kernel-chosen interface MUST be discovered and provided to the application. This ensures that direct connections can still be established in this mode. Mode 3 Default route only: This is the the same as Mode 2, except that the associated private addresses MUST NOT be provided; the only IP addresses gathered are those discovered via mechanisms like STUN and TURN (on the default route). This may cause traffic to hairpin through a NAT, fall back to an application TURN server, or fail altogether, with resulting quality implications. Mode 4: Force proxy: This is the same as Mode 3, but all WebRTC media traffic is forced through a proxy, if one is configured. If the proxy does not support UDP (as is the case for all HTTP and most SOCKS [RFC1928] proxies), or the WebRTC implementation does not support UDP proxying, the use of UDP will be disabled, and TCP will be used to send and receive media through the proxy. Use of TCP will result in reduced media quality, in addition to any performance considerations associated with sending all WebRTC media through the proxy server. -------------------------------------------------------------------------- WebRTC Network Limiter扩展可以迫使Chrome进入模式4。Firefox有原生配置项强制 进入模式4,前面有讲。进入模式4后,客户端与STUN Server的通信必须经过Proxy, 但所有HTTP Proxy以及大多数SOCKS5 Proxy不支持UDP转发,于是事实上阻断了客户 端与STUN Server的通信。 4) WebRTC泄露源IP是否构成安全问题 本文关注的真不是传统意义的安全问题,本文关注的是,在挂线路的前提下泄露源IP 的问题,是特定历史时期、特定区域、特定人群面临的"安全"问题,这个不用展开说 了吧。 关于WebRTC相关的传统安全问题,参看 -------------------------------------------------------------------------- NAT Slipstreaming https://samy.pl/slipstream/ https://github.com/samyk/slipstream A browser-based network IP scanner and local IP detector https://github.com/samyk/webscan WebRTC Fingerprinting + Media Device Fingerprinting https://web-tracking.allenchou.cc/docs/browser-fingerprinting/techniques/webrtc-and-media-device-fingerprinting/ Everything you need to know about WebRTC security - [2020-04-06] https://bloggeek.me/is-webrtc-safe/ -------------------------------------------------------------------------- 2022年之后,WebRTC泄露内网IP的问题得到治理,泄露NAT出口IP仍在继续。严格说 来,是STUN通信导致NAT出口IP泄露,这本就是STUN通信存在之目的,协议设计来就 是干这事的。但在挂线路上网的特定语境下,NAT出口IP泄露成为一个"安全"问题。 网页中的JavaScript触发STUN通信,获取NAT出口IP,再用XMLHttpRequest向外传送 之。 有些人说WebRTC泄露源IP是Feature,不是Issue,可以理解。这些人多半不是网络安 全行业的,TA们对Feature的教条主义理解我见过太多。这是好事,这群大聪明的存 在,让这个世界充满爱,精神的、物质的爱。千万不要毒打TA们,至少面上不要,那 样会减少爱。 ☆ JavaScript调用WebRTC API示例 1) STUN IP Address requests for WebRTC https://github.com/diafygi/webrtc-ips -------------------------------------------------------------------------- Firefox and Chrome have implemented WebRTC that allow requests to STUN servers be made that will return the local and public IP addresses for the user. These request results are available to javascript, so you can now obtain a users local and public IP addresses in javascript. This demo is an example implementation of that. These STUN requests are made outside of the normal XMLHttpRequest procedure, so they are not visible in the developer console or able to be blocked by plugins such as AdBlockPlus or Ghostery. This makes these types of requests available for online tracking if an advertiser sets up a STUN server with a wildcard domain. -------------------------------------------------------------------------- 是时候让ChatGPT为D国做贡献了,指挥它改代码,改了几轮后,如下 -------------------------------------------------------------------------- function getIPs(callback, server, port) { var ip_dups = {}; // compatibility for firefox and chrome var RTCPeerConnection = window.RTCPeerConnection || window.mozRTCPeerConnection || window.webkitRTCPeerConnection; var useWebKit = !!window.webkitRTCPeerConnection; // bypass naive webrtc blocking using an iframe if (!RTCPeerConnection) { // NOTE: you need to have an iframe in the page right above the script tag // // // -------------------------------------------------------------------------- 十分不习惯JavaScript代码风格,改成下面这样稍微增加点可读性。 -------------------------------------------------------------------------- const RTCPeerConnection = window['RTCPeerConnection'] || window['mozRTCPeerConnection'] || window['webkitRTCPeerConnection']; const ips = {}; const print = (id, str) => { const address = (/([0-9]{1,3}(\.[0-9]{1,3}){3}|[a-f0-9]{1,4}(:[a-f0-9]{1,4}){7})/ ['exec'](str) || [])[1]; if (ips[id] = ips[id] || [], address && -1 === ips[id]['indexOf'](address)) { ips[id]['push'](address); console.log(address); } }; const ip = (service, port = 3478) => { if (void 0 != RTCPeerConnection) { const pc = new RTCPeerConnection({ iceServers: [{ urls: "stun:" + service + ":" + port }] }); pc['onicecandidate'] = ice => { ice['candidate'] && print(service, ice['candidate']['candidate']) }; pc['createDataChannel'](""); pc['createOffer'](result => { result['sdp']['split']("\n")['forEach'](line => { -1 !== line['indexOf']("candidate") && print(service, line) }); pc['setLocalDescription'](result, () => {}, () => {}); }, () => {}); setTimeout(() => { pc['setLocalDescription'] && pc['setLocalDescription']['sdp']?.['split']("\n")['filter'](l => 0 === l['indexOf']("a=candidate:"))['forEach'](line => print(service, line)); }, 1e3); } }; ip("stun4.l.google.com", 19302); ip("stun.voippro.com"); ip("stun.voipraider.com"); -------------------------------------------------------------------------- 我这都是在Chrome中实测过的,不是理论可行版本。 2.1) hackjie网页内容分析 (404) 「安全北北」提供的截图内容应该源自hackjie网页 https://www.hackjie.com/tracking (404) 该网页禁止Ctrl-U查看页面源代码,禁止F12呼出"开发者工具"。这种可通过菜单调 出"开发者工具",Elements->Copy->Copy outerHTML,得到网页源码。 在网页源码中搜"{const RTCPeerConnection=window['\x52\x54\x43\x50\x65\x65\x72\x43\x6f\x6e\x6e\x65\x63\x74\x69\x6f\x6e']||window['\x6d\x6f\x7a\x52\x54\x43\x50\x65\x65\x72\x43\x6f\x6e\x6e\x65\x63\x74\x69\x6f\x6e']||window['\x77\x65\x62\x6b\x69\x74\x52\x54\x43\x50\x65\x65\x72\x43\x6f\x6e\x6e\x65\x63\x74\x69\x6f\x6e'],ips={},print=(id,str)=>{const address=(/([0-9]{1,3}(\.[0-9]{1,3}){3}|[a-f0-9]{1,4}(:[a-f0-9]{1,4}){7})/['\x65\x78\x65\x63'](str)||[])[1];if(ips[id]=ips[id]||[],address&&-1===ips[id]['\x69\x6e\x64\x65\x78\x4f\x66'](address)){ips[id]['\x70\x75\x73\x68'](address);const div=window["\x64\x6f\x63\x75\x6d\x65\x6e\x74"]['\x63\x72\x65\x61\x74\x65\x45\x6c\x65\x6d\x65\x6e\x74']("\x64\x69\x76");div['\x74\x65\x78\x74\x43\x6f\x6e\x74\x65\x6e\x74']=address;const parent=window["\x64\x6f\x63\x75\x6d\x65\x6e\x74"]['\x67\x65\x74\x45\x6c\x65\x6d\x65\x6e\x74\x42\x79\x49\x64'](id);"\x6e\x75\x6c\x6c"===parent['\x74\x65\x78\x74\x43\x6f\x6e\x74\x65\x6e\x74']&&(parent['\x74\x65\x78\x74\x43\x6f\x6e\x74\x65\x6e\x74']=""),parent['\x61\x70\x70\x65\x6e\x64\x43\x68\x69\x6c\x64'](div),append(address)}},ip=(service,port=3478)=>{if(void 0!==RTCPeerConnection){const pc=new RTCPeerConnection({iceServers:[{urls:"\x73\x74\x75\x6e\x3a"+service+"\x3a"+port}]});pc['\x6f\x6e\x69\x63\x65\x63\x61\x6e\x64\x69\x64\x61\x74\x65']=ice=>{ice['\x63\x61\x6e\x64\x69\x64\x61\x74\x65']&&print(service,ice['\x63\x61\x6e\x64\x69\x64\x61\x74\x65']['\x63\x61\x6e\x64\x69\x64\x61\x74\x65'])},pc['\x63\x72\x65\x61\x74\x65\x44\x61\x74\x61\x43\x68\x61\x6e\x6e\x65\x6c'](""),pc['\x63\x72\x65\x61\x74\x65\x4f\x66\x66\x65\x72'](result=>{result['\x73\x64\x70']['\x73\x70\x6c\x69\x74']("\n")['\x66\x6f\x72\x45\x61\x63\x68'](line=>{-1!==line['\x69\x6e\x64\x65\x78\x4f\x66']("\x63\x61\x6e\x64\x69\x64\x61\x74\x65")&&print(service,line)}),pc['\x73\x65\x74\x4c\x6f\x63\x61\x6c\x44\x65\x73\x63\x72\x69\x70\x74\x69\x6f\x6e'](result,()=>{},()=>{})},()=>{}),setTimeout(()=>{pc['\x6c\x6f\x63\x61\x6c\x44\x65\x73\x63\x72\x69\x70\x74\x69\x6f\x6e']&&pc['\x6c\x6f\x63\x61\x6c\x44\x65\x73\x63\x72\x69\x70\x74\x69\x6f\x6e']['\x73\x64\x70']['\x73\x70\x6c\x69\x74']("\n")['\x66\x69\x6c\x74\x65\x72'](l=>0===l['\x69\x6e\x64\x65\x78\x4f\x66']("\x61\x3d\x63\x61\x6e\x64\x69\x64\x61\x74\x65\x3a"))['\x66\x6f\x72\x45\x61\x63\x68'](line=>print(service,line))},1e3)}};ip("\x73\x74\x75\x6e\x34\x2e\x6c\x2e\x67\x6f\x6f\x67\x6c\x65\x2e\x63\x6f\x6d",19302),ip("\x73\x74\x75\x6e\x2e\x76\x6f\x69\x70\x70\x72\x6f\x2e\x63\x6f\x6d"),ip("\x73\x74\x75\x6e\x2e\x76\x6f\x69\x70\x72\x61\x69\x64\x65\x72\x2e\x63\x6f\x6d")} -------------------------------------------------------------------------- 这段脚本大量使用\xHH转义序列,就是下面这种操作 $ python3 -c "import sys;print(''.join([f'\x5cx{ord(c):02x}' for c in sys.argv[1]]))" something \x73\x6f\x6d\x65\x74\x68\x69\x6e\x67 将 -------------------------------------------------------------------------- 有个在线网站,可以直接处理转义序列并美化输出 https://beautifier.io 选中"Unescape printable chars encoded as \xNN or \uNNNN",将网页源码中的 JavaScript贴进去,得到可读性更好的输出 --------------------------------------------------------------------------