反向解析公共IP- 这里没有问题
Tl; dr:有些域名名称服务器可能会在直接查询反向解析私有IP时暴露内部的IP地址和域名。用dig -x检查一下,或者使用privdns.py 检查一下。
一个简单的错误
我最近犯了一个很小且看似不重要的错误:我试图连接某个公司的基础设施的服务器,但没有登录到他们的VPN。这看起来很无聊,你可能会觉得,这样的事情每天都在发生。但几个小时后,我正在编写Python代码,并且在大量扫描互联网上的DNS服务器。即使我最终没有取得成功(从安全的角度来看这是很好的结果),但这仍然是一个有趣的实验。那么到底发生了什么事。
当我试图ping内部公司的服务器时,我得到了下面的回应:
- michael@seventysix:~ ping internal-db1.example.com
- PING internal-db1.example.com (10.0.0.1) 56(84) bytes of data.
- ^C
- --- internal-db1.example.com ping statistics ---
- 3 packets transmitted, 0 received, 100% packet loss, time 2014ms
当然,结果显示超时了。但注意一些事情:域名已经被正确解析。即使我没有登录到VPN,我仍然可以解决内部域名。为了确保这不是由于某个DNS缓存造成的,我尝试从云集群中未曾登录到公司网络并使用不同名称服务器的虚拟机中重现此操作,并得到了相同的结果。
为了理解这背后的事情为什么这么有趣,这里有一些关于IP地址和DNS的背景知识。
内部,外部IP和DNS
IPv4和IPv6地址空间分为私有和公有IP。以下网络是私有的:
- 10.0.0.0/8
- 172.16.0.0/12
- 192.168.0.0/16
- FC00 :: / 7
例如,在你的家庭网络或公司内部网络中使用专用IP。如果你在内部网络中处理公司服务器,他们通常具有上述范围内的IP。
为了连接名称服务器和IP地址,我们使用DNS(域名服务)。DNS服务器(或“域名服务器”)是将域名example.com翻译成IP的服务器。老知识,到目前为止,你很可能知道这一点。内部公司网络中使用的是同样的东西:你不必记住10.0.0.1内部数据库服务器的IP,而是使用DNS将域名internal-db1.example.com 翻译成私有IP,例如10.0.0.1。因此,当你的普通Windows桌面客户端尝试连接到数据库服务器时,它会要求DNS服务器将该域名解析为internal-db1.example.com可以与之通信的IP。(如果你想了解更多关于DNS的信息,我鼓励你从伟大的互联网上观看这个漂亮,简洁的视频 —— 那个人不是我哦:)
https://youtu.be/4ZtFk2dtqv0
在一些公司中,管理内部IP的域名的同一DNS服务器同时也管理着其公共IP的域名,例如他们网站的域名。请求“谁是www.example.com”和“谁是internal-db1.example.com”,都是从同一个DNS服务器 —— 即公司的DNS服务器来问询ns1.example.com。这就是我刚才遇到的那种情况,ns1.example.com是为解决内部和 外部IP 而设立的名称服务器。只是这台名称服务器不在乎请求解析域名的IP地址是来自公司的内部网络还是外部,所以它响应了我的请求。
- => "Who is internal-db1.example.com"?
响应:
- <= "Hey, it's 10.0.0.1",
不用担心它是通过内部地址来响应来自公司网络之外的DNS请求。
使这一事件成为可能的另一个要求是该公司使用了相同的域名来服务内部和外部。假设他们的网站被命名为:
· www.example.com。
内部数据库服务器被命名为:
· internal-db1.example.com。
在ping internal-db1.example.com时,我并没有明确地查询这个公司的DNS,因为我家的DNS被设置为使用不同的DNS(假设它是Google的DNS)。由于DNS具有分布式结构,如果Google的DNS想要获取www.example.com的IP ,它首先会要求其中一个根DNS服务器负责跟踪谁负责第二级域名example.com。已联系的根服务器会使用域名ns1.example.com的IP作为域名example.com的授权服务器来响应Google的DNS 。然后谷歌的DNS请求ns1.example.com解析internal-db1.example.com并收到它最终转给我们的响应也就是我们上面看到的内部IP。如果有内部域名internal-db1.example.local,Google的DNS就不会知道是谁要求顶级域名(.local),因为注册的公司example.com没有注册(也不能)example.local。
想一想:在这一点上,Google的DNS知道公司的内部域名和相应的IP。而互联网上查询的其他所有DNS服务器internal-db1.example.com都会知道同样的事情。乍一看并不是什么大不了的事情,但是作为一个试图保护这个基础设施的人,我希望你们仍然能够明白这一点。
一个小的信息泄漏
显然,我现在可以通过询问任何公共DNS来解析公司的内部域名。更让人感兴趣的是许多公司都可以用来枚举服务器:
- db1-internal.company.com
- db2-internal.company.com
- db3-internal.company.com
等等 - 这意味着如果你知道一个服务器的名称,那么你可以猜测其他服务器的名称。当然,你也可以尝试爆破域名名称,也许是dev-internal.company.com或log-internal.company.com。这里的泄露信息的问题在于,你可以爆破内部域名,并检查公司网络中是否有这些名称的机器,检索内部IP 而不登录到网络。但是,你仍然需要暴力域名名称。(是的,有工具可以做到这一点。)
一个更严重的信息泄漏问题
如果你对网络,IP和DNS有所了解,你可能会猜测我的下一步是什么。许多人基本上知道DNS是如何工作的。人们所知道的是,你不仅可以将一个域名解析为一个IP地址,而且还可以反过来:给定一个IP地址,你可以将其解析为一个域名。与正向DNS相反,这被称为反向解析或反向DNS,并且通过查询特定ARPA域的PTR记录的DNS来完成。如果你想反向解析一个给定的IP,你必须扭转IP地址,并添加一个特殊的域名,比如in-addr.arpa.net域名。例如,为了解析IP 1.2.3.4对应的域名,你需要要求你的名称服务器寻找一条记录是
- 4.3.2.1.in-addr.arpa.net
的PTR类型(与正向解析域名时的类A 的IPv4 或类型为AAAA的IPv6地址相比)。
当你“拥有”一个IP 1.2.3.4(意味着它是在IANA注册的)时,你可以为相应的域名指定一个权威的域名服务器,4.3.2.1.in-addr.arpa.net并且在该域名服务器上配置一条PTR记录,该记录指向一个指定的域名。如果有人试图反向解析1.2.3.4,他会被重定向到你的域名服务器并寻找PTR条目。(即使将多个域名连接到相同的服务器,你也只能将一个域名附加到IP地址。)
所以回到公司的域名example.com上来。如果我不仅能得到一个域名的IP地址,而且可以相反的操作,那么有没有办法来检查一个内部IP地址是否有一个域名与之相关联呢?我可以只对私有IP空间进行反向查询吗?这会让事情变得更有趣。如果可能的话,我可以简单地开始迭代枚举私有IP空间,检查每个IP是否有注册的PTR记录,通过这种方式可以获得大量有关公司内部网络的信息 -——IP地址,域名以及我可以从中得到的所有信息。
由于DNS的结构,简单地反向解析IP是不起作用的:反向解析意味着你的默认域名服务器(例如Google)需要寻找到1.0.0.10.in-addr.arpa.net的内部IP地址。由于没有人可以拥有该IP并将其域名服务器指定为权威服务器,因此IANA不允许你在此处输入条目,因此Google的DNS将无法处理该IP的反向DNS查询,因为它使用company.com是做不到的。它不会像在域名解析的情况下那样尝试联系我们公司的DNS,因为它不知道我们公司的DNS将自己视为了这个内部IP的权威服务器。
但是 - 如果我直接联系公司的域名服务器,询问能否为我解析1.0.0.10.in-addr.arpa.net,那么这时会发生什么?在这之间没有谷歌DNS是不知道该怎么做的。尽管这样做是没有意义的,但是尽管不能在IANA上注册私有IP,但是这不会阻止DNS管理员会在他的服务器上自己配置反向解析,对吧?
该公司的名称服务器并没有让人失望:
- michael@seventysix:~ dig -x 10.0.0.1 @ns1.example.com
- ; <<>> DiG 9.10.3-P4-Ubuntu <<>> -x 10.0.0.1 @ns1.example.com
- ;; global options: +cmd
- ;; Got answer:;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 6077;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1;; WARNING: recursion requested but not available
- ;; OPT PSEUDOSECTION:; EDNS: version: 0, flags:; udp: 4096;; QUESTION SECTION:;1.0.0.10.in-addr.arpa. IN PTR
- ;; ANSWER SECTION:1.0.0.10.in-addr.arpa. 3600 IN PTR internal-db1.example.com.
- ;; Query time: 16 msec
- ;; SERVER: XXX.XXX.XXX.XXX#53(XXX.XXX.XXX.XXX);; WHEN: Wed Jan 21 14:37:49 CET 2018;; MSG SIZE rcvd: 110
你看到那个美丽的“ANSWER ”部分了吗?没错。我们通过公司的域名服务器来解析内部IP。现在事情变得非常有趣,因为没有什么能阻止我迭代枚举整个私有的IPv4地址空间,通过外部可访问的DNS服务器从网络外部来解决公司网络的每个IP地址。这是最纯粹的乐趣。
自动化所有的东西
我现在所需要的是一个脚本,它可以遍历私有IP地址空间,来获取该公司的所有内部域名和IP地址。由于配置不当的DNS,导致了一个简单而又简单的信息泄漏。(后来有人告诉我,DNS实际上并不是“错误配置”的,但这完全是为了克服一些VPN DNS解析问题。要真正获得这种反向IP地址解析,通常需要设置一个适当的zonefile,这意味着必须显式地配置它,来反向解析内部IP。无论如何,至少在几个小时后,本文中这个反向解析的问题已经被修复了。)
在发现了这个缺陷之后,我也很想知道它有多普遍,以及有多少DNS管理员应用了类似的配置。我编写了一个python脚本,用于对给定的名称服务器的每个私有网络范围的前15个主机进行反向查询,并开始对域名服务器进行扫描。使用masscan发生了一些麻烦,处理了麻烦之后 (最终效果很好),我从Shodan下载了大约20.000 DNS服务器的列表,并在周末进行了检查。这些结果并不引人注目,但也有一些有趣的结果。我通知了一些受影响的公司,但也发现了一些私有的路由器(大多是Broadcom),这些公司透露了诸如“迈克尔的iPhone”或惠普打印机、亚马逊之类的名称。
- michael@seventysix ~/privdns % ./privdns.py XXX.XXX.XXX.XXX 10.0.0.0/8
- [*] Checking nameserver XXX.XXX.XXX.XXX
- [+] 10.0.0.1 : E***.net.
- [+] 10.0.0.2 : P***.net.
- [+] 10.0.0.3 : A***.net.
- [+] 10.0.0.4 : A***.net.
- [+] 10.0.0.5 : E***.net.
- [+] 10.0.0.6 : E***.net.
- [+] 10.0.0.7 : P***.net.
- [+] 10.0.0.8 : P***.net.
- [+] 10.0.0.9 : E***.net.
- [+] 10.0.0.10 : P***.net.
- [+] 10.0.0.11 : a***.net.
- [.] Resolved but no entry for 10.0.0.12
- ...
如果你想自己玩的话,你可以在我的GitHub上找到这个脚本。毕竟,这只是一个信息泄露,而我所看到的并不是太常见。据我所知,它还需要一个特定的DNS配置。
- privdns.py
就是这样。这是一个关于如何在一个公司的DNS中解析私有IP地址时,泄露他们的基础设施和IP的故事,并且没有特别的复杂的黑客攻击和利用技术。