西厢计划很好很强大,GFW还能拿什么来应对?

作者:observer  来源:http://obmem.com/?p=615

好久没看google reader了,险些错过了极其凶猛的一个翻墙工具“西厢计划”。
`

西厢计划原理的进一步思考

`
我看了西厢计划项目的wiki还是云里雾里的,好在youxu大大的西厢计划原理小解解释的非常清楚,在这里我也简单归纳一下,西厢计划就是在TCP建立连接之初通过插入发送完全符合协议的TCP包欺骗GFW连接已经终结,来达到穿墙的目的。原理据说如下图。

xixiang
`
根据“原理”的说法,张生同学实际上是利用了GFW本身的特性。(事实上,墙可以视作一种网络入侵检测系统,有着所有NIDS系统的弱点。)因为性能原因,墙作为一个旁观者,它无法做到对每一条TCP包都进行检查来过滤敏感词汇。tek4小组的大牛们,据说也就是西厢计划的探索者,经过长时间对墙的研究,发现墙很聪明地只会在连接发起的时候进行检测。
`
这样做是可以说的通的。中国的出国带宽应该早已破T,如果墙需要检查所有的TCP包,会是很大的负担。所以墙才会检查TCP会话的状态,当发现是死老虎状态时,直接放跑所有后继TCP会话。
`
然而我有一个百思不得其解的问题让我怀疑墙是否只在连接发起时进行过滤。我做了两个测试:
我建立了一个网页http://test.app-base.com/link.html,这个网页中含有falun词汇,并且有一个链接访问”/?falun”
测试1. 访问link.html。结论正常。
测试2. 访问link.html,再点击falun链接,结果被重置。
`
测试一结束后,我和服务器已经完成了三次握手,并且有来有回地发送了GET和获取了网页,这个时候我还有keep-alive属性,根据我对http 1.1的理解,这时候并没有终止TCP连接,而是立即回应了另一个请求,但是这个请求却被墙重置了,所以墙只在TCP连接发起时进行过滤这个说法我觉得有 问题。当然我对网络协议还是很一知半解的,有说错的话请及时更正我,谢谢。
`
按照我的上述实验来看,墙并非只在TCP连接发起时进行过滤,而是对每一个TCP包都做检查,发现是GET请求就进行过滤,发现是回应则PASS(至少测试1没有被过滤,如果它扫描的话那就说明基于不同规则。)
`
然而西厢计划的成功实施,说明墙是保存连接信息的,所以它在记录两个主机的连接“终止”以后,放跑了所有这两个主机间的流量。那么关键的问题是,如果墙取消这么一个设定,不“放跑”已经“终止”的两个主机之间的流量,会对墙造成很大负担吗?

`

如果会,那么墙想要干掉西厢计划还是很困难的;如果不会,那么修正这个破绽简直轻而易举。

`
上述问题等价于:实际应用中,是否有很多正常的应用会在RST终止以后还是罗里罗嗦地发送一堆包?出于网络延时我觉得RST以后确实可能会发送一堆包,但是这个数量相对于正常应用的TCP包来说应该是小巫见大巫。那么为什么墙要做那么一个古怪的限制呢?为什么墙要记录TCP连接状态,阻断连接以后就直接无视后续的包呢?
`
思索了半天,我所能想到的唯一一个理由就是墙那么做是为了避免DDoS攻击。 如果墙还要继续监控数据包,这可能会造成潜在的攻击点:攻击者不断地发送同样的数据包,墙必须一次又一次地拦截并且发送RST给攻击者,大规模地攻击下, 墙的过滤系统资源将被耗尽,从而无法进行正常的运作。而如果墙能够确认连接已经重置,就算仅仅是出于性能优化考虑,判断主机IP决定是否过滤也要高效得 多。
`

如果我是墙,会怎么应对?

1. 无视reset信号,不记录主机间的连接状态,所有TCP包都加入过滤。
`
这是最容易的一种处理方法,但是也是(据我推测)有安全和性能隐患的一种处理方式,理由见前文。
`
2. 记录三次握手序号,封锁西厢计划。
`
西厢计划骗墙认为receiver已经死老虎是通过发送一个序号不对的RST给sender,sender会无视,墙却会中招以为是死老虎。
`
如果墙想逮住”死老虎”,他必须记录sender给receiver的SYN/ACK握手的序号,并且和receiver再次返回给sender的ACK 序号进行比对才能确定这个是否是西厢计划的一次欺骗。从数据结构上来看,需要多保存一个SEQ号,这是一个32bit的数,相比原来多占1/3的空间;而 且如果墙是硬件实现的话(我觉得是),改变数据结构可不容易;从性能上来看,要多做一次主机的匹配和ACK序号的比对,性能开销也不小;而且墙一旦这么做 了,隐患更大,之前因为不太了解墙的工作模式,想攻击都没法攻击,既然你用这么个办法来堵漏洞,那我就有的放矢直接灌水各种RST信号,那么墙就真的悲剧 了。
`
看起来我觉得这种补救方式更加得不偿失。
`
3. 直接用IP封锁。(黑名单)
`
好像很犀利,不过可以直接通过代理绕过去,以前用代理因为有关键字过滤所以也没什么用,有了西厢计划,再加上代理,封IP就变得非常徒劳了。至于什么代理?什么都可以,squid、web代理、反向代理等、只要在墙外就行。
`
4. 白名单。
`
真的是大中华局域网了么,@@
这种情况下除非有白名单中包含国外主机,那还能通过代理出去,否则,就一个局域网怎么翻墙?这是最狠的一招,我觉得不太可能发生,但是永远不要低估某些人的脑残程度,万一……
`

为何不直接对内容过滤?从TCP协议的角度来看

`
根据我自己的测试,GFW似乎没有对内容进行过滤。不考虑处理能力的问题,理论上GFW似乎可以通过随机检查TCP包,然后发送阻断包终止连接。
`
然而他真的能发送阻断包吗?扫了一下TCP/IP协议,我发现它能干的事情有限。这是因为一旦连接建立,慢启动过后,TCP就开始高速运转 了,sender同时会发送n个包给receiver,墙截取了当前的包,发觉有问题,这时候他想干扰传输有两个选择,要么发RST,要么发FIN(RFC1122,4.2.2.13)。可是这时候墙无法推测下一个序列号,因为他无法知道该死的sender到底同时发了多少个包给receiver,只能靠猜。
`
但是并不是说墙没有办法,根据TCP协议的Flow Control部分,receiver 会给sender发一个windows size的参数,规定sender只能发那么多数据,之后要等待receiver的ACK表示收到。发送ACK表示收到的同时,receiver还会告诉 sender它的acknownledge number,表示他预期下一个序列号是什么,这时候墙就能能乘虚而入伪造RST/FIN数据给receiver了。
`
这又是一个复杂的实现+性能和安全隐患,我想这也是为啥墙一般不直接做内容过滤,而是更倾向于url扫描和dns污染的另一个理由吧。
`

结论

西厢计划很好很强大,让我看到了墙的脆弱性,随着对墙的越来越深入的了解,越来越多牛人加入翻墙的研究,墙终究会变得不堪一击。道高一尺,魔高一 丈。通过这次对墙的原理的学习,我突然觉得墙其实还是很千疮百孔的,并没有我原来想象的那么强大。就那么个破东西,国家花了无数纳税人的钱,只为了阻止纳 税人们了解真实的世界,唉,很是无语啊。
`
最后补充一下,我本人对TCP的了解仅限于学得很是不行的“计算机网络”的知识,而且因为从来不用基本忘光,如果狗屁不通错误连篇也请谅解,如果能指出错误就更好了。
`

3月22日更新

首先,tek4小组在完成西厢计划后已经解散,解散之后他们发布了对GFW和西厢计划的一个总结,更宏观地解释了GFW的应对方式,证实了西厢计划并没有那么强大,见参考资料11。
`
其次,由西厢计划得到启发,结合“第八组第三次作业”中提到的忽略RST穿墙法(参考资料12),西厢计划似乎可以简化实现,并且由于实施单方面忽略 RST而不是企图欺骗墙的关系,性能和无解程度会大大增强。如果和参考资料10的判断IDS结合起来,说不定会有很好的效果。
`
最后,第一次感觉不在墙内真是遗憾,那么有趣的技术没有办法实践,sigh…
`

3月23日更新

西厢计划出“第二季”了,其实和西厢计划没什么关系,可以说应该只是受到了西厢计划的启发。
`
这是一个很赞的实现,充分展示了墙的脆弱性,真是千疮百孔啊,未来没准第三季、第四季还会陆续有来。
`

参考资料

1. TCP协议
2. RFC1122(TCP部分,82-92)
3. IPv4
4. 西厢计划原理小解
5. 西厢计划提到的那篇论文,我扫了一眼居然发现了和我看了协议以后做的推理一样的某些段落,不禁小得意一下。
6. 穿越GFW的技术,很不错的总结。
7. GFW技术,研究与工具这个博客上面的内容都很有趣,值得一读。
8. 深入理解GFW,内部结构也是上面这个博客的内容,很强大。
9. NIDS网络入侵检测系统的缺陷。GFW作为一个NIDS,我们可以利用的漏洞都有总结,有些可以用,有些不行。
10. 一篇关于如何发现虚假RST攻击的论文,扫了一下觉得挺有用,以后可能用得到。
11. 原班人马对西厢计划弱点和GFW应对的解释,很有趣,我也算是千分之一了吧。
12. 第八组第三次作业中提出了直接忽略GFW的RST包也可以完成翻墙,结合参考文章10,我觉得西厢计划可以有更简单和更强大的实现。

没有评论: