http://www.iprotocolsec.com/2012/02/28/qq%E5%8D%8F%E8%AE%AE%E5%88%86%E6%9E%90%E5%8F%8A%E5%85%B6%E8%BF%98%E5%8E%9F%E4%BA%8C/
QQ协议分析及其还原(二)
上一篇讲到了QQ协议的Header部分,这一篇主要讲密钥生成及其交换的过程。
QQ登陆协议密钥交换过程,首先我们使用Wireshark抓报文分析,观察主要用到的命令字(见上一篇Header部分的介绍)。
命令字 | 含义 |
1、Touch Information(0×0091) | 根服务器SAY HELLO,如果对该报文做一些小动作,可以让QQ认为,TX的服务器或网络不能访问… |
2、Login Request(0x00ba) | 未知,可以不进行处理。 |
3、Login Verify(0x00dd) | 向服务器发送登陆请求,需要使用密码进行运算作为密钥才能机密该报文,解密的报文中包含对第4步的解密密钥。 |
4、Login get Information(0x00e5) | 未知,但是服务器返回的报文你必须得知道,因为这个报文中包含解密会话密钥报文(第6步)的密钥。 |
5、Login verify E3(0x00e3) | 未知,可以不进行处理。 |
6、Login send Information(0×0030) | 客户端向服务器发送sessionKey,使用第4步获取的密钥进行解密。 |
1、Touch Information(0×0091)
这个报文无需关心,是客户端向服务器在SAY HELLO…
2、Login Request(0x00ba)
未知,在此处并不重要。
3、Login Verify(0x00dd)
非常重要!!获取会话密钥首先得解密该报文。但是要解密该报文,必须得知道该登陆QQ用户的密码,而用户密码只有用户和TX知道,第三方是不知道的(也有可能存在“不可思议”的第三方…)。数据传输过程中使用的加密算法是blowfish,这个算法目前从公开的资料上来说,还没有发现漏洞。因此,要实时获取用户的聊天信息,除非已经知道密码了,或者已经暴力破解了密码(这里简单介绍一下怎么进行暴力破解,这里的暴力破解,当然不是模拟一个QQ客户端不停的向TX服务器发送登陆请求,这样太慢了,而且TX那边也会有记录。首先,得分析出这个报文的密钥生成算法[不是简单的直接使用密码作为密钥],加密算法(这个已知,是blowfish),第二,需要将对方的登陆报文截取保存到文件,然后写一个程序,不停拼接字符串、数字、标点符号进行组合,根据第一步分析它密钥的生成方法生成出密钥,然后作为blowfish算法的密钥,去解密报文,如果解密成功,恭喜你,你暴力破解到了一个QQ密码。但是这种概率比较小,即使有一些,这些号码的价值不大,扯远了…)。
LoginVerify报文的解密密钥生成方法,在QQ2011版本之前,是MD5(MD5(PWD)),对QQ的密码做了两次MD5运算。但是QQ2011版本(包括2011版本)之后,这个算法做了一点修改,就是:MD5(MD5(PWD+QQ_NUM)),这个修改其实是非常有必要的,为什么呢?因为随着硬件技术的发展,以及前些年MD5彩虹表的推出,简单密码的MD5值非常容易就能从彩虹表中找出对应MD5值,从而得到原始字符串密码,即使TX做了两次的MD5运算。在彩虹表的推出或以前(因为我也不知道是在这以前还是以后,呵呵),在执行MD5运算时,就有了加SALT的说法,很形象!加盐,在这里,QQ_NUM就是盐,这样就加大了使用彩虹表破解的难度。
使用密码根据以上的算法得出解密密钥,解密Login Verify报文后,会得到一个新的密钥,这个密钥暂且就叫做verify_key。
Login Verify Reply(0x00dd)
服务器对客户端Login Verify报文的响应,这个报文需要verify_key作为密钥进行解密,得出一个新的密钥-verify_reply_key。
4、Login get information(0x00e5)
客户端接收到服务器的Login Verify Reply报文后,会使用verify_reply_key加密数据发送到服务器,而这里面又包含了一个key – get_info_key。
5、Login verify E3(0x00e3)
未知,此处可以不进行处理。
6、Login send Information(0×0030)
使用get_info_key解密该报文,得到会话KEY – session key。
回想一下:密码是关键,有了密码才能解密Login Verify(0x00dd)报文,解密了Login Verify(0x00dd),才能解密后续的的报文。其步骤是:passwd -> verify_key -> verify_reply_key -> get_info_key -> session_key。