公众号旧文

如何根据 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

很多初学者习惯看到一个开放端口,就直接认定服务器运行了某种服务。

实际上,真正可靠的方法并不是猜,而是不断验证。

端口扫描告诉我们的,只是可能是什么;

协议交互才能证明真正是什么。

扩展阅读:

无需申请,即可使用:免费二级域名正式开放