QQ协议分析及还原

最初,QQ通信协议并没有加密,而是直接采取明文的方式进行传输,到了后来才使用了加密传输,加密算法一直没有变过,使用的是blowfish算法,但是密钥的交换协议变得比较频繁。其实TX也是被逼的,现在的互联网用户比前几年更加注重隐私安全,这么大用户量的通信软件,如果用户与对方之间的聊天信息可以轻易的被第三方破译获取,那么用户量肯定会离开她,而去选择那些能够更加保护好个人隐私的人通信软件。因此,随着时间的推移和技术的发展,以前设计的协议可能会被研发者发现一些弱点,“图谋不轨”者加以利用,会对TX造成一些潜在的风险,他不得不对协议进行修改(QQ2011正式版中的密钥交换中对密码的MD5计算就加入了salt的概念,这个salt就是对应的QQ号码,后面会有详细的描叙)。

QQ协议首选的传输层是UDP,如果UDP不可登陆,那么会再尝试使用TCP进行传输。UDP使用的端口是8000,TCP使用的端口是443,应用协议基本一样,只是在通过TCP进行传输时,前两个字节为协议内容的长度(包括2个字节)。

QQ协议中每个通信内容都带有一个协议头部,如下图:采集失败,请手动处理

 

其中标识1一个字节,版本号、命令字和序号都是2个字节,QQ号码有4个字节,接下来是数据部分(已加密),最后是一个尾部标识1个字节。

在进行协议还原的时候,最关心的就是协议头部的命令字,需要根据不同的命令字,来进行相应的处理,最终获取密钥解密聊天内容。

 

QQ登陆协议密钥交换过程,首先我们使用Wireshark抓报文分析,观察主要用到的命令字(见上一篇Header部分的介绍)。

 

QQ2011登陆过程分析
命令字 含义
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。

前面两篇简单的介绍了QQ登陆协议密钥交换过程以及所使用的加密算法,知道了这两点,就可以对它的协议进行还原了。

QQDecrypt,通过winpcap抓包,实时对QQ聊天协议进行还原。采集失败,请手动处理

 

除了聊天协议之外,我们还可以对QQ相关的协议进行还原,包括但不限于:

1、QQ文件传输

2、QQ音频传输

3、QQ视频传输

4、QQ密码验证程序

5、QQ密码获取,是的,你没有看错,有一种主动的方法(用户登录时)就可以获得QQ的密码。在网络出口获取,而不是在客户端进行HOOK的方式获取。

阅读剩余
THE END