|
概述 我所作的协议是在黑箱基础上面作出, 并参考了LumaQQ 的文档, 还有网上流传很广泛的一份文档, 以及中国协议分析网的部分资料。 所分析的结果仅供学习借签参考, 不能用于其他的违法行为。 分析环境 我在我的Linux 工作站(Redhat Fedore 3 + Linux-2.6.10) 上面安装了Vmware 虚拟机,然后在虚拟上安装了QQ2005beta2, 在我的Linux 中使用ethereal 抓包软件。 下图:

QQ 加密算法
QQ 协议中用到算法有MD5 算法,用它来生成密码的HASH 串,然后有用来加密传送数据的TEA 算法,推荐的TEA 算法应该是32 轮,但是QQ 目前就使用了16 轮,TEA 是通过增加加密算法的轮数来提高安全性的, 不是使用复杂的算法。
网上有许多的资料关于这两种算法。由于下面会有代码分析, 所以我们这里给出我的MD5 算法和TEA 相关算法:下面是我的MD5 实现:
QQ 数据报文
QQ 的数据通过UDP 方式传送,就是说每个独立的报文长度不会大于64K,发送到QQ 服务器的8000 端口(默认)。
所有的QQ 发送的数据报文格式如下:
字节内容以及说明 0 报文的开头, 所有的报文以0x02 开始 1-2 两个字节的以网络字节顺序表示的QQ 版本号 3-4 两个字节的以网络字节顺序表示的命令号 5-6 两个字节的发送序号,接收回应的时候必须效验这个序号, 其实这个序号可以随机生成,我认为。 7 -N 具体的数据,可能加密,也可能不加密,这里的数据要看具 体的情况 N+1 报文的结束,必须以0x03 表示
QQ2005beta2 版本代码
下面的分析这个版本QQ 的版本号码是0x0d51
获取登录令牌
QQ2005beta2 登录的时候首先会发送一个请求,向服务器请求登录令牌,目前这令牌是
24 个字节,但是其实可以是其他的,要看服务器发回给我们的数据了。我抓的数据是13 个字节,如下:02 0d 51 00 62 1a 15 14 c5 aa ea 00 03 02 是报文的开头,0x0d51 是版本,0x0062 是请求Lgin Token 的命令我登录的QQ 号码是348498666,表示位网络字节是0x00eaaac514 0x1a15 是序号
请求格式如下:
字节内容 0 0x02 报文开始 1-2 网络字节的QQ 版本0x0d51 3-4 请求登录令牌的命令号0x0062 5-6 序号,可以是随机的 7-10 网络字节顺序的QQ 号码 11 0x00 12 0x03 报文结尾
如果成功会收到到服务返来的数据,这时候需要检查数据的命令类型是否也为0x0062 并且序列号是否是发送时候采用的序列号,如果不是,表示有错误,可以继续接收下一个包,直到超时!
目前我们抓到回应数据一般是34 字节,
回应的格式如下:
字节内容 0 0x02 报文开始 1-2 服务器标识,0x0000(一般是) 3-4 0x0062 5-6 序列号,和刚才发送采用的是一样的 7 0 表示成功 8 令牌数据的长度(现在是24) 9 – N 令牌数据 N+1 0x03 报文结束
下面是我们获取登录令牌的实现:
/* 这个函数用来获取登录令牌*/ int qq_request_login_token(struct qq_client *qc,unsigned char*token) {
unsigned char buff_tx[65535]; /*64K 数据发送缓存*/ unsigned char buff_rx[65535]; /*64K 数据发送缓存*/ int len = -1; fd_set fds; struct timeval timeout; int e = -1; uint16_t tmp16 = 0; uint32_t tmp32 = 0; uint16_t seq = rand(); /*我们随机生成序号*/
/*检查传入的参数*/ if(!qcqc->server<0!token){ return -EFAULT; }
/*清零数据是个好习惯!*/ bzero(buff_tx,sizeof(buff_tx)); bzero(buff_rx,sizeof(buff_rx));
/*构造发送数据*/ /*0x02 表示报文开始*/ buff_tx[0] = 0x02; /*QQ 版本号码 0x0d51 是QQ2005beta2 */ *((uint16_t*)&buff_tx[1]) = htons(0x0d51); /*0x0062 表示登录令牌请求*/ *((uint16_t*)&buff_tx[3]) = htons(0x0062); /*序号*/ *((uint16_t*)&buff_tx[5]) = htons(seq); /*QQ 号码*/ *((uint32_t*)&buff_tx[7]) = htonl(qc->id); /*这位设置位0*/ buff_tx[11] = 0x00; /*报文结束*/ buff_tx[12] = 0x03;
上一篇:命令行下可以解读TCP数据报内容的Sniffer
下一篇:QQ协议分析之TCPF包结构
|