【热剩饭】获取代理池背后攻击者的真实IP
2021-4-2 14:48:6 Author: mp.weixin.qq.com(查看原文) 阅读量:25 收藏

写在前面

    继上次代理池之后,我们有了动态切换IP的代理池方案,看着挺不错,封不完IP,作为防守方要怎么揪攻击者的小辫子呢?

    WebRTC 获取IP是比较老的技术了,看了一圈大家好像也没怎么注意这玩意儿,今天再把这剩饭拿出来热一热,毕竟江郎才尽了不是。


起因

    代理是大家在打点的时候经常会用到的,其中就以 socks5 最为方便。但是我们注意到,socks5 协议本身是支持 UDP 协议的,只是大部分的客户端软件/库的作者比较懒,没有实现这部分,遇到之后都直接写个 TODO

    那么思路来了,我们能不能在网页上发起一个 udp 请求呢?试想一下,攻击者在代理后面,所有的 tcp 请求都会被攻击者通过 socks5 代理转发出去,如果是 udp 请求,由于代理不支持 udp 会直接由攻击者自己去访问,那么是不是就可以抓到攻击者的真实的出口IP地址了呢?

理论上好像是这么个道理,不如搞个 demo 测试一下


寻找合适的方法

说干就干,Google 一下,马上知道。我们找一下 HTML/JS/CSS 这些语言能不能发起 udp 请求。

StackOverFlow 上面给了我们答案,可以用 WebRTC。

哇,这玩意儿可不陌生啊,老朋友了。大家以前在用 XSS 平台的时候,最喜欢的 XSS 获取受害者内网/公网 IP ,就是用的 WebRTC。

https://github.com/diafygi/webrtc-ips  这个仓库里面已经有现成的 demo 了。好家伙,6 年前的 demo,结合着新版本的开发文档,我们把这个 demo 稍稍改动了一些:

为了明显的对比 TCP 获取到的 IP 地址和 WebRTC 获取到的 IP 地址, 我们改成 php 的, 然后给 javascript 里面加了一些 try catch 处理,最终长这个样子:

webrtc.php

<!DOCTYPE html><html>    <head>        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">    </head>    <body>        Remote Addr: <?=$_SERVER['REMOTE_ADDR']?>        <hr>        <h3>WebRTC</h3>        <h4>Your local IP addresses:</h4>        <ul id="localip"></ul>        <h4>Your public IP addresses:</h4>        <ul id="publicip"></ul>        <h4>Your IPv6 addresses:</h4>        <ul id="ipv6"></ul>        <iframe id="rtc_iframe" sandbox="allow-same-origin" style="display: none"></iframe>        <script>            //get the IP addresses associated with an account            function getIPs(callback){                var ip_dups = {};                //compatibility for firefox and chrome                var RTCPeerConnection = window.RTCPeerConnection                    || window.mozRTCPeerConnection                    || window.msRTCPeerConnection                    || window.webkitRTCPeerConnection;                var useWebKit = !!window.webkitRTCPeerConnection;                //bypass naive webrtc blocking using an iframe                if(!RTCPeerConnection){                    var win = document.getElementById("rtc_iframe").contentWindow;                    RTCPeerConnection = win.RTCPeerConnection                        || win.mozRTCPeerConnection                        || win.msRTCPeerConnection                        || win.webkitRTCPeerConnection;                    useWebKit = !!win.webkitRTCPeerConnection;                }                //minimal requirements for data connection                var mediaConstraints = {                    optional: [{RtpDataChannels: true}]                };
var servers = { iceServers: [ { urls: [ 'stun:stun.l.google.com:19302?transport=udp', 'stun:stun1.l.google.com:19302?transport=udp', 'stun:stun2.l.google.com:19302?transport=udp', 'stun:stun3.l.google.com:19302?transport=udp', 'stun:stun4.l.google.com:19302?transport=udp', "stun:stun.ekiga.net?transport=udp", "stun:stun.ideasip.com?transport=udp", "stun:stun.rixtelecom.se?transport=udp", "stun:stun.schlund.de?transport=udp", "stun:stun.stunprotocol.org:3478?transport=udp", "stun:stun.voiparound.com?transport=udp", "stun:stun.voipbuster.com?transport=udp", "stun:stun.voipstunt.com?transport=udp", "stun:stun.voxgratia.org?transport=udp" ] } ] }; //construct a new RTCPeerConnection var pc; try { pc = new RTCPeerConnection(servers, mediaConstraints); } catch (e) { return } function handleCandidate(candidate){ //match just the IP address var ip_regex = /([0-9]{1,3}(\.[0-9]{1,3}){3}|[a-f0-9]{1,4}(:[a-f0-9]{1,4}){7})/ var ip_addr = ip_regex.exec(candidate)[1]; //remove duplicates if(ip_dups[ip_addr] === undefined) callback(ip_addr); ip_dups[ip_addr] = true; } //listen for candidate events pc.onicecandidate = function(ice){ //skip non-candidate events if(ice.candidate) handleCandidate(ice.candidate.candidate); };
//create a bogus data channel pc.createDataChannel("bl"); //create an offer sdp try { pc.createOffer().then(function(result) { pc.setLocalDescription(result); }); } catch (e) { pc.createOffer().then(function(result) { pc.setLocalDescription(result, function(){}, function(){}); }, function() {}); } //wait for a while to let everything done setTimeout(function(){ //read candidate info from local description var lines = pc.localDescription.sdp.split('\n');
lines.forEach(function(line){ if(line.indexOf('a=candidate:') === 0) handleCandidate(line); }); }, 1000); } //insert IP addresses into the page getIPs(function(ip){ var li = document.createElement("li"); li.textContent = ip; //local IPs if (ip.match(/^(192\.168\.|169\.254\.|10\.|172\.(1[6-9]|2\d|3[01]))/)) document.getElementById("localip").appendChild(li); //IPv6 addresses else if (ip.match(/^[a-f0-9]{1,4}(:[a-f0-9]{1,4}){7}$/)) document.getElementById("ipv6").appendChild(li); //assume the rest are public IPs else document.getElementById("publicip").appendChild(li); });</script> </body></html>

