Total Pageviews

Thursday 18 February 2016

辨别DNS 是否被污染

图中可以看到我们的ISP 的DNS 服务器在图中叫做DNS Recurser,在解析一个域名的时候,总共经过了以下的步骤,图是以www.wikipedia.org 作为示范的:
  1. 向root 服务器获取该gTLD 的管辖服务器,图中为org 结尾的域名
  2. root 服务器返回org 的管辖服务器
  3. 向org 的管辖服务器查询,谁来负责解析wikipedia.org 这个域名的
  4. org 的管辖服务器返回解析wikipedia.org 的服务器IP 地址
  5. 向wikipedia.org 的解析服务器发出查询,解析www.wikipedia.org 的IP 地址
  6. 拿到最终要的IP 地址
共6个步骤。那么如果在最后一次查询的时候,有人假冒了wikipedia.org 的解析服务器,则可以在中间进行欺骗攻击,致使用户最后得到的IP 地址不是真实的地址。如图所示,
解析请求被劫持
更详细的关于DNS的内容,可以自行参考rfc1035(http://tools.ietf.org/html/rfc1035)。

手工模拟

以上是大致的解析原理,我们手工一步一步来模拟解析的每个步骤吧。这里我用的环境是北京联通ADSL + Mac OS X 10.7 『Lion』 + 某国家VPN 一条。工具用到了dig 和tcpdump 来完成,Windows 下默认木有俩工具似乎,大家自行寻找吧,或者找一个GNU/Linux 发行版装上,个人推荐Ubuntu,有red hat 情节的,就Fedora 好了。首先用联通的ADSL 来试验下
$ dig //直接获取根服务器的地址
`
; <<>> DiG 9.7.3 <<>> 
;; global options: +cmd 
;; Got answer: 
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 12586 
;; flags: qr rd ra; QUERY: 1, ANSWER: 13, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION: 
;. IN NS
;; ANSWER SECTION: 
. 473766 IN NS e.root-servers.net. 
. 473766 IN NS c.root-servers.net. 
. 473766 IN NS j.root-servers.net. 
. 473766 IN NS h.root-servers .net. 
. 473766 IN NS m.root-servers.net. 
. 473766 IN NS f.root-servers.net. 
. 473766 IN NS g.root-servers.net. 
. 473766 IN NS l.root-servers.net . 
. 473766 IN NS b.root-servers.net. 
. 473766 IN NS k.root-servers.net. 
. 473766 IN NS d.root-servers.net. 
. 473766 IN NS i.root-servers.net. 
. 473766 IN NS a.root-servers.net.
`
;; Query time: 30 msec ;; SERVER: 202.106.46.151#53(202.106.46.151) ;; WHEN: Sat Aug 13 22:18:56 2011 ;; MSG SIZE rcvd: 228
这里我们可以看到,全球的域名根服务器共有从a 到m,共13 组服务器。继续去dig 出来这些服务器的地址吧,随便找一个好了
$ dig e.root-servers.net
`
; <<>> DiG 9.7.3 <<>> e.root-servers.net 
;; global options: +cmd 
;; Got answer: 
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id : 2043 
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION: 
;e.root-servers.net. IN A
;; ANSWER SECTION: 
e.root-servers.net. 560668 IN A 192.203.230.10
`
;; Query time: 29 msec ;; SERVER: 202.106.46.151#53(202.106.46.151) ;; WHEN: Sat Aug 13 22:21:10 2011 ;; MSG SIZE rcvd: 52
这里我们抓到了其中一组的DNS 根服务器e.root-servers.net 的地址为192.203.230.10,继续
$ dig -t ns @192.203.230.10 com.
`
; <<>> DiG 9.7.3 <<>> -t ns @192.203.230.10 com. 
; (1 server found) 
;; global options: +cmd 
;; Got answer: 
;; ->>HEADER<<- opcode : QUERY, status: NOERROR, id: 11080 
;; flags: qr rd; QUERY: 1, ANSWER: 0, AUTHORITY: 13, ADDITIONAL: 15 
;; WARNING: recursion requested but not available
;; QUESTION SECTION: 
;com. IN NS
;; AUTHORITY SECTION: 
com. 172800 IN NS m.gtld-servers.net. 
com. 172800 IN NS d.gtld-servers.net. 
com. 172800 IN NS g.gtld-servers.net. 
com. 172800 IN NS c .gtld-servers.net. 
com. 172800 IN NS e.gtld-servers.net. 
com. 172800 IN NS k.gtld-servers.net. 
com. 172800 IN NS h.gtld-servers.net. 
com. 172800 IN NS j.gtld-servers.net. 
com. 172800 IN NS a.gtld-servers.net. 
com. 172800 IN NS f.gtld-servers.net. 
com. 172800 IN NS i.gtld-servers.net. 
com. 172800 IN NS b.gtld-servers.net. 
com. 172800 IN NS l.gtld-servers.net.
;; ADDITIONAL SECTION: 
a.gtld-servers.net. 172800 IN A 192.5.6.30 
a.gtld-servers.net. 172800 IN AAAA 2001:503:a83e::2:30 
b.gtld-servers.net. 172800 IN A 192.33.14.30 
b.gtld-servers.net. 172800 IN AAAA 2001:503:231d::2:30 
c.gtld-servers.net. 172800 IN A 192.26.92.30 
d.gtld-servers.net. 172800 IN A 192.31.80.30 
e.gtld-servers.net. 172800 IN A 192.12.94.30 
f.gtld-servers.net. 172800 IN A 192.35.51.30 
g.gtld-servers.net. 172800 IN A 192.42.93.30 
h.gtld-servers .net. 172800 IN A 192.54.112.30 
i.gtld-servers.net. 172800 IN A 192.43.172.30 
j.gtld-servers.net. 172800 IN A 192.48.79.30 
k.gtld-servers.net. 172800 IN A 192.52. 178.30 
l.gtld-servers.net. 172800 IN A 192.41.162.30 
m.gtld-servers.net. 172800 IN A 192.55.83.30
`
;; Query time: 497 msec ;; SERVER: 192.203.230.10#53(192.203.230.10) ;; WHEN: Sat Aug 13 22:32:29 2011 ;; MSG SIZE rcvd: 509
上面共有从a 到m,一样是13 组服务器在所有的com. 的gTLD 的记录保存。
``
`
$ dig -t ns @192.5.6.30 twitter.com
; <<>> DiG 9.7.3 <<>> @192.203.230.10 twitter.com 
; (1 server found) 
;; global options: +cmd 
;; Got answer: 
;; ->>HEADER<<- opcode: QUERY , status: NOERROR, id: 4691 
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION: 
;twitter.com. IN A
;; ANSWER SECTION: 
twitter.com. 33917 IN A 203.98.7.65
`
;; Query time: 111 msec ;; SERVER: 192.203.230.10#53(192.203.230.10) ;; WHEN: Sat Aug 13 22:21:59 2011 ;; MSG SIZE rcvd: 45
这里看到问题了么?本来应该返回twitter.com 的具体的解析服务器,为什么直接返回了一个A 记录?而且还是这么诡异的一个地址?查询以下这个IP 的归属地,是『新西兰奥克兰Telstraclear公司』,应该是胡乱编出来的地址了。至此再测试下去意义也就不大了,具体原因等会儿分析。换上VPN 看看结果如何
``
`
$ dig
; <<>> DiG 9.7.3 <<>> 
;; global options: +cmd 
;; Got answer: 
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 63584 
;; flags: qr rd ra; QUERY: 1, ANSWER: 13, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION: 
;. IN NS
;; ANSWER SECTION: 
. 82346 IN NS a.root-servers.net. 
. 82346 IN NS b.root-servers.net. 
. 82346 IN NS e.root-servers.net. 
. 82346 IN NS g.root-servers .net. 
. 82346 IN NS i.root-servers.net. 
. 82346 IN NS h.root-servers.net. 
. 82346 IN NS m.root-servers.net. 
. 82346 IN NS c.root-servers.net . 
. 82346 IN NS d.root-servers.net. 
. 82346 IN NS k.root-servers.net. 
. 82346 IN NS j.root-servers.net. 
. 82346 IN NS f.root-servers.net. 
. 82346 IN NS l.root-servers.net.
`
;; Query time: 138 msec ;; SERVER: 8.8.8.8#53(8.8.8.8) ;; WHEN: Sat Aug 13 22:25:08 2011 ;; MSG SIZE rcvd: 228
这里的结果完全一样,我们继续选择e 的那组
``
`
$ dig e.root-servers.net
; <<>> DiG 9.7.3 <<>> e.root-servers.net 
;; global options: +cmd 
;; Got answer: 
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id : 10099 
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION: 
;e.root-servers.net. IN A
;; ANSWER SECTION: 
e.root-servers.net. 47915 IN A 192.203.230.10
`
;; Query time: 191 msec ;; SERVER: 8.8.8.8#53(8.8.8.8) ;; WHEN: Sat Aug 13 22:25:42 2011 ;; MSG SIZE rcvd: 52
嗯,这里也一样,继续
``
`
$ dig -t ns @192.203.230.10 com.
; <<>> DiG 9.7.3 <<>> -t ns @192.203.230.10 com. 
; (1 server found) 
;; global options: +cmd 
;; Got answer: 
;; ->>HEADER<<- opcode : QUERY, status: NOERROR, id: 56227 
;; flags: qr rd; QUERY: 1, ANSWER: 0, AUTHORITY: 13, ADDITIONAL: 15 
;; WARNING: recursion requested but not available
;; QUESTION SECTION: 
;com. IN NS
;; AUTHORITY SECTION: 
com. 172800 IN NS c.gtld-servers.net. 
com. 172800 IN NS a.gtld-servers.net. 
com. 172800 IN NS g.gtld-servers.net. 
com. 172800 IN NS h .gtld-servers.net. 
com. 172800 IN NS b.gtld-servers.net. 
com. 172800 IN NS l.gtld-servers.net. 
com. 172800 IN NS d.gtld-servers.net. 
com. 172800 IN NS j.gtld-servers.net. 
com. 172800 IN NS k.gtld-servers.net. 
com. 172800 IN NS f.gtld-servers.net. 
com. 172800 IN NS m.gtld-servers.net. 
com. 172800 IN NS e.gtld-servers.net. 
com. 172800 IN NS i.gtld-servers.net.
;; ADDITIONAL SECTION: 
a.gtld-servers.net. 172800 IN A 192.5.6.30 
a.gtld-servers.net. 172800 IN AAAA 2001:503:a83e::2:30 
b.gtld-servers.net. 172800 IN A 192.33.14.30 
b.gtld-servers.net. 172800 IN AAAA 2001:503:231d::2:30 
c.gtld-servers.net. 172800 IN A 192.26.92.30 
d.gtld-servers.net. 172800 IN A 192.31.80.30 
e.gtld-servers.net. 172800 IN A 192.12.94.30 
f.gtld-servers.net. 172800 IN A 192.35.51.30 
g.gtld-servers.net. 172800 IN A 192.42.93.30 
h.gtld-servers .net. 172800 IN A 192.54.112.30 
i.gtld-servers.net. 172800 IN A 192.43.172.30 
j.gtld-servers.net. 172800 IN A 192.48.79.30 
k.gtld-servers.net. 172800 IN A 192.52. 178.30 
l.gtld-servers.net. 172800 IN A 192.41.162.30 
m.gtld-servers.net. 172800 IN A 192.55.83.30
`
;; Query time: 337 msec ;; SERVER: 192.203.230.10#53(192.203.230.10) ;; WHEN: Sat Aug 13 22:31:39 2011 ;; MSG SIZE rcvd: 509
没有什么新奇的,继续…
``
`
$ dig -t ns @192.5.6.30 twitter.com
; <<>> DiG 9.7.3 <<>> -t ns @192.5.6.30 twitter.com 
; (1 server found) 
;; global options: +cmd 
;; Got answer: 
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 26303 
;; flags: qr rd; QUERY: 1, ANSWER: 0, AUTHORITY: 4, ADDITIONAL: 4 
;; WARNING: recursion requested but not available
;; QUESTION SECTION: 
;twitter.com. IN NS
;; AUTHORITY SECTION: 
twitter.com. 172800 IN NS ns1.p34.dynect.net. 
twitter.com. 172800 IN NS ns2.p34.dynect.net. 
twitter.com. 172800 IN NS ns3.p34.dynect.net. 
twitter.com. 172800 IN NS ns4.p34.dynect.net.
;; ADDITIONAL SECTION: 
ns1.p34.dynect.net. 172800 IN A 208.78.70.34 
ns2.p34.dynect.net. 172800 IN A 204.13.250.34 
ns3.p34.dynect.net. 172800 IN A 208.78.71.34 
ns4.p34 .dynect.net. 172800 IN A 204.13.251.34
`
;; Query time: 448 msec ;; SERVER: 192.5.6.30#53(192.5.6.30) ;; WHEN: Sat Aug 13 22:34:05 2011 ;; MSG SIZE rcvd: 179
到这里的结果就和刚才不一样了,可以看到,192.5.6.30 这个服务器正常返回了应该负责解析twitter.com 的真实ns 的服务器,既然都做到这里了,就继续下去吧,继续从里面随便抓一个出来
``
`
$ dig @208.78.71.34 twitter.com any 
;; Truncated, retrying in TCP mode.
; <<>> DiG 9.7.3 <<>> @208.78.71.34 twitter.com any 
; (1 server found) 
;; global options: +cmd 
;; Got answer: 
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 36456 
;; flags: qr aa rd; QUERY: 1, ANSWER: 19, AUTHORITY: 0, ADDITIONAL: 0 
;; WARNING: recursion requested but not available
;; QUESTION SECTION: 
;twitter.com. IN ANY
;; ANSWER SECTION: 
twitter.com. 30 IN SOA ns1.p26.dynect.net. zone-admin.dyndns.com. 2007110572 3600 600 604800 60 
twitter.com. 86400 IN NS ns1.p34.dynect.net. 
twitter. com. 86400 IN NS ns2.p34.dynect.net. 
twitter.com. 86400 IN NS ns4.p34.dynect.net. 
twitter.com. 86400 IN NS ns3.p34.dynect.net. 
twitter.com. 30 IN A 199.59.149.203 
twitter.com. 30 IN A 199.59.149.230 
twitter.com. 30 IN A 199.59.149.235 
twitter.com. 30 IN A 199.59.148.10 
twitter.com. 30 IN A 199.59.148.14 
twitter.com. 30 IN A 199.59.148.81 
twitter.com. 30 IN A 199.59.148.82 
twitter.com. 30 IN A 199.59.149.198 
twitter.com. 600 IN MX 10 aspmx.l.google.com. 
twitter.com. 600 IN MX 20 alt1.aspmx .l.google.com. 
twitter.com. 600 IN MX 20 alt2.aspmx.l.google.com. 
twitter.com. 600 IN MX 30 ASPMX2.GOOGLEMAIL.com. 
twitter.com. 600 IN MX 30 ASPMX3.GOOGLEMAIL .com. 
twitter.com. 600 IN TXT "v=spf1 ip4:199.16.156.0/22 ​​ip4:199.59.148.0/22 ​​ip4:128.121.145.168 ip4:128.121.146.128/27 mx ptr a:postmaster.twitter.com a :ham-cannon.twitter.com mx:one.textdrive.com include:cmail1.com include:aspmx.googlemail.com include:support.zendesk.com -all"
`
;; Query time: 148 msec ;; SERVER: 208.78.71.34#53(208.78.71.34) ;; WHEN: Sat Aug 13 22:35:46 2011 ;; MSG SIZE rcvd: 696
我们可以发现挂上VPN之后的解析流程才是正确无误的过程,但是为什么不挂上就不能正确解析?自然是DNS服务器被污染了。并且拦截的方式似乎也很弱智,发现UDP 53口的包带有twitter.com字样,直接返回一个随即、胡编出来的IP地址,也不管人家到底是不是直接要去查twitter.com的A记录。为了证明这种猜想,继续做一些试验吧。不如发一个错误的DNS包出去,看看返回什么结果。
$ dig @202.204.49.251 twitter.com -t ns --->> 查询的服务器是202.204.48.251
`
; <<>> DiG 9.7.3 <<>> @202.204.49.251 twitter.com -t ns 
; (1 server found) 
;; global options: +cmd 
;; Got answer: 
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 19538 
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION: 
;twitter.com. IN NS
;; ANSWER SECTION: 
twitter.com. 32460 IN A 159.24.3.173
`
;; Query time: 213 msec ;; SERVER: 202.204.49.251#53(202.204.49.251) ;; WHEN: Sat Aug 13 22:43:45 2011 ;; MSG SIZE rcvd: 45
这里的服务器是iBeiKe 在教育网内的服务器,对于外网没有开除了80 的任何口,而且也没有53 的UDP 开着,果然,够弱智!

tcpdump 抓包

tcpdump 这个东西虽然叫做tcpdump,但是UDP 抓起来也没有问题,随便抓抓DNS 的解析包,不需要什么重型武器,这种轻量级别就很好用了。环境和上面一样,我用的无线网络,所以在Mac OS X 的接口就是en1 了。不上VPN 看看结果如何吧
$ sudo tcpdump -i en1 -vvv udp tcpdump: listening on en1, link-type EN10MB (Ethernet), capture size 65535 bytes 22:11:41.687602 IP (tos 0x0, ttl 64, id 37209, offset 0, flags [none] , proto UDP (17), length 57) localhost.57689 > ns1.p34.d​​ynec​​t.net.domain: [udp sum ok] 2927+ A? twitter.com. (29) 22:11:41.717641 IP (tos 0x0, ttl 216, id 14349, offset 0, flags [none], proto UDP (17), length 73) ns1.p34.d​​ynec​​t.net.domain > localhost.57689: [udp sum ok] 2927 q: A? twitter.com . 1/0/0 twitter.com. [4h50m45s] A 159.24.3.173 (45) 22:11:41.718373 IP (tos 0x0, ttl 117, id 43381, offset 0, flags [none], proto UDP (17), length 73) ns1.p34.d​​ynec​​t.net.domain > localhost.57689: [bad udp cksum 2700!] 2927 q: A? twitter.com. 1/0/0 twitter.com. [5m] A 37.61.54.158 ( 45) 22:11:42.306659 IP (tos 0x0, ttl 48, id 61847, offset 0, flags [none], proto UDP (17), length 191) ns1.p34.d​​ynec​​t.net.domain > localhost.57689: [ udp sum ok] 2927*- q: A? twitter.com. 3/4/0 twitter.com. [30s] A 199.59.148.82, twitter.com. [30s] A 199.59.149.230, twitter.com. [30s ] A 199.59.149.198 ns: twitter.com. [1d] NS ns4.p34.d​​ynec​​t.net., twitter.com. [1d] NS ns2.p34.d​​ynec​​t.net., twitter.com. [1d] NS ns1 .p34.d​​ynec​​t.net., twitter.com. [1d] NS ns3.p34.d​​ynec​​t.net. (163)
唔,有人抢在正确的包之前跑来了。你为什么这么积极呢?为什么呢…