公众号旧文
如何根据 IP 反推出服务器运行了什么服务?
现在有一台服务器,我们只知道它的公网 IP:
45.8.173.18
除此之外,一无所知。
不能登录服务器,也不知道里面安装了什么软件。
那么,仅凭这个 IP,能推断出服务器上运行了哪些服务吗?
答案是:可以。
下面,我们就一步一步进行推理。
第一步:扫描 TCP 端口
首先,使用 nmap 扫描 TCP 端口:
nmap 45.8.173.18
得到结果:
PORT STATE SERVICE
22/tcp open ssh
53/tcp open domain
很多人看到这里,就会说:
这台服务器运行着 SSH 和 DNS。
但这个结论下得太早了。
因为 nmap 显示的 SERVICE,并不是服务器主动告诉你的。
它只是根据端口号,查询端口数据库后,给出的一个常见用途。
例如:
- 22 通常用于 SSH
- 80 通常用于 HTTP
- 443 通常用于 HTTPS
- 25 通常用于 SMTP
- 53 通常用于 DNS
所以 53/tcp open domain
只代表 TCP 53 端口开放,而 53 端口通常用于 DNS。
这里是通常,并不是一定。
理论上,任何程序都可以监听 53 端口。
也就是说,开放 53,不代表一定运行着 DNS。
目前,我们只能提出第一个假设:
这台服务器,很可能运行着 DNS。
但注意,仅仅是可能。
第二步:继续扫描 UDP
DNS 有一个特点:
不仅使用 TCP,更多的时候,使用的是 UDP。
于是继续扫描 UDP:
nmap -sU 45.8.173.18
得到结果:
PORT STATE SERVICE
53/udp open domain
现在,证据又增加了一条。
53 的 TCP 开放。
53 的 UDP 也开放。
对于 DNS 来说,这是非常常见的工作方式。
因此,服务器运行 DNS 的可能性进一步提高。
但是,依然不能下结论。
因为理论上,一个程序完全可以同时监听:
- TCP 53
- UDP 53
却仍然不是 DNS。
所以到目前为止,我们真正能够确定的事实只有:
有一个程序,同时占用了 TCP/53 和 UDP/53。
至于它是不是 DNS,还需要继续验证。
第三步:不要猜,直接按照 DNS 协议通信
既然怀疑它是 DNS,那最好的办法,就是:
按照 DNS 协议,与它进行一次真正的通信。
使用 dig:
dig @45.8.173.18 ns1.851004721.xyz
服务器返回:
ANSWER SECTION: ns1.851004721.xyz. 60 IN A 45.8.173.18
这时候,我们终于可以确定:
这台服务器,确实运行着 DNS。
因为如果它不是 DNS,它根本无法理解 DNS Query。
更不可能按照 DNS 协议,返回一个合法的 DNS Response。
至此,53 端口是 DNS
已经不再是猜测。
而是经过协议验证后的事实。
第四步:新的问题来了
知道它是 DNS。
并不代表知道它负责什么。
公共 DNS,例如:
8.8.8.8
可以帮你查询几乎所有域名。
但是一台权威 DNS。
可能只负责一个域名。
例如:
851004721.xyz
除此之外,其它域名,它根本不会回答。
所以新的问题来了:
它负责哪些域名?
第五步:DNS 并不会主动告诉你
有没有一个命令,可以让 DNS 把管理的所有域名列出来?
答案是:没有。
DNS 协议本身,并没有这样的功能。
否则,任何人都可以轻松枚举一台 DNS 服务器管理的所有域名。
显然,这样的设计并不合理。
所以如果不知道服务器负责哪个域名,很难直接推断出来。
第六步:利用已有信息继续推理
现实中,通常会根据已有信息继续验证。
例如,我们已经知道目标域名是:
851004721.xyz
于是直接查询:
dig @45.8.173.18 ns1.851004721.xyz
返回:
flags: qr aa rd;
其中:
aa
表示:
Authoritative Answer(权威回答)
这意味着,这台服务器,就是这个域名的权威 DNS。
继续观察,还能看到:
WARNING: recursion requested but not available
这不是报错,而是 dig 默认希望服务器帮它递归查询。
服务器回答:我不提供递归解析。
这恰恰符合一台标准权威 DNS 的行为。
因为权威 DNS 的职责,就是回答自己负责的域名。
而不是替别人查询整个互联网。
第七步:验证根域名是否存在记录
继续查询:
dig @45.8.173.18 851004721.xyz
返回:
status: NOERROR ANSWER: 0
为什么是 NOERROR,却没有任何记录?
因为 NOERROR 不是找到记录,而是查询成功。
只不过:
851004721.xyz
目前没有 A 记录。
因此:
ANSWER: 0
如果服务器根本不知道这个域名。
通常会返回:
NXDOMAIN
也就是说:
服务器已经知道:
851004721.xyz
这个 Zone 存在。
只是没有配置根域名的 A 记录。
如果完全不知道域名怎么办?
如果我们只有一个 DNS 服务器的 IP,完全不知道服务器负责哪个域名。
现实中通常有几种办法:
第一,根据公开信息寻找线索。
例如网站、证书、文档、Whois、NS 记录等,都可能暴露服务器负责的域名。
第二,如果已经知道某个域名。
可以查询它的 NS:
dig NS example.com
再解析 NS 对应的 IP。
如果 IP 与目标一致。
那么基本可以确认:
这台服务器,就是这个域名的权威 DNS。
第三,尝试 Zone Transfer(AXFR):
dig AXFR example.com @服务器IP
如果管理员误开放了区域传送。
那么整个 Zone 的所有记录都会直接返回。
不过,现在绝大多数权威 DNS 都默认禁止 AXFR,因此通常会被拒绝。
总结
整个推理过程,就是一个不断提出假设、不断验证假设的过程。
得到一个陌生 IP
│
▼
扫描 TCP 端口
│
▼
发现 TCP/53 开放
│
▼
继续扫描 UDP
│
▼
发现 UDP/53 也开放
│
▼
怀疑运行 DNS
│
▼
使用 dig 按 DNS 协议通信
│
▼
确认它是真正的 DNS 服务
│
▼
继续验证它负责哪些域名
│
▼
确认它是一台权威 DNS
很多初学者习惯看到一个开放端口,就直接认定服务器运行了某种服务。
实际上,真正可靠的方法并不是猜,而是不断验证。
端口扫描告诉我们的,只是可能是什么;
协议交互才能证明真正是什么。
扩展阅读: