善意提醒

如果您打开本站很慢,布局排版混乱,并且看不到图片,那么可能是因为您还没有掌握用科学的方法上网的本领。
显示标签为“翻墙”的博文。显示所有博文
显示标签为“翻墙”的博文。显示所有博文

2014-01-22

2014 年 1 月全国性 DNS 劫持事件评析

许久没更新博客了。这次全国性事件既然这么轰动,震惊互联网界及翻墙界,那我就借此机会说上两句。

事件是 15:20 开始的,而我当时 15:30 刚好有个会,所以这个事件只经历了一点开头:
当时我正在整理自己的收藏夹,进行到 windbg 和 ollydbg 的时候,发现需要翻墙才能访问了。刚开始我在疑惑为啥 GFW 会对调试工具下手,难道愚民政策已经扩展到技术界了?随后我发现大部分时间这两个网站的域名被解析到了 65.49.2.178 这个 IP 上。少部分时间的尝试是正确的,但这个概率小得不足以完成大部分文件的载入。由于我用的 DNS 一直都是四个 8 ,所以第一个反应就是这两个站点被 DNS 污染了。
既然是污染,那么应该能抓到正确的 DNS 回应包,只是慢点而已。但这次我发现 DNS 回应包是一对一的,没有多余的包回来。只是第一次解析的时候往往能解析到正确的地址上,后面再解析,回复的就是 65.49.2.178 了。当时我还没试别的网站。
然后开会的时间到了,我就走了。再回来的时候,故障已经基本结束了,没什么时间和机会去分析。技术方面的分析,可以参考 这个。我认为分析得靠谱,符合此次事件的各种特征。我在这里只补充一些文中没有提到的部分。

首先,这不是「DNS 污染」,是「DNS 劫持」。
我这里不是在抠字眼,或者讨论这两个词的定义问题。我只是指出这个事实:这次 GFW 对于 DNS 的攻击方式,跟以往(或者说一直以来)的 DNS 污染有所不同。
一般,GFW 的做法是抢在 DNS 服务器的正常应答之前,伪造一个应答,欺骗客户端。正常的应答仍旧会返回到客户端,只不过 GFW 的欺骗包会很快,相当快,使得客户端不理睬正常的回应包。
但这次不同,从抓包的结果看来,「一问一答」,并没有多余的回应包。即使 DNS 是境外的 8.8.8.8,也是如此。境内的 DNS,尚有别的办法可以进行控制。境外的 DNS,必须是在 DNS 查询 / 回应包的转发路径上对其进行劫持 / 丢弃,才能实现这种效果。

其次,探索一下 GFW 这次这个 DNS 劫持功能的工作模式。
通常而言,要进行 DNS 劫持,GFW 可以有两种基本做法:
  • 劫持 DNS 查询包:截获 DNS 查询包,不把它向目的 DNS 进行转发,然后自己伪造一个 DNS 回应包给客户端发去。
  • 丢弃 DNS 回应包:截获 DNS 回应包,伪造一个 DNS 回应包发给客户端,然后把正确的回应包丢弃,使其不能正常到达客户端。
实际上的情况,可能比这要更复杂一点。比如,丢包的事情,应该是 GFW 的一个状态防火墙完成的。而防火墙的规则添加可能需要一点时间,所以第一次查询时有可能会有正确的回应包漏过。
另外,根据每次都是「一问一答」看来,伪造的 DNS 回应包可能是防火墙规则自动触发。也就是说,DNS 回应包被拦截后,才会伪造一个发给客户端。如果没被拦截,就不会伪造。否则无法解释第一次查询时正确的回应包漏过之时为什么也是「一问一答」。
综合上述情况,并结合 GFW 的部署和需求特点,这次的 DNS 劫持功能应该是采用的第二种工作模式,也就是说对 DNS 回应包进行处理。很显然,对于 GFW 而言:从「非受控区域」过来的数据,才是真正需要控制的「有害数据」。从「受控区域」出去的数据,就算会被判定为「有害」,也没必要进行处理,守株待兔就可以,说不定对方根本就不存在呢。

顺便,对 GFW 的一些技术细节,从这次事件可以有更多的认识。
要完成 DNS 劫持,有一个前提:GFW 可以控制 DNS 包转发路径中的(至少)某个路由器,或者 GFW 自身(的一部分)就是 DNS 包转发路径中串进去的一环。相比之下,如果要做到以前的 DNS 污染,只需要在交换机上旁路接入一台设备,不需要串在路由路径中。
具体而言,从这个 DNS 劫持的功能看来,应该会有三个部件参与:
  • 识别模块:这个可以由一个 IDS 性质的设备来完成。对来自「非受控区域」的 DNS 回应包进行检测。这个完全可以在旁路慢慢做,不影响网络出口的性能。
  • 过滤模块:当识别模块检测到「有害信息」后,会向一个状态防火墙添加一条动态规则。生效不一定很快,但因为是全国性质的,漏也漏不了多少。这条动态规则包括丢弃符合条件的 DNS 回应包,以及驱动欺骗模块去伪造一个 DNS 回应包。这个设备必须串入骨干路由,应该是部署在互联网出口处,基本上必须是一个群集。
  • 欺骗模块:伪造的工作是跟过滤模块联动的,即:丢弃-伪造。这个模块以前应该就存在,部署在旁路上就可以。

回头想想,这些都并不是什么前沿的技术。花不了多少时间我自己都能写出来。目前阻碍这个功能(DNS 劫持)大规模应用的因素,可能主要还是来自性能方面的压力。否则现在对那些敏感域名仍然在大量采用的低效的 DNS 污染早就该换成劫持了。在性能方面而言,用旁路模式当然会好很多。有关人等大概也知道,在 DNS 上无论怎么折腾,也都是锁君子锁不住小人,索性不把宝贵的性能浪费在这里了。

2013-09-22

GoAgent 证书问题一例

昨天准备在太太的电脑上用一下 GoAgent,结果发现很多网站都不能用。很奇怪的是,Twitter 页面能打开,但 CSS / JS 看起来基本上都不对。而在我自己的电脑(LAN 内部)上却是好的。所以很明显是 Local 而不是 Network 的问题。
看 GoAgent 控制台上的日志,问题似乎跟 SSL 的连接建立有关系。再把 Chrome 的「审查元素」功能打开,Console 里面一堆错误。随便挑了个页面试图打开,好了,这下清楚了,证书有问题。
看了看 GoAgent 的官方 Q & A,基本上只提到说证书需要导入。很多在网上问这类问题的人,得到的也是类似回答。但问题在于,证书的导入是没有问题的,重新导入也没有效果。而且并不是所有网站都不能通过 GoAgent 代理。

其实问题很简单:GoAgent 仿冒的证书被占用啦。
官方其实也提到过这个事情:
因为 GAE 平台限制,没法支持真正的 ssl 加密,goagent 只能通过伪造证书的方式做到代理 ssl 加密的网站,这个证书就是用来欺骗浏览器的。
GoAgent 实际上相当于一个「中间人」。当访问 HTTPS 站点时,就得采用 SSL 中间人攻击的类似方式,才能完成代理的工作。SSL 中间人攻击怎么弄?导入受信任的根证书,然后利用这个根证书签发的证书把内容拆开后重新组装、加密、封包,骗完甲方骗乙方,欺骗通讯双方。否则两端任何一方觉得这内容不对劲,SSL 传输就会失败。这其实也就是为什么必须要干掉 CNNIC 相关的根证书的原因。

所以,对于每一个 HTTPS 站点,GoAgent 都会生成一份用自己根证书签发的数字证书。看看 GoAgent 的 local 目录下,如果访问过 HTTPS 站点,则一定会有一个 certs 目录。这生成的证书,就放在这个 certs 目录下。其实一看这个目录里面都有些什么文件,就很明白了:
这次的问题在于,GoAgent 有不同的版本,其携带的根证书也是变化过的。至少我机器上随便打开 CertMgr 就见到了五个不同的版本:
如果升级的时候不把 certs 目录清空,就有可能会有部分站点对应的证书还是以前的老的、用旧的根证书签发出来的。GoAgent 客户端一看,噢,证书已经有了,就不再重新生成了。但 Chrome 觉得证书不对,于是 SSL 握手就被挡了。

解决办法很简单,每次升级 GoAgent 的时候,把 local/certs 目录删掉。或者干脆每次用新目录来升级好了。

2013-09-10

写了个批量测试服务器 Ping 值的小工具

不时有人问我要 hosts,但是很多时候也不敢贸然的给。担心泄漏是一方面。另外一方面,我这边可以用的 hosts,在别人那边可能用不了。我这边用起来很快的 hosts,在人家那边可能像乌龟爬。叫别人 ping 一下当然不是什么太麻烦的事情,但如果连试好几个 IP 都不行,有时候也是很头大的事。效率也很低下。

因此想,要是有个能批量 Ping,并且能很容易看到输出结果的工具,就好了。用批处理做个批量 Ping 是很容易的,但结果并不是特别一目了然。于是干脆自己动手做了一个。
启动时会加载当前目录下的 server.list 文件,文件中每行写一个地址(这几个地址有些人可能一看就知道是什么东西了)就可以了。写域名也是可以的,但我这里输出结果中并不包含域名解析的结果。
目前只打算简单做成这样,反正只当小工具用用。如果觉得网络不顺的时候,就启动起来跑一跑看看。然后也可以把一堆 IP 丢给别人自己校验去。

有需求的朋友可以去拿来用下。工具的下载地址:Dropbox镜像 Mega下载页面
为了减少 CRT 依赖性,上面的发布版本是静态链接的。如果想用动态链接版本,或者担心木马、病毒什么的,就下载下面的源代码自己编译吧。VC6 就可以。反正自己也没写多少代码,许可证什么的就懒得去弄了。
源代码下载地址:Dropbox镜像 Mega下载页面

2013-06-27

自己写了个帮助快速替换 hosts 的工具

替换 hosts 对于会的人而言并不是一件复杂的事情。不过仍然稍嫌繁琐:目录本来就比较深,还要涉及到文件复制和改名。稍一不留意还有搞错掉的可能。

两个月前,我终于无法忍受了,自己写了一个批处理来解决这个问题。人容易出错,人会烦,机器不会出错——如果你程序写对了的情况下。作为程序员,就应该有自己动手丰衣足食的觉悟。因此就有了 SetHosts.bat 的第一版:
@echo off
pushd %SystemRoot%\system32\drivers\etc\
copy /y %1 hosts
popd
只这样显然是不够的。在命令行下敲指令,这不是我的初衷。虽然 Windows 的 Drag & Drop 可以省很多事情,但我还想做得更多。把这个 BAT 注册成某个特定后缀的文件的默认打开程序不是很好吗?这样以后直接双击文件就可以完成替换了。

于是当时我自己用 regedit 在注册表上填写了关联文件打开方式的相关信息。现在我可以双击 hosts_cn.fkw 或 hosts_us.fkw 来快速地应用某个我事先准备好的 hosts 文件了。
应该说,自己用用,这样是足够了。不过我还想做的更好一点。让程序自己完成这个填写注册表的过程,不是更好吗?于是有了 SetHosts.bat 的第二版:
@echo off
if {%1}=={} goto install
if {%1}=={/u} goto uninstall
if {%1}=={/U} goto uninstall
pushd %SystemRoot%\system32\drivers\etc\
copy /y %1 hosts
popd
goto :eof
:install
set MY_TEMPREGFILE=%TEMP%\temp.reg
set MY_SETHOST=%~f0
set MY_SETHOST=%MY_SETHOST:\=\\%
echo Windows Registry Editor Version 5.00>%MY_TEMPREGFILE%
echo.>>%MY_TEMPREGFILE%
echo [HKEY_CLASSES_ROOT\.fkw]>>%MY_TEMPREGFILE%
echo @="Fuckwall.Hosts">>%MY_TEMPREGFILE%
echo [HKEY_CLASSES_ROOT\Fuckwall.Hosts]>>%MY_TEMPREGFILE%
echo [HKEY_CLASSES_ROOT\Fuckwall.Hosts\shell]>>%MY_TEMPREGFILE%
echo [HKEY_CLASSES_ROOT\Fuckwall.Hosts\shell\edit]>>%MY_TEMPREGFILE%
echo [HKEY_CLASSES_ROOT\Fuckwall.Hosts\shell\edit\command]>>%MY_TEMPREGFILE%
echo @="\"C:\\Windows\\Notepad.exe\" \"%%1\"">>%MY_TEMPREGFILE%
echo [HKEY_CLASSES_ROOT\Fuckwall.Hosts\shell\open]>>%MY_TEMPREGFILE%
echo [HKEY_CLASSES_ROOT\Fuckwall.Hosts\shell\open\command]>>%MY_TEMPREGFILE%
echo @="\"%MY_SETHOST%\" \"%%1\"">>%MY_TEMPREGFILE%
regedit /s %MY_TEMPREGFILE%
del /q %MY_TEMPREGFILE%
set MY_TEMPREGFILE=
set MY_SETHOST=
echo 处理程序安装成功
echo 您可以双击后缀名为fkw的文件来直接更换hosts
echo.
pause
goto :eof
:uninstall
set MY_TEMPREGFILE=%TEMP%\temp.reg
echo Windows Registry Editor Version 5.00>%MY_TEMPREGFILE%
echo.>>%MY_TEMPREGFILE%
echo [-HKEY_CLASSES_ROOT\.fkw]>>%MY_TEMPREGFILE%
echo [-HKEY_CLASSES_ROOT\Fuckwall.Hosts]>>%MY_TEMPREGFILE%
echo [-HKEY_CLASSES_ROOT\Fuckwall.Hosts\shell]>>%MY_TEMPREGFILE%
echo [-HKEY_CLASSES_ROOT\Fuckwall.Hosts\shell\edit]>>%MY_TEMPREGFILE%
echo [-HKEY_CLASSES_ROOT\Fuckwall.Hosts\shell\edit\command]>>%MY_TEMPREGFILE%
echo [-HKEY_CLASSES_ROOT\Fuckwall.Hosts\shell\open]>>%MY_TEMPREGFILE%
echo [-HKEY_CLASSES_ROOT\Fuckwall.Hosts\shell\open\command]>>%MY_TEMPREGFILE%
regedit /s %MY_TEMPREGFILE%
del /q %MY_TEMPREGFILE%
set MY_TEMPREGFILE=
echo 处理程序反安装成功
pause
goto :eof
这下不仅注册有了,注销(反安装)也有了。以后看到 fkw 后缀的文件,就可以快速地 Fuckwall 了。……于是今天方校长就请病假了。

如果整代码有困难,那么可以从下面两个链接之一进行下载:
Dropbox: https://dl.dropboxusercontent.com/u/44933633/SetHosts.bat
Mega: https://mega.co.nz/#!Bhx2yYoR!ElR26mi-iGqx5WU3YJks8ViINKEE_wlv1Y32Mil6UEU

2013-01-07

国内域名快要到期

八年前不懂事,通过国内商注册了域名,而且后来图便宜一下子续费了好多年。于是 superliufa.com 这个域名一直要到 2013 年 01 月 10 日才到期。当时看来是很久远的事情,不过现在看来大限就快到了。

根据以前过期的域名看来,该国内商有个流氓措施,就是会在域名过期后自己掏钱续费一年,但是收回所有管理权限,让你没法马上转移。不过我不着急呀!我的网站,一不用来挣钱,二不用来炒流量。一年后咱们走着瞧,奸商您要是兜里有俩闲钱咱们就再斗个一年,爷生命线挺长,耗得起。

不过,如此一来,这个架在 Blogger 上的博客,墙内的朋友很快就要无法访问了。墙外的地址是 superliufa.blogspot.com,届时(2013 年 01 月 10 日后)我将会取消博客上的自定义域名选项,这样首页就不会再跳转到 blog.superliufa.com 了。要翻墙的赶紧啊!可以参考我的 翻墙系列文章(虽然还不多),千万别输在起跑线上哦!