郁闷!研究了一下Sogou的代理服务器验证协议

昨天晚上收到一条来自13800138000的信息,说过手机卡没钱了,不足扣除月租,然后就停机了!这可是令我大吃一惊的,前几天才充够了85元等着扣月租,今天一查卡上余额只有25元,几天之内我可怜的60元飞到哪里去了?上网查了一下清单,发现CMCC的WLAN因为超时上网,额外抽了我50多元……本来这个套餐才20元。另外还有个啥移动梦网抽的10元就不说了……我郁闷啊!用超时了也不给我一个提醒,还帮我正常登录,正常使用……真想骂人,又骂不出来。移动多我一个不多,少我一个不少,唉!
废话说太多了,不过说出来我心里也舒服了-_-! 没这事就不会无聊到去支持Sogou浏览器……

下面进入正题:
打开Sogou浏览器,用教育网访问外部网的时候,直接是连不上的,必然要经过Sogou的代理服务器中转。如何获取代理服务器列表,如何判断网络类型等不是我想要讨论的内容。下面仅说说它如何验证客户端身份

GET http://xiaoxia.org/ HTTP/1.1
Accept: application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
Accept-Charset: GBK,utf-8;q=0.7,*;q=0.3
Accept-Encoding: gzip,deflate
Accept-Language: zh-CN,zh;q=0.8
Cache-Control: max-age=0
Connection: keep-alive
Host: xiaoxia.org
Proxy-Connection: keep-alive
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.3 (KHTML, like Gecko) Chrome/6.0.472.33 Safari/534.3 SE 2.X MetaSr 1.0
X-Sogou-Auth: 9CD285F1E7ADB0BD403C22AD1D545F4A/30/853edc6d49ba4e27
X-Sogou-Tag: f19f1ae7
X-Sogou-Timestamp: 4d7858f6

有些细心的人看了上面的HTTP内容,会发现一个奇怪的问题。好吧!我100%肯定上面这个HTTP头是搜狗浏览器发出去的,我只是用了Chrome的浏览器皮肤,但是没想到它的User-Agent都换了Chrome的……

一般来说,用于搜狗服务器验证的只有3个字段,X-Sogou-*。大致了解一下他们的意思,从名字上就可以看出来了。

X-Sogou-Auth是用于辨别身份,每个使用搜狗浏览器的用户,都有一串唯一的标识,就像序列号一样。这样人家公司才容易统计他们的产品到底有多少人使用,客户群有多庞大,群体中主要是哪类人,身高,三围等,以便改善他们的产品服务!9CD285F1E7ADB0BD403C22AD1D545F4A这串东西看上去好像是md5生成的,但是如何生成的不是很清楚,可能是在第一次使用搜狗浏览器的时候就生成。它存在于Windows的注册表中,\HKEY_CURRENT_USER\Software\SogouExplorer\hid/30/853edc6d49ba4e27这一串暂不明,也不感兴趣。只要随机生成一串X-Sogou-Auth的内容,都不影响代理的正常使用。

X-Sogou-Timestamp如其名,就是北京时间的Unix Timestamp,在c/c++里通过time(0)函数获取即可。

X-Sogou-Tag是最头痛的部分,也是本文想要讨论的重点。每次发送的代理HTTP请求,它和X-Sogou-Timestamp一样都一直在变化。而且有时候X-Sogou-Timestamp不变,X-Sogou-Tag会变。使用控制变量法,经过多次发送的代理HTTP请求对比,得出以下结论:X-Sogou-Tag与Host和X-Sogou-Timestamp有关。可能是它们组合的Hash函数。我猜测是CRC32,不过后来验证发现我的猜测是错误的!

下面直接查找一下生成X-Sogou-Tag的代码:

1、用OD打开搜狗浏览器,运行之后,搜索X-Sogou-Tag字段!

2、发现在sogounet的只读数据段里找到了字段,设置访问断点!

3、在搜狗浏览器中随便打开一个外部网,会在某处发生内存访问中断,然后单步执行,到达下面这个地方:

4、运行到上面这部分发现已经生成了X-Sogou-Tag,现在是需要找出生成这个Tag的函数。于是往回找,在上面所示的函数前面部分下断点,然后单步调试,观察堆栈的变化。

5、找到一个函数调用CALL sogounet.0411F1F0,调用之后,通过一串字符生成了一个Hash,通过比较返回值,就是X-Sogou-Tag的字符串内容。跟踪进入该函数。

6、CALL sogounet.0411F120返回的是32位的无符号整形,接着使用“%08x”的格式转换为字符串。

7、进入sogounet.0411F120,最终确定该函数就是生成X-Sogou-Tag的Hash函数。输入的字符串格式是[Timestamp][ProxyHost][SogouExplorerProxy]

看来生成X-Sogou-Tag也不是一个简单的表达式,似乎找不到什么规律,也首先否定了它是CRC32的可能性。很可能是核心开发成员自创的一套验证方法,防止自家的代理服务器被盗用。

下面是我逆出来的C++代码,因为水平有限,只能逆成这般样子了……

没有贴出完整的代码,有兴趣的同学自己研究一下吧!会学到不少东西的哦:-)

最后,验算一下是否正确:

郁闷!研究了一下Sogou的代理服务器验证协议》有22个想法

  1. Creke

    蛋疼把算法写进polipo,发现会有一定的几率算不对Tag,不知道Python版本以及您在使用过程中有没有发现类似问题?谢谢

    回复
  2. Pingback引用通告: 更新 "西工大的猫" 1.4 | 李劼杰的博客

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据