Blog

关于 GFW 主动探测 HTTP 服务器的规律的研究

发布时间: ,大约 1200 字 ,阅读时间:6 分钟,

近日在整理 HTTP 服务器日志的时候,我发现了一些非常奇怪的内容,例如:

$ cat access.log | grep wujieliulan
111.85.179.42 - - [22/Jul/2018:15:59:49 +0000] "GET http://wujieliulan.com/mnews.htm HTTP/1.1" 404 571 "-" "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)"
182.110.30.8 - - [26/Jul/2018:19:33:24 +0000] "GET http://wujieliulan.com/mnews.htm HTTP/1.1" 404 571 "-" "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)"
117.14.156.234 - - [26/Jul/2018:22:14:56 +0000] "GET http://wujieliulan.com/mnews.htm HTTP/1.1" 404 571 "-" "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)"
124.66.8.120 - - [27/Jul/2018:15:34:07 +0000] "GET http://wujieliulan.com/mnews.htm HTTP/1.1" 404 571 "-" "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)"
117.43.152.214 - - [27/Jul/2018:20:07:21 +0000] "GET http://wujieliulan.com/mnews.htm HTTP/1.1" 404 571 "-" "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)"
106.45.8.28 - - [28/Jul/2018:10:37:33 +0000] "GET http://wujieliulan.com/mnews.htm HTTP/1.1" 404 571 "-" "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)"
106.91.210.17 - - [30/Jul/2018:13:10:03 +0000] "GET http://wujieliulan.com/mnews.htm HTTP/1.1" 404 571 "-" "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)"
1.30.24.232 - - [30/Jul/2018:19:32:10 +0000] "GET http://wujieliulan.com/mnews.htm HTTP/1.1" 404 571 "-" "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)"
150.255.186.243 - - [31/Jul/2018:14:26:55 +0000] "GET http://wujieliulan.com/mnews.htm HTTP/1.1" 404 571 "-" "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)"
1.189.164.182 - - [31/Jul/2018:17:18:01 +0000] "GET http://wujieliulan.com/mnews.htm HTTP/1.1" 404 571 "-" "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)"
60.13.136.57 - - [01/Aug/2018:08:12:52 +0000] "GET http://g.wujieliulan.com/mnews.htm HTTP/1.1" 404 571 "-" "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)"
110.84.210.134 - - [01/Aug/2018:18:37:24 +0000] "GET http://wujieliulan.com/mnews.htm HTTP/1.1" 404 571 "-" "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)"
120.40.115.232 - - [02/Aug/2018:03:27:47 +0000] "GET http://wujieliulan.com/mnews.htm HTTP/1.1" 404 571 "-" "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)"
123.191.135.13 - - [02/Aug/2018:07:27:40 +0000] "GET http://wujieliulan.com/mnews.htm HTTP/1.1" 404 571 "-" "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)"
106.45.9.143 - - [02/Aug/2018:11:55:50 +0000] "GET http://wujieliulan.com/mnews.htm HTTP/1.1" 404 571 "-" "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)"
116.113.15.243 - - [03/Aug/2018:01:43:16 +0000] "GET http://wujieliulan.com/mnews.htm HTTP/1.1" 404 571 "-" "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)"
106.45.8.72 - - [03/Aug/2018:18:40:17 +0000] "GET http://wujieliulan.com/mnews.htm HTTP/1.1" 404 571 "-" "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)"
112.66.68.196 - - [04/Aug/2018:18:11:33 +0000] "GET http://wujieliulan.com/mnews.htm HTTP/1.1" 404 571 "-" "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)"
171.37.179.176 - - [05/Aug/2018:00:06:31 +0000] "GET http://wujieliulan.com/mnews.htm HTTP/1.1" 404 571 "-" "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)"
111.85.179.127 - - [05/Aug/2018:13:01:32 +0000] "GET http://wujieliulan.com/mnews.htm HTTP/1.1" 404 571 "-" "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)"

这些请求可以看出,是扫描器在探测 HTTP 代理。 但这里有一点很奇怪:这些 IP 的来源基本上都来自中国大陆境内, 但是中国大陆境内的 GFW 应当把这个网站屏蔽了才对。