ok, 找台服务器,把这个脚本放上去,然后开启代理试一下:

挂代理的方式我也顺便测试了,你们可以自己测一下

  1. Chrome 插件 SwitchyOmega

  2. Proxifier 直接给浏览器进程挂代理

  3. Clash 开系统代理

然后访问我们的目标站点:

18.167.94.x 是代理的地址, 上 IPIP 查一下地理位置是 HK 的

我们再查一下 117.136.x.x 这个用 WebRTC 获取到的 IP 地址:

好家伙,果然是我本机的出口IP了


事情就是这么个事情,老套路,不算什么新东西。说一下注意的点:

  • 这玩意儿默认是启用的(对的没错,包括你现在在看文章用的微信的浏览器)

  • 那挂个支持 udp 的 socks5 代理行不行?不行,WebRTC设计之初就是为了点对点通信,毕竟是传流的,压根就不会走代理,懂了啵

  • VPN 行不行?可以。

受限于时间原因,像 QUIC 等其它的基于UDP的协议,没来得及一一去尝试,大家自己有兴趣可以实验实验。我们来说说想到的几处应用。

蓝队发散思维

1.  WAF 拦截页面埋点,打点爱用代理是吧?埋在 WAF 拦截后的页面里面,抓到的IP都不是好人

2. 往蜜罐里埋

3. 可以挖掘一下其它的未被注意到的基于 UDP 协议的功能

至于拿到真实 IP 地址之后,回传的问题,可以用 ajax 发 http 包带回去,也可以自己实现一个 WebRTC 服务器,走 udp 来收这部分的数据。除了 WebRTC 服务器之外,像 WebRTC 中用于的 STUN / TURN 服务器,你也可以自己实现一套,反正不让你知道我在哪一步记你就完事。


红队发散思维

1. 专用打点浏览器,禁掉 WebRTC 功能。

是的,我找了一圈的人测试,发现很少有人会禁掉这个功能,所以写了这篇文章出来。

Chrome浏览器禁用 WebRTC 的方法是:在Chrome应用商店里,安装一个名为 WebRTC Leak Prevent 的扩展,然后选择 Disable non-proxied UDP(force proxy) 即可。

Firefox浏览器禁用WebRTC的方法是:在浏览器上输入:about:config。之后搜索:media.peerconnection.enabled。找到它后双击,将其改成 false 即可。

2. 就算你禁掉了 WebRTC,也有挂代理,推荐用热点,再挂代理池

就像我上面提到的,我只是测试了 WebRTC,其它的浏览器支持的基于 UDP 的协议我都没来得及去试。

3. 改用 VPN


    想拿清明节 3 倍工资的同学,别愣着,快去优化吧


不如关注一波再走?


文章来源: https://mp.weixin.qq.com/s?__biz=MzI0MDI5MTQ3OQ==&mid=2247484114&idx=1&sn=50ee6039f361e4a62b2a8faae35bac9b&chksm=e91c592ade6bd03c4ce1bca045fac9e26141465df8e21dab697c365b4cf9beb2ebd75c5843ac&scene=58&subscene=0#rd
如有侵权请联系:admin#unsafe.sh