V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
charslee013
V2EX  ›  分享发现

我是如何找到隐藏在防火墙下的源服务器 IP

  •  1
     
  •   charslee013 · 2023-07-31 16:14:39 +08:00 · 3495 次点击
    这是一个创建于 515 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我是如何找到隐藏在防火墙下的游戏服务器 IP

    起因

    闲逛的时候看有个discussion说替换了另一个 Cloudflare IP 地址后,就无法工作的情况

    这里插一句介绍下Cloudflare CDN 以及 Anycast Cloudflare CDN 是一个内容分发网络,使用了 Anycast 路由技术,这意味着链接任意一个 Cloudflare CDN 的 IP 地址,都可以正确访问目标网站

    一开始我并不相信仅仅换一个 IP 就会导致无法访问。为了弄清原因,我决定完整复原一次连接过程。

    https://i.imgur.com/eJJup2S.png

    首先该程序会向 https://mjjpgs.mahjongsoul.com:8443/api/v0/recommend_list?service=tcp-gateway&protocol=tcp&ssl=false 发起链接,获得游戏服务器的具体地址

    $ curl 'https://mjjpgs.mahjongsoul.com:8443/api/v0/recommend_list?service=ws-gateway&protocol=ws&ssl=true' | jq
    
    {
      "servers": [
        "mjjpgs.mahjongsoul.com:9663"
      ]
    }
    

    探测

    到这里傻眼了,虽然是同个域名,但 Cloudflare CDN 对于端口是有要求的,用 nmap 得出的实验结果是一致的

    普通 Cloudflare CDN 默认开启的端口如下

    $ nmap -sV -p- -T 5 --min-rate 10000 $(dig @1.1.1.1 www.cloudflare.com +short | tail -n 1)
    
    PORT     STATE SERVICE       VERSION
    80/tcp   open  http          cloudflare
    443/tcp  open  ssl/https     cloudflare
    2052/tcp open  clearvisn?
    2053/tcp open  ssl/http      nginx
    2082/tcp open  infowave?
    2083/tcp open  ssl/http      nginx
    2086/tcp open  gnunet?
    2087/tcp open  ssl/http      nginx
    2095/tcp open  nbx-ser?
    2096/tcp open  ssl/http      nginx
    8080/tcp open  http-proxy    cloudflare
    8443/tcp open  ssl/https-alt cloudflare
    8880/tcp open  cddbp-alt?
    

    mjjpgs.mahjongsoul.com 使用的 IP 地址比较特殊,使用 nmap 探测出来的端口全都是 tcpwrapped

    $ nmap -sV -p- -T 5 --min-rate 10000 $(dig @1.1.1.1 mjjpgs.mahjongsoul.com +short | tail -n 1) 
    
    PORT      STATE    SERVICE             VERSION
    1/tcp     open     tcpwrapped
    2/tcp     open     tcpwrapped
    3/tcp     open     tcpwrapped
    4/tcp     open     tcpwrapped
    5/tcp     open     tcpwrapped
    6/tcp     open     tcpwrapped
    7/tcp     open     tcpwrapped
    8/tcp     open     tcpwrapped
    9/tcp     open     tcpwrapped
    10/tcp    open     tcpwrapped
    11/tcp    open     tcpwrapped
    12/tcp    open     tcpwrapped
    13/tcp    open     tcpwrapped
    14/tcp    open     tcpwrapped
    15/tcp    open     tcpwrapped
    16/tcp    open     tcpwrapped
    

    说明该类型的 IP 会根据你的请求来源、目标和内容来决定是否开启真正连接,这种特定的 IP只允许特定的特定访问类型通过

    胡同

    在知道了使用了特定的 IP 地址,现在的目标就改为了:找到另一个允许 mjjpgs.mahjongsoul.com:9663 的 Cloudflare CDN IP

    便动手写了个简单的 Websocket/TLS 校验工具,模拟下图所示的 http 请求,具体代码在这

    https://i.imgur.com/rFHegg6.png

    程序的逻辑如下:

    1. 解析 IP 地址或者按行解析文件的 IP 地址或 CIDR
    2. 对目标 IP:Port 发起 HTTPS 连接
    3. 连接成功后,发起 HTTP 请求升级为Websockets
    4. 升级成功后(HTTP/1.1 → Websocket),会返回Http code 101 表示切换协议成功

    程序的选项如下所示

    # 你可以指定 IP 地址,或者输入一个只包含 IP 地址或者 CIDR 域的文件
    Usage: go run main.go -ip <IP> -port <Port> -file <FileName> -num <Number> -host <HostName>
    
    • ip: 指定一个 IP 地址,可以跟 -file 一起使用,但必须至少选择一个
    • port: 指定目标的端口
    • file: 每行是 IP 地址或者 CIDR 域的文件,可以跟 -ip 一起使用,但必须至少选择一个
    • num: 并发数
    • host: 指定需要验证的域名

    这里我们准备一份Cloudflare ip range 文件,下载到本地后直接运行

    $ curl https://www.cloudflare.com/ips-v4 --output ips.txt
    # 指定端口 9663,并发 2000,域名为 mjjpgs.mahjongsoul.com
    $ go run main.go -port 9663 -file ips.txt -num 2000 -host mjjpgs.mahjongsoul.com
    

    但结果往往都是不出人所料的,得出的结果也只有 172.65.244.96 这么一个 IP 地址

    $ go run main.go -port 9663 -file ./ips.txt -num 2000 -host mjjpgs.mahjongsoul.com
    **172.65.244.96
    All requests completed.**
    

    放弃

    其实到这里其实差不多该放弃了,如果你是 Clouflare 会员用户,可能用过一款叫做 Spectrum | DDoS Protection for Apps | Cloudflare 的产品

    Cloudflare Spectrum 是一种反向代理产品,它可以将 Cloudflare 的优势扩展到所有 TCP/UDP 应用程序,在本文里面就是用作游戏加速以及抵御 DDoS 攻击

    这里再展开讲讲跟 Cloudflare CDN 的区别,像我们正常使用 Cloudflare CDN 的时候,其实是 Cloudflare 反向代理了请求连接到源服务器

    https://i.imgur.com/33bjqWU.png

    只是 Cloudflare CDN 主要是针对 HTTP/HTTPS 协议,并且只允许特定的端口(80,443,8443)进行链接

    并且 Cloudflare CDN 可以缓存静态内容,而 Spectrum 不会缓存任何内容,只是将流量(TCP or UDP)代理到源服务器,并且 Spectrum 还可以设置特定的 IP 地址作为该服务的唯一的入口

    这就导致了普通的 Cloudflare CDN IP 无法进行正确的反向代理(因为设置了只允许特定 IP 进行访问),从而隐藏起了源服务器 IP 地址以及抵御了大规模的 DDos 攻击

    整体效果图如下

    https://i.imgur.com/zE0ohDr.png

    路转

    在我百无聊奈一篇又一篇的查阅资料的时候,原来讨论贴的作者的一句话提醒了我

    https://i.imgur.com/ZDTXyiK.png

    换了一个 IP 地址后,mjjpgs.mahjongsoul.com:8443 没问题

    如果你还记得上面的知识,8443 端口是一个允许被 Cloudflare CDN 代理的端口,这么说明其实我们可以通过一般的 Cloudflare CDN IP 去访问 [mjjpgs.mahjongsoul.com]( http://mjjpgs.mahjongsoul.com) 服务器?

    说干就干,直接使用其他的 Cloudflare CDN IP 去访问

    $ curl 'https://mjjpgs.mahjongsoul.com:8443/api/v0/recommend_list?service=ws-gateway&protocol=ws&ssl=true' --resolve mjjpgs.mahjongsoul.com:8443:104.25.9.80 | jq
      % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                     Dload  Upload   Total   Spent    Left  Speed
    100    43  100    43    0     0    161      0 --:--:-- --:--:-- --:--:--   161
    
    {
      "servers": [
        "mjjpgs.mahjongsoul.com:9663"
      ]
    }
    

    结果符合预期,是可以通过正常连接的,那么有没有一种可能:

    如果服务器的管理员只是设置好了Specturm,导致正常途径情况下只能通过特定 IP 地址去链接,但是没有限制来源 IP 必须是 Cloudflare IP 呢?

    找寻

    顺着这个思路,只需要将可能的 IP 进行一次 SSL 证书验证和 Websocket 升级后成功,就是我们要找的游戏源服务器 IP 地址

    剩下就是猜他所使用的是哪家公有云了,尝试解析一下首页的 IP 的公有云归属

    $ nslookup www.mahjongsoul.com | nali
    
    2023/07/30 21:47:32 文件不存在,尝试从网络获取 ipv4.dat
    Downloading... 5251 KB / 5252 KB   
    2023/07/30 21:47:33 已将 ipv4.dat 保存到本地
    Server:         127.0.0.53 [局域网 IP]
    Address:        127.0.0.53 [局域网 IP]#53
    
    Non-authoritative answer:
    Name:   www.mahjongsoul.com
    Address: 47.245.38.201 [日本 东京阿里云]
    

    那么我们把目标转为阿里云旗下所属的 IP 域,我们可以直接通过 https://ipinfo.io/AS45102 来找到分配给阿里云的所有 IP 地址,接下来只需要找到符合要求的 IP 地址即可

    ipinfo.io 下载需要注册,我把具体的 CIDR 地址转换成文本文件并上传在在这了 如果你想自己从 ipinfo.io 下载并导出为文本,可以参考这个转换脚本

    接下来,就是验证的时刻了

    # 下载 Alicloud ip range
    $ curl https://gist.githubusercontent.com/charSLee013/66055696579ceda7066487c4c099cbda/raw/e325a32336f239c8ecf21b74ae450547d76f1683/ali_ips.txt --output ali_ips.txt
    
    # 开始执行
    $ go run main.go -port 9663 -file alicloud_netblocks.txt -num 10000 -host mjjpgs.mahjongsoul.com
    
    139.95.4.55
    47.252.21.16
    47.89.136.64
    All requests completed.
    
    

    使用 openssl 验证证书检验成果

    $ openssl s_client -connect 139.95.4.55:9663 -servername mjusgsbk.mahjongsoul.com < /dev/null 2>/dev/null | openssl x509 -text -noout |grep 'Subject: CN'
    
    Subject: CN = *.mahjongsoul.com
    

    结语

    以上就是我找寻隐藏在防火墙后面源 IP 地址的整个过程,一开始觉得都知道开启 Specturm 了,想必防御措施拉满,但没想到千里之堤,溃于蚁穴

    一直用于验证网站身份的 SSL 证书,成为了这次寻找中最大的帮手。 ;-)

    22 条回复    2023-08-26 23:55:39 +08:00
    zhengxinhn
        1
    zhengxinhn  
       2023-07-31 16:30:43 +08:00
    既然是 Websocket 你都猜到证书了不如直接去搜证书,可以免去扫描这一步。
    原来雀魂也是中国的游戏啊😂
    yyzh
        2
    yyzh  
       2023-07-31 16:41:29 +08:00
    charslee013
        3
    charslee013  
    OP
       2023-07-31 16:42:45 +08:00
    @zhengxinhn 问题就在这,搜到的证书都是 Cloudflare IP 的,我试了下在 fofa 还有 Censys 都没找到源 IP ,也有可能是我技术八行不会弄 😂
    1423
        4
    1423  
       2023-07-31 16:51:07 +08:00
    真的 6,主要是 www.mahjongsoul.com 暴露了阿里云,极大的减小了扫描范围
    另外想知道最后扫阿里云耗时多少?
    est
        5
    est  
       2023-07-31 16:54:02 +08:00
    是不是直接把公有云的 ip 跑一遍也能得到服务器 ip ?
    1423
        6
    1423  
       2023-07-31 16:58:25 +08:00


    censys 也查得到
    censys 这些好处是能保留一段历史,有过记录的服务器停掉后一段时间内仍然能查得到
    源站不看 sni 直接返回证书,可能觉得用了非常用端口就安全吧
    charslee013
        7
    charslee013  
    OP
       2023-07-31 17:05:53 +08:00
    @1423 我当时设置了 1 万并发,用了大概 5 小时左右?反正我是晚上睡觉前挂着扫,早上就能看到结果了

    @est 理论上确实可以,比如 0.0.0.0/0 就是全部 ipv4 的 IP 地址了,只是这样做有亿点点慢~

    @1423 少了 139.95.4.55 ,其他两个 IP 好像是以前老旧的日服和美服服务器绑定过域名有 DNS 记录
    139.95.4.55 这个 IP 确实是第一次发现,应该是设置了 Specturm 后隐藏了起来
    charslee013
        9
    charslee013  
    OP
       2023-07-31 17:19:52 +08:00
    @1423 淦!是我笨比了 QAQ
    zhengxinhn
        10
    zhengxinhn  
       2023-07-31 17:30:40 +08:00
    @charslee013 (services.tls.certificate.parsed.subject.common_name=*.mahjongsoul.com) and services.port=`9663` censys 一搜就是这 3 个 IP
    charslee013
        11
    charslee013  
    OP
       2023-07-31 17:50:16 +08:00
    @zhengxinhn 原来是匹配 *.mahjongsoul.com ,我一直以为是匹配全称的 mjusgsbk.mahjongsoul.com 😭
    tool2d
        12
    tool2d  
       2023-07-31 18:09:13 +08:00
    歪个楼,最近我服务器 443 端口,老是莫名 IP ,发送 name server = sparrow.cloudflare.com 来敲门。

    问题是我服务器也没用 Cloudflare 啊,封了一个 IP ,又来一个 IP 。而且是 24 小时不间断的敲门,真是晕死。

    OP 知道是啥原因吗?
    charslee013
        13
    charslee013  
    OP
       2023-07-31 19:31:49 +08:00   ❤️ 2
    @tool2d 有个可能原因是攻击者伪造了 sparrow.cloudflare.com 这个域名来掩盖他们的真实身份(cloudflare 官方有自己的 IP 范围不需要匿名 IP)

    如果你用的 nginx 作为网关,可以设置一个默认的 server block 用来处理没有匹配到任何 server name 的请求,比如下面这个写法

    server {
    listen 80 default_server; // 默认处理返回 403
    return 403;
    }

    server {
    listen 80;
    server_name www.example.com; // 你的域名
    ...
    }

    参考自 https://stackoverflow.com/questions/34301884/nginx-reverse-proxy-only-allow-connection-from-hostname-not-ip
    tool2d
        14
    tool2d  
       2023-07-31 22:08:12 +08:00
    @charslee013 感谢。我已经进行连接断开,搞不太懂对方为什么要需要不断重试。
    ZRS
        15
    ZRS  
       2023-07-31 22:20:10 +08:00 via iPhone
    一般来说和 cf 通信要用自签证书,扫全 v4 抓证书是个再常见不过的事,同时限定仅接受 CF IP 段的连入
    charslee013
        16
    charslee013  
    OP
       2023-07-31 23:08:51 +08:00
    @ZRS 这也是很多系统管理员的失误,认为特定端口+cloudflare CDN 就能阻挡侦测和攻击,殊不知还要限定仅 CF IP 段的连接才能万无一失
    huoshen
        17
    huoshen  
       2023-08-01 04:43:05 +08:00
    感觉这个思路见过,都是证书配置不当泄漏了 ip 。最好的做法还是防火墙仅允许特定的 ip 通过,然后把 cf 全段放进去,可以避免被扫描到
    huahsiung
        18
    huahsiung  
       2023-08-13 14:23:31 +08:00
    warp 应该 CF IP 段的,没试过,不过应该是 https://www.cloudflare.com/zh-cn/ips/


    @huoshen
    @ZRS
    @charslee013
    giaodadi
        19
    giaodadi  
       2023-08-13 18:14:02 +08:00
    @huahsiung warp 的 ip 不在这些 ip 段的
    charslee013
        20
    charslee013  
    OP
       2023-08-13 22:55:48 +08:00
    @huahsiung 在 cloudflare 的 [官方文档]( https://developers.cloudflare.com/cloudflare-one/connections/connect-devices/warp/deployment/firewall/#warp-ingress-ip) 中可以知道 warp+的 IP 范围是

    * 162.159.192.0/24(未通过验证)
    * 162.159.193.0/24(通过验证)

    这两个 IP 段都不在常规的 IP range 中,但是都在 cloudflare AS13335 自治域中,cloudflare 的 IP 地址都可以在这个文件找到 https://gist.github.com/charSLee013/bed03a5de5855ee1f66d519f9cd061af
    huahsiung
        21
    huahsiung  
       2023-08-14 15:36:47 +08:00
    @giaodadi
    @charslee013

    这个是 WARP client will connect IP

    使用 warp 双栈测试了一下,https://i.niupic.com/images/2023/08/14/bApc.JPG

    IPv4 大部分命中该段,https://gist.github.com/charSLee013/bed03a5de5855ee1f66d519f9cd061af

    ipv6 全部没有命中( 2a09:),可能是 IPv6 够多,足够区分使用。而 IPv4 太少了,有一些 IPv4 就复用了
    giaodadi
        22
    giaodadi  
       2023-08-26 23:55:39 +08:00
    @huahsiung
    WARP 的 IP 会命中
    https://www.cloudflare.com/zh-cn/ips/
    这里面的 IP 吗
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2504 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 01:32 · PVG 09:32 · LAX 17:32 · JFK 20:32
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.