随后,我对这些记录进行了深入的研究, 发现它们都出现在中国大陆 IP 访问过后大约 1-120 秒内。 网络上的搜索结果也印证了这些猜想

与此同时,我发现了另一些日志, 这些日志使用了内部服务器代号命名的域名作为主机头, 但我从未向任何人(除 DNS 服务提供商和我自己)暴露过这些域名, 这些日志类似于这些:

[我的 IP] - - [07/Aug/2018:18:40:53 +0000] "GET / HTTP/1.1" 内部服务器代号.example.com 0.000 471 200 165 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64)
AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36" - -
110.167.93.42 - - [07/Aug/2018:18:40:54 +0000] "GET /loading.gif HTTP/1.1" 内部服务器代号.example.com 0.000 221 200 217 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0" - -
[我的 IP] - - [07/Aug/2018:18:40:54 +0000] "GET /favicon.ico HTTP/1.1" 内部服务器代号.example.com 0.000 455 200 217 "https://内部服务器代号.example.com/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36" - -
110.167.93.42 - - [07/Aug/2018:18:40:58 +0000] "GET / HTTP/1.1" 内部服务器代号.example.com 0.000 199 200 165 "-" "Mozilla/5.0 (Windows NT 6.1; Trident/7.0; rv:11.0) like Gecko" - -
110.167.93.42 - - [07/Aug/2018:18:40:59 +0000] "GET /loading.gif HTTP/1.1" 内部服务器代号.example.com 0.000 210 200 217 "-" "Mozilla/5.0 (Windows NT 6.1; Trident/7.0; rv:11.0) like Gecko" - -
[我的 IP] - - [07/Aug/2018:18:41:02 +0000] "GET / HTTP/1.1" 内部服务器代号.example.com 0.000 471 200 165 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36" - -
[我的 IP] - - [07/Aug/2018:18:41:02 +0000] "GET /favicon.ico HTTP/1.1" 内部服务器代号.example.com 0.000 455 200 217 "https://内部服务器代号.example.com/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36" - -
110.167.93.42 - - [07/Aug/2018:18:41:04 +0000] "GET / HTTP/1.1" 内部服务器代号.example.com 0.000 240 200 165 "-" "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36" - -
1.28.91.56 - - [07/Aug/2018:18:41:13 +0000] "GET http://wujieliulan.com/mnews.htm HTTP/1.1" wujieliulan.com 0.000 249 200 217 "-" "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)" - -

但我触发 GFW 爬虫通过的是 HTTPS 而不是 HTTP 来访问。 这就非常奇怪了,我使用的证书是自签名证书, Common Name 是 localhost,签名算法是 SHA256RSA,密钥长度是 2048, 证书也没有遭到篡改,可 GFW 却拿到了我的 Host 值, 难不成现在的 GFW 还能破译 HTTPS 里面的加密流量(不可能的)了?

于是我假设了下面两种可能性:

  1. GFW 通过用户请求的 DNS 包来反向分析出对应 IP 所使用的域名
  2. GFW 通过用户在跳转到 HTTPS 网站之前的 HTTP 301 包来反向分析出对应 IP 所使用的域名

随后我对 GFW 爬虫的行为进行了研究,但很长一段时间都没有发现结果。 当我准备放弃研究时突然发现有一个国内的网络服务扫描器扫到了我的机器上,日志如下:

# HTTP ATTACK LOG
115.29.223.75 - - [07/Aug/2018:17:28:31 +0000] "HEAD / HTTP/1.1" [我的服务器的IP] 0.000 41 200 0 "-" "-" - -
110.177.73.76 - - [07/Aug/2018:17:29:00 +0000] "GET /favicon.ico HTTP/1.1" [我的服务器的IP] 0.000 244 200 217 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36" - -
110.177.73.76 - - [07/Aug/2018:17:29:00 +0000] "GET /view/img/favicon.ico HTTP/1.1" [我的服务器的IP] 0.000 215 200 217 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0" - -
110.177.73.76 - - [07/Aug/2018:17:29:01 +0000] "GET /home/favicon.ico HTTP/1.1" [我的服务器的IP] 0.000 241 200 217 "-" "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36" - -
110.177.73.76 - - [07/Aug/2018:17:29:02 +0000] "GET /2/favicon.ico HTTP/1.1" [我的服务器的IP] 0.000 238 200 217 "-" "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36" - -
110.177.73.76 - - [07/Aug/2018:17:29:03 +0000] "GET /3/favicon.ico HTTP/1.1" [我的服务器的IP] 0.000 197 200 217 "-" "Mozilla/5.0 (Windows NT 6.1; Trident/7.0; rv:11.0) like Gecko" - -
110.177.73.76 - - [07/Aug/2018:17:29:07 +0000] "GET / HTTP/1.1" [我的服务器的IP] 0.000 225 200 165 "-" "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36" - -

# HTTPS ATTACK LOG
110.177.73.76 - - [07/Aug/2018:17:29:09 +0000] "GET /favicon.ico HTTP/1.1" [我的服务器的IP] 0.000 195 200 217 "-" "Mozilla/5.0 (Windows NT 6.1; Trident/7.0; rv:11.0) like Gecko" - -
110.177.73.76 - - [07/Aug/2018:17:29:11 +0000] "GET /view/img/favicon.ico HTTP/1.1" [我的服务器的IP] 0.000 253 200 217 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36" - -
110.177.73.76 - - [07/Aug/2018:17:29:12 +0000] "GET /home/favicon.ico HTTP/1.1" [我的服务器的IP] 0.000 249 200 217 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36" - -
221.0.20.15 - - [07/Aug/2018:17:29:13 +0000] "GET http://wujieliulan.com/mnews.htm HTTP/1.1" wujieliulan.com 0.000 249 200 217 "-" "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)" - -
110.177.73.76 - - [07/Aug/2018:17:29:14 +0000] "GET /2/favicon.ico HTTP/1.1" [我的服务器的IP] 0.000 237 200 217 "-" "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36" - -
110.177.73.76 - - [07/Aug/2018:17:29:16 +0000] "GET /3/favicon.ico HTTP/1.1" [我的服务器的IP] 0.000 208 200 217 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0" - -
110.177.73.76 - - [07/Aug/2018:17:29:21 +0000] "GET / HTTP/1.1" [我的服务器的IP] 0.000 184 200 165 "-" "Mozilla/5.0 (Windows NT 6.1; Trident/7.0; rv:11.0) like Gecko" - -

115.29.223.75 即网络服务扫描器的 IP。

从日志上可以看出,网络服务扫描器 使用了我的 IP 作为 Host 头,所以可以判断出 GFW 是通过用户在跳转到 HTTPS 网站之前的 HTTP 包来反向分析出对应 IP 所使用的域名的。 这也说明了 GFW 并不能解密 HTTPS 包。

由于其中包含了 Firefox 45 的 User-Agent,所以我猜测这种新式的爬虫大概在 2016 年的时候开发的。

从这个 GFW 爬虫的行为上看,它只抓取各种地方的 favicon.ico 和首页,其意义不明。

总结

我猜测的 GFW 爬虫的行为:

  1. 用户访问网站
  2. 将用户访问的网站加入 GFW 爬虫的处理队列
  3. GFW 爬虫随机抽取一些规则访问网站
  4. 将网站加入一段时间的白名单
  5. 如此循环

其中用户使用的 Host 值也会进行缓存,缓存至少 10 分钟

2018-12-2 更新

最近,我发现了 GFW 不仅会获取 HTTP 包的 Host 值, 还会通过 TLS 包中的 SNI 值来获取域名。

gfw-get-domain-via-tls.png

如图所示,我通过 cURL 访问了我之前搭建的一个 ownCloud 服务的域名, 在一分钟内,就有数个中国大陆境内的 IP 通过 CloudFlare 访问我的存储服务。 因为这个存储服务只有我一个人用,能做到这种精确程度的,我觉得只有运营商或者 GFW 了。

我还整理了一下 GFW Bots 所使用的 User-Agent ,主要几个在下面列出:

Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36
Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36
Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36
Mozilla/5.0 (Windows NT 10.0; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0
Mozilla/5.0 (Windows NT 6.1; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0
Mozilla/5.0 (Windows NT 6.1; Trident/7.0; rv:11.0) like Gecko

License

如未明确声明,所有文章皆以

知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。如果您需要商用,您可以通过电子邮件( [email protected] )联系。