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

2023-07-31 16:14:39 +08:00
 charslee013

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

起因

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

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

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

首先该程序会向 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 请求,具体代码在这

程序的逻辑如下:

  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>

这里我们准备一份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 反向代理了请求连接到源服务器

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

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

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

整体效果图如下

路转

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

换了一个 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 证书,成为了这次寻找中最大的帮手。 ;-)

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


censys 也查得到
censys 这些好处是能保留一段历史,有过记录的服务器停掉后一段时间内仍然能查得到
源站不看 sni 直接返回证书,可能觉得用了非常用端口就安全吧
charslee013
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 后隐藏了起来
1423
2023-07-31 17:08:56 +08:00
charslee013
2023-07-31 17:19:52 +08:00
@1423 淦!是我笨比了 QAQ
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
2023-07-31 17:50:16 +08:00
@zhengxinhn 原来是匹配 *.mahjongsoul.com ,我一直以为是匹配全称的 mjusgsbk.mahjongsoul.com 😭
tool2d
2023-07-31 18:09:13 +08:00
歪个楼,最近我服务器 443 端口,老是莫名 IP ,发送 name server = sparrow.cloudflare.com 来敲门。

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

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


@huoshen
@ZRS
@charslee013
giaodadi
2023-08-13 18:14:02 +08:00
@huahsiung warp 的 ip 不在这些 ip 段的
charslee013
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

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/961230

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX