Mar 21, 2010

HTTP URL/深度关键词检测

一项持续时间比张某还长的遗留研究。下面是它的开发研究简介,细节很多,非研究者可以略去不看。

HTTP URL/深度关键词检测

GFW的TCP协议阻断方式

GFW只根据单向的报文还原通信内容进行协议分析和关键词判断。并且在还原通信内容时,并不检查ack域的正确性,这也符合其“better is worse的设计哲学”,对于seq重叠的包,GFW的策略是忽略后来的包,因此利用GFW的这种流重组特性对其进行欺骗也十分容易。

一旦GFW根据还原出的内容检测到关键词,会根据触发关键词的包和关键词类型发送type1的RST或者type2的RST/ACK,在《入侵防御系统的评测和问题》中已经介绍,type2类型首次阻断中会先发送一组三个RST/ACK,序列号依次加1460、2920。type1与type2有所不同的是,type1首次阻断发送的RST的seq是关键词结束位置所在的包的ack,type2的seq则可能取为在此之前若干个包的ack,这可能与GFW处理报文的buffer大小和更新方式有关。在有些地区,单向发送内容触发type2关键词之后本地无法收到RST/ACK(对方可以收到),除非对方回复过任何设置了ACK选项的tcp包,另一些地区则本地总可以收到RST/ACK,原因还不清楚。这些问题希望有兴趣的读者自行研究。

特定情况下GFW还会伪造通信,例如type2的继发阻断中发送伪造的SYN/ACK企图劫持连接(为什么功能没有开发完全?),再如GFW的邮件检测模块对smtp协议的阻断会先伪造对方发送一条错误信息,再进行阻断。

URL关键词的检测

GFW的HTTP关键词检测模块的具体细节不是这里的重点,这里只回顾一些有关关键词检测的内容:

  • GFW有两种不相关的type、GFW结点的划分与TCP包的源端口无关、GFW时常有结点不工作、type1不工作的节点和type2不工作的结点不同。
  • URL关键词同样也有type1、type2之分。
  • 即使单向发送HTTP询问在一些地区可能无法收到GFW的type2 RST/ACK,实际上确实触发了关键词,会有90秒继发封锁。
  • 如果询问的格式是GET http://url HTTP/1.1\r\n\r\n,GFW进行关键词测试串的就是url。
  • 如果询问的格式是GET /url HTTP/1.1\r\nHost: hostname\r\n\r\n,GFW进行关键词测试的串就是.hostname/url。
  • GFW的HTTP URL关键词有普通的字符串关键词还有string1 && string2 && string3型的关键词,例如.google.com && great && firewall。只要url中包含这三个子串,无论出现的顺序如何,都会触发GFW。令人疑惑的是,string1*string2这种关键词匹配(在url中string1、string2顺序出现)判断实现起来要比string1 && string2容易得多,而目前已知的所有非普通关键词都是string1 && string2形式而不是string1*string2形式,是否存在string1*string2形式的关键词需要知道更多的URL关键词。

判断一个URL是否包含关键词的方法十分明了,选择一个跟本地IP分别在GFW两端的目标IP da,再任意选择一个不等于___的目标端口dp。对(da, dp)单向发送s;a;pa;s。(s = SYN; a = ACK; p = PSH)。为保证GFW按照顺序看到可以将每个包重复发送多遍,两组包间隔一定时间发送。如果触发了type1关键词可以收到GFW的r(RST),触发type2关键词可以收到GFW的sa。无sa或者无r,并不能说明不包含关键词,可能是GFW的相应结点不工作了。这时应该可以对此(da, dp)发送www.youtube.com来尝试触发。触发,说明原本确实没有关键词;否则说明GFW的相应类型的相应结点不工作了。

对关键词进行手工求解未免太过低效,利用GFW的单向报文检测特性,可以用来进行关键词检测的(da, dp)是几乎无穷多而且便于寻找的,让程序自动检测关键词非常可行。

  • 情况1、假定只有一个关键词。
    • 假设str长len,发起len个询问,第i个询问检测str去掉第i个字符形成的字符串。如果有阻断,说明这个字母可以去掉,否则说明这个字母不能去掉。询问完全并行。拿到所有结果之后可以立刻求出关键词。
    • 理想情况下只要1单位时间。
  • 情况2、假定所有关键词都是普通关键词,求出所有最小关键词。
    • 这种情况下可以进一步假定关键词是互不包含的子串,所以关键词可以定义前后关系。假设str长度为len,发起len个询问,第i个询问去掉前len + 1 - i个字符。求出最大的j使得在去掉前j个字符的情况下仍然有关键词。现在只需要求出从第j+1个字符开始的关键词,发起len - j个询问,第i个询问去掉后len - j + 1 - i个字符。现在求出最大的k使得去掉后k个字符仍然有关键词就完了。最后一个关键词就是str[j + 1..len - k],共花去2单位时间、询问。接下来处理str[1..len - k - 1] with hint: "开头位置 <= j",仍然是倒着测,有助于及时break。
    • 理想情况下时间等于关键词数目。
    • 为了减少(da, dp)的报废数目(短时间报废过多会被迫等待继发封锁结束),可以使用“二级索引”的办法:分sqrt(len)块,然后再精确到块内的位置。这样只是时间*2。
  • 情况3、&&型关键词、可能有多个,求出所有关键词。
    • 即使是求出其中的某一个关键词都是必须串行的,要花len的时间,难以忍受。但是实践中,.google.com && ** 和 search && ** 和 q=** 有可能同时是关键词,而询问作为www.google.com/search?q=**出现。由于此问题可由3-SAT规约到,是NPC问题,认为不可完成,所以从其它方面考虑:
      • 1. 根据经验假设只会出现2个&&,但实现带任意多&&的关键词的匹配算法上并不困难,GFW应该有相应的计算能力。
      • 2. 令s为{1..len}的一个随机置换,顺次考察s[i],如果去掉后仍然触发就去掉,不再触发就保留。最后可以得到一个关键词。多路并行应该就可以求出所有关键词了。尽管到达每个关键词的概率不均匀,实践效果应该可以接受。

深度检测关键词和其他关键词检测

GFW对所有通信进行了全文关键词检测,并且可以对gzip、deflate压缩的报文实现实时解压缩判断。进行这种关键词检测,需要事先准备好被测试文本。如果是某网页或者某文件含有深度检测关键词,需要将相应文件下载到本地。与测试URL关键字不同之处就是文件可以非常大。上面的方法几乎行不通。但我们希望先缩小关键词的寻找范围。希望根据GFW的r或者ra包的序列号来定位出现关键词的两个包,这样被检测字符串的长度就被缩小到了不到3000字节,就可以套用上面的方法了。

由于GFW的r和ra的seq是取自本地发出包的ack,只要对每个包按照发送顺序设置ack。

坑了(事实上)。

7 comments:

  1. The family is very important for us and I am sure they appreciate how you treat them.

    ReplyDelete
  2. sometimes you came across the posts, that gives you a new thought and a pleasant experience, and it is one of them.

    ReplyDelete
  3. This comment has been removed by the author.

    ReplyDelete
  4. small business telephone systems
    business telephone system
    telephone systems for business
    call centre solutions
    ip phone system
    contact centres solutions
    by www.reliancecommunications.com.au

    ReplyDelete