说劫持首先要理解会话。从用户在浏览器输入网址(点下书签)开始:
- 系统在联网的时候被分配到一个 DNS 服务器地址 / 用户手工设置了一个 DNS 地址(如 8.8.8.8)
- 浏览器向系统配置的 DNS 查询「这个网址对应的 IP 是多少」
- 1 中的 DNS 服务器返回「服务器地址是 x.x.x.x」或者「NXDOMAIN:没这个 X 域名」
- 浏览器向 3 中返回的 x.x.x.x 的 80 端口建立 TCP 连接
- 连接建立后,浏览器在这个连接中发送 GET /xxx HTTP/1.1 请求页面
- 服务器收到上述 GET 请求,返回 HTTP 200 OK,后面是各种 HTML 内容
传统所谓的 DNS 劫持是说,当用户向自己系统设定的 DNS 服务器(可能是 ISP 分配的,可能是手工设置的 8.8.8.8. 之类)请求某网站 IP 地址,如果名字错误无法解析,标准的 DNS 协议规定应该发送 NXDOMAIN 错误信息(上述第 3 步),而电信可能(直接,如果用户使用的是自动分配的电信 DNS;或首先拦截来自远程服务器的 NXDOMAIN 消息,如果是用户手工设置过其它的服务器)发送一个「正常」的响应返回给用户一个错误的地址(「
http://zhihu.com 的 IP 是 123.123.213.213,实际上这个 IP 是错误的地址,如常见的 114 网址导航等),将用户浏览器页面重定向到指定的(广告)页面去。这种中途拦截、篡改 DNS 响应插入内容的做法叫做「DNS 劫持」。
现在这个所谓的 iPush (糟蹋我 i- prefix 啊垃圾!),实际上比 DNS 劫持要恶劣得多。它是主动分析用户正常的网络流量(第 5 步建立连接之后的内容),在网站返回的正常 HTML 页面(上述第 6 步)中,插入自己的内容(包括随机页面重定向、插入 iframe / javascript 页面弹窗等)。这个时候实际上用户已经完成了正常的 DNS 解析,与网站之间建立了 TCP 会话。但由于 TCP 本身只是一个管道,而 HTTP 协议是明文(无加密)的,在这个 HTTP 会话中,所有的节点(路由器网关、过滤服务器等)都有可能完整监视(和篡改)其中发送的内容 。这种「中间人」攻击,在普通 HTTP 会话中是完全无法检查防止的。由于是由攻击者在 TCP 流中间插入了一段信息,客户会以为所有信息都是来自原始服务器而无从检查和区分,所以利用这种方法给知乎页面右下角插入一个弹窗广告之类,用户很可能就以为是网站自身的内容了。
至于文中提到的「收集用户 Email 等信息」其实对用户的危害更严重:在知乎还没有 HTTPS 登录的时候我给人做过这个演示,用 Wireshark 可以重建完整的 TCP 流内容,包括登录 URL、用户名和明文密码等,真的是「一切尽收眼底」。
网站运营者对这种无耻的中间人攻击可以做的事情不多。全程使用 HTTPS 是第一步,因为首先解密 HTTPS 会话要求的计算量较大,比攻击 HTTP 流要复杂一些;同时 HTTPS 会要求 SSL 证书签名的域名与访问的网址域名对应,中间人攻击时替换的 SSL 证书往往会被浏览器检查出来并警告用户(我之前公司安全老大就曾经遇到过 Gmail 的 SSL 证书被中间人替换的情况)。但由于现在使用不合适 SSL 证书的站点相当多(包括域名不匹配、过期等),用户可能已经对浏览器的 SSL 安全警告视若无睹的直接同意,这样也无法真正保护用户的信息安全。
真的要行之有效的解决,还是如 @
陈衍领 所说,只有靠立法和监管,限制电信服务商不要做自己不该做的事情;或者引入更充分的竞争允许用户选择。但是……
-- 完 --
下载知乎 iPhone 客户端:
http://zhi.hu/ios