闲逛的时候看有个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 请求,具体代码在这
程序的逻辑如下:
Http code 101
表示切换协议成功程序的选项如下所示
# 你可以指定 IP 地址,或者输入一个只包含 IP 地址或者 CIDR 域的文件
Usage: go run main.go -ip <IP> -port <Port> -file <FileName> -num <Number> -host <HostName>
-file
一起使用,但必须至少选择一个-ip
一起使用,但必须至少选择一个这里我们准备一份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 证书,成为了这次寻找中最大的帮手。 ;-)
1
zhengxinhn 2023-07-31 16:30:43 +08:00
既然是 Websocket 你都猜到证书了不如直接去搜证书,可以免去扫描这一步。
原来雀魂也是中国的游戏啊😂 |
2
yyzh 2023-07-31 16:41:29 +08:00
|
3
charslee013 OP @zhengxinhn 问题就在这,搜到的证书都是 Cloudflare IP 的,我试了下在 fofa 还有 Censys 都没找到源 IP ,也有可能是我技术八行不会弄 😂
|
4
1423 2023-07-31 16:51:07 +08:00
真的 6,主要是 www.mahjongsoul.com 暴露了阿里云,极大的减小了扫描范围
另外想知道最后扫阿里云耗时多少? |
5
est 2023-07-31 16:54:02 +08:00
是不是直接把公有云的 ip 跑一遍也能得到服务器 ip ?
|
6
1423 2023-07-31 16:58:25 +08:00
|
7
charslee013 OP |
8
1423 2023-07-31 17:08:56 +08:00
|
9
charslee013 OP @1423 淦!是我笨比了 QAQ
|
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
|
11
charslee013 OP @zhengxinhn 原来是匹配 *.mahjongsoul.com ,我一直以为是匹配全称的 mjusgsbk.mahjongsoul.com 😭
|
12
tool2d 2023-07-31 18:09:13 +08:00
歪个楼,最近我服务器 443 端口,老是莫名 IP ,发送 name server = sparrow.cloudflare.com 来敲门。
问题是我服务器也没用 Cloudflare 啊,封了一个 IP ,又来一个 IP 。而且是 24 小时不间断的敲门,真是晕死。 OP 知道是啥原因吗? |
13
charslee013 OP @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 |
14
tool2d 2023-07-31 22:08:12 +08:00
@charslee013 感谢。我已经进行连接断开,搞不太懂对方为什么要需要不断重试。
|
15
ZRS 2023-07-31 22:20:10 +08:00 via iPhone
一般来说和 cf 通信要用自签证书,扫全 v4 抓证书是个再常见不过的事,同时限定仅接受 CF IP 段的连入
|
16
charslee013 OP @ZRS 这也是很多系统管理员的失误,认为特定端口+cloudflare CDN 就能阻挡侦测和攻击,殊不知还要限定仅 CF IP 段的连接才能万无一失
|
17
huoshen 2023-08-01 04:43:05 +08:00
感觉这个思路见过,都是证书配置不当泄漏了 ip 。最好的做法还是防火墙仅允许特定的 ip 通过,然后把 cf 全段放进去,可以避免被扫描到
|
18
huahsiung 2023-08-13 14:23:31 +08:00
|
20
charslee013 OP @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 |
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 就复用了 |
22
giaodadi 2023-08-26 23:55:39 +08:00
|