.int或者 international顶级域名或许是互联网上提供的最“高档”的一个扩展。
子域名的数量太少,根据维基百科的信息,截止 2012 年 6 月,其一共有 166 个子域名。根据介绍,大约 27 年前,这个域名的主要目的还是为国际条约组织服务。对 .int域名的要求列在互联网数字分配机构(IANA)的网站上,摘录如下:
必须是各国政府之间缔结的一项国际条约。我们应该可以在联合国的国际条约数据库中查询得到,或者你应该给我们一个实际条约的可核实副本。请确保你提供的是一个条约,而不是某个组织的章程或内部规章细则。我们认识到在.int顶级域名下的子域名应该是合格的机构,尤其是联合国的专门机构,这个组织应该在联合国大会有观察员地位。条约必须建立一个组织来提交对 .int域名的申请。这个组织必须由条约本身确立,而不是类似理事会等机构的决定。所建立的组织必须根据国际法主体,被广泛认为是具有独立的国际法律法人。宣言或条约必须创建组织。如果这个组织是由秘书处创建的,它必须要有法人。例如,它必须能够签订合同、成为法律诉讼的一方。
这些要求都不低,就算某个国家极度渴望,也不可能有单一的国家可以对 .int域名进行注册。尽管如此,也有一些例外情况。如 YMCA (基督教青年会)就拥有 .int域名,由于它在有这些条件限制之前就拥有了这个域名。但是对于未来的组织,想拥有 .int域名就必须遵守以上条件。
用 dig 对 .int 域名进行 DNS 查询
我们来看看 .int顶级域名的 DNS 结构。首先要得到一份 .int区域文件的拷贝,这份文件将会包含所有现存的 .int 域名的列表和他们的权威服务器。奇怪的是,在维基百科上的 .int域名列表只有一个引用源和这个链接。这个区域文件似乎是准确的,但是为什么它托管在一个随机的域名上,像 statdns.com。他们是怎么得到的呢?为了找到答案,我们要调查一下 .int域名服务器。
所以,让我们来看看 .int域名服务器。首先,这些服务器是什么?
mandatory@Matthews-MacBook-Pro-4 ~/Desktop> dig NS int.
;<<>> DiG 9.8.3-P1 <<>> NS int.
;;global options: +cmd
;;Got answer:
;;->>HEADER<<- opcode: QUERY, status: NOERROR, id: 48321
;;flags: qr rd ra; QUERY: 1, ANSWER: 5, AUTHORITY: 0, ADDITIONAL: 0
;;QUESTION SECTION:
;int. IN NS
;;ANSWER SECTION:
int. 16208 IN NS ns.icann.org.
int. 16208 IN NS sec2.authdns.ripe.net.
int. 16208 IN NS ns.uu.net.
int. 16208 IN NS ns0.ja.net.
int. 16208 IN NS ns1.cs.ucl.ac.uk.
;;Query time: 25 msec
;;SERVER: 172.16.0.1#53(172.16.0.1)
;;WHEN: Sat Jun 11 16:43:46 2016
;;MSG SIZE rcvd: 153
看起来,有五个 .int域名服务器。这些服务器都知道每个单独的 .int域名。那我们为什么不向他们请求一个副本?我们可以采用被用于 DNS 域传送的 AXFR DNS 请求。通常, AXFR 请求只允许从受信任的从服务器向主服务器发起,当从服务器需要复制主服务器的 DNS 信息时。但是,偶然情况下你会幸运地得到一个服务器,这个服务器将会被配置为允许任何人执行区域传送(AXFR)请求。使用以下命令,我们可以请求每一个域服务器,从而得到 .int顶级域名的域文件拷贝。
dig @ns.icann.org. AXFR int.
dig @sec2.authdns.ripe.net. AXFR int.
dig @ns.uu.net. AXFR int.
dig @ns0.ja.net. AXFR int.
dig @ns1.cs.ucl.ac.uk. AXFR int.
在完成查询之后,事实证明只有 ns1.cs.ucl.ac.uk可以给我们提供相关信息
mandatory@Matthews-MacBook-Pro-4 ~/Desktop> dig @ns1.cs.ucl.ac.uk. AXFR int.
;<<>> DiG 9.8.3-P1 <<>> @ns1.cs.ucl.ac.uk. AXFR int.
;(1 server found)
;;global options: +cmd
int. 86400 IN SOA sns.dns.icann.org. noc.dns.icann.org. 2016061000 3600 1800 604800 86400
int. 86400 IN NS ns.uu.net.
int. 86400 IN NS ns.icann.org.
int. 86400 IN NS ns0.ja.net.
int. 86400 IN NS ns1.cs.ucl.ac.uk.
int. 86400 IN NS sec2.authdns.ripe.net.
int. 60 IN TXT "$Id: int 5232 2016-06-10 23:02:24Z cjackson $"
ippc.int. 86400 IN NS dnsext01.fao.org.
ippc.int. 86400 IN NS dnsext02.fao.org.
ices.int. 86400 IN NS ns1.hosting2.dk.
ices.int. 86400 IN NS ns2.hosting2.dk.
ices.int. 86400 IN NS ns3.hosting2.dk.
eumetsat.int. 86400 IN NS ns1.p21.dynect.net. ...trimmed for brevity...
天呐!这样就可以得到这份列表了,一个顶级域名服务器竟然允许全局 DNS 域传送。这个服务器刚刚传递给我们一份全 .int域的拷贝。现在我们有了全部 .int域名的列表。我们将解析域到一个文件中,然后运行 NS 对其进行查询,以便知道他们拥有哪个域名服务器。dig NS -f int_domains.txt这很有趣,因为 .int域名只能由 IANA 创建,但是域名服务器可以设置为任意域名。在分析完以上的查询结果后,当请求它的域名服务器时域名 maris.int返回了状态码 SERVFAIL。这在 DNS 请求中是一个很模糊的错误,通常意味着在域名的权威域名服务器上出了问题。真奇怪,为什么是这些域名服务器?我们将会发起一个 dig 请求来查询 a.int域名服务器来找出原因:
mandatory@Matthews-MacBook-Pro-4 ~/Desktop> dig @ns.icann.org. NS maris.int
;<<>> DiG 9.8.3-P1 <<>> @ns.icann.org. NS maris.int
;(1 server found)
;;global options: +cmd
;;Got answer:
;;->>HEADER<<- opcode: QUERY, status: NOERROR, id: 16832
;;flags: qr rd; QUERY: 1, ANSWER: 0, AUTHORITY: 2, ADDITIONAL: 0
;;WARNING: recursion requested but not available
;;QUESTION SECTION:
;maris.int. IN NS
;;AUTHORITY SECTION:
maris.int. 86400 IN NS www.ispo.cec.be.
maris.int. 86400 IN NS cobalt.aliis.be.
;;Query time: 30 msec
;;SERVER: 199.4.138.53#53(199.4.138.53)
;;WHEN: Sat Jun 11 18:02:19 2016
;;MSG SIZE rcvd: 83
由此得知, maris.int域名有两个域名服务器,www.ispo.cec.be和 cobalt.aliis.be。让我们来检查一下第一个域名服务器,看看是否能发现什么问题。我们可以用 dig 做一个快速的 A 记录查询来完成需要
mandatory@Matthews-MacBook-Pro-4 ~/Desktop> dig A www.ispo.cec.be
;<<>> DiG 9.8.3-P1 <<>> A www.ispo.cec.be
;;global options: +cmd
;;Got answer:
;;->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 32301
;;flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 0
;;QUESTION SECTION:
;www.ispo.cec.be. IN A
;;AUTHORITY SECTION:
cec.be. 1799 IN SOA tclux1.cec.lu. di-cox.cec.eu.int. 2013062501 3600 600 604800 3600
;;Query time: 443 msec
;;SERVER: 172.16.0.1#53(172.16.0.1)
;;WHEN: Sat Jun 11 18:05:36 2016
;;MSG SIZE rcvd: 99
如上面的输出,我们收到了一个 NXDOMAIN 错误。这意味着记录不存在,我们可以运行另一个 NS 查询来判断基础域名是否存在,还是说这只是个子域名。
mandatory@Matthews-MacBook-Pro-4 ~/Desktop> dig ns cec.be ;<<>> DiG 9.8.3-P1 <<>> ns cec.be
;;global options: +cmd
;;Got answer:
;;->>HEADER<<- opcode: QUERY, status: NOERROR, id: 35109
;;flags: qr rd ra; QUERY: 1, ANSWER: 10, AUTHORITY: 0, ADDITIONAL: 0
;;QUESTION SECTION:
;cec.be. IN NS
;;ANSWER SECTION:
cec.be. 3599 IN NS ns1bru.europa.eu.
cec.be. 3599 IN NS tclux17.cec.eu.int.
cec.be. 3599 IN NS tcbru22.cec.eu.int.
cec.be. 3599 IN NS ns1lux.europa.eu.
cec.be. 3599 IN NS auth00.ns.be.uu.net.
cec.be. 3599 IN NS tclux1.cec.eu.int.
cec.be. 3599 IN NS ns2bru.europa.eu.
cec.be. 3599 IN NS ns2lux.europa.eu.
cec.be. 3599 IN NS auth50.ns.be.uu.net.
cec.be. 3599 IN NS tcbru25.cec.eu.int.
;;Query time: 550 msec
;;SERVER: 172.16.0.1#53(172.16.0.1)
;;WHEN: Sat Jun 11 18:09:28 2016
;;MSG SIZE rcvd: 268
显然基础域名存在,但是没有子域名记录。这个域名服务器的把柄被我们逮到了,对 cobalt.aliis.be的从属服务器的全部 DNS 请求都应该失败。让我们来看看下一个,我们再次执行一个 A 记录查询:
;<<>> DiG 9.8.3-P1 <<>> A cobalt.aliis.be
;;global options: +cmd
;;Got answer:
;;->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 51336
;;flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 0
;;QUESTION SECTION:
;cobalt.aliis.be. IN A
;;AUTHORITY SECTION:
be. 599 IN SOA a.ns.dns.be. tech.dns.be. 1015004648 3600 1800 2419200 600
;;Query time: 176 msec
;;SERVER: 172.16.0.1#53(172.16.0.1)
;;WHEN: Sat Jun 11 18:16:10 2016
;;MSG SIZE rcvd: 101
因垂丝汀,这个请求也返回了 NXDOMAIN 错误。那么基础域名呢?
;<<>> DiG 9.8.3-P1 <<>> A aliis.be
;;global options: +cmd
;;Got answer:
;;->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 52102
;;flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 0
;;QUESTION SECTION:
;aliis.be. IN A
;;AUTHORITY SECTION:
be. 565 IN SOA a.ns.dns.be. tech.dns.be. 1015004648 3600 1800 2419200 600
;;Query time: 21 msec
;;SERVER: 172.16.0.1#53(172.16.0.1)
;;WHEN: Sat Jun 11 18:16:43 2016
;;MSG SIZE rcvd: 101
哇!基础域名也不存在!但是,等一下,这其实是一个超糟糕的事情,因为任何人都可以注册.be域名。这意味着,任何人都可以注册 aliis.be然后接管 maris.int,因为 aliis.be是它的权威解析服务器。正因为这样,我们花费 13 美元购买了 aliis.be域名。我们现在有了 maris.int的完全控制权,但是更重要的是,我们阻止了其他人为了自己恶毒的意图接管它。那我们接下来要做什么呢?
恢复 maris.int往日的荣光
maris.int在他们的域名服务器到期之前做了些什么?我们可以去 Archive.org查找存档。看这个网站肯定有复古的感觉,特别是页面底部的图标“使用 Netscape 浏览器获得最佳体验”。我们可以使用 Archive 下载器来得到这个网站的本地副本。我们现在已经有了恢复这个网站的一切!我们要做的第一件事儿就是设置 aliis.be的 DNS。我们会为根域名添加一个 A 记录,这个根域名指向我们在亚马逊云主机上部署的一个实例。我们还将添加一个通配子域名记录,这个记录将会重定向全部对子域名的 CNAME 请求到根域名 A 记录默认的 IP 地址。现在的权威域名解析服务器已经被设置成我们部署的 AWS 实例。下一步我们就要安装 BIND DNS 服务器并且配置它作为 maris.int域的权威主机。然后我们就可以设置全部对 maris.int子域名的请求都指向 AWS 服务器了。因此,现在任何对 maris.int的任何请求,包括其子域名,都会被指向我们的服务器。随着部署的完成,我们现在可以使用 Python 来重开原始网站(基于 Archive 提供的快照)。
最后,因为我认为有些人可能会问发生了什么?这里已经是 Archive 对现在我持有的这个网站的快照了。
披露时间线
2016.6.10 最初与 int-dom@iana.org 发邮件沟通,其允许我们完成对一个 .int 域名的完全托管。一个关于披露责任信息的链接和一个我的 PGP 的链接被提供出来。
2016.6.13 IANA 证实存在问题
2016.6.13 和 IANA 沟通协商这个问题
2016.6.15 后续与 IANA 的电子邮件沟通一切正常,并且提供了原始报告中不清楚的进一步细节。
2016.6.21 IANA 验证了这个问题,并且指出他们在尝试与 MARIS 的人进行联系。但是这个域名服务器并没有被改变。
2016.7.9 由于自从这个域名被我购买下来后没有进一步利用的可能性,这个问题已经公开披露。我将会继续更新这个域名直到漏洞被 MARIS 或 IANA 的人修复(我也将会继续维护他们的原始网站,除非他们不希望我这样做),来防止被其他人恶意利用。
对受限制的顶级域名存在的问题思考
一个有趣的人才会拥有一个受限制的顶级域名的想法。.int 顶级域名只是许多有限制的顶级域名之一。许多其他的顶级域名也有限制,如 .gov、.edu、.mil。试图限制谁可以访问一个特定的顶级域名的问题,DNS 和网站都建立在指向第三方的基础上。
例如, CNAME 的 DNS 记录可以被用于将一个子域名指向另一个完全受限的域名(FQDN)。另一个明显的例子是 NS 的 DNS 记录也可以指向 FQDN。这就是我们为什么可以结果 maris.int。任何一个指向我们限制的顶级域名空间外的域名的 DNS 记录都会到期,之后可以由第三方注册。
IP 地址也与之类似,你是否把 A 记录指向了第三方的主机?如果主机提供商突然倒闭了,或者有些人接管了这个 IP,他们就拥有了一个你受限的顶级域名下的子域名或者域名。更糟的是,你仍然被限制着你的顶级域名空间。你决定全部的 DNS 必须都指向你所拥有的 IP 地址和域名。所以你必须在管理 DNS 和你的顶级域名下的每个域名服务器。你可以防止任何人入侵你的顶级域名空间吗?听起来,好像不能。一旦我们将协议链向上移动一个比特,我们就会暴露在网络风险中。在这些协议水平下,你呈现给你的访问者的页面在 example.restrictedtld并且服务器和 DNS 都在你的控制下。
但是,现在就遇到了一个有趣的问题。网络的本质也是复杂的。你就不想在 CDN 上拉取一个 JavaScript 脚本吗?拉取 CSS 和 JavaScript 又有什么区别呢?所有这些必须都由你自己来管理,否则主机、域名都有可能过期,尽量做到离开你能和你在时一样。总而言之,这是一个相当困难的问题,这违背了互联网内联的设计。
对于一个攻击者而言,只需要进行少量的研究和扫描就能获得你受限顶级域名的子域名或者域名的控制,这并不困难 。