作者:charytang
联系方式:Email: [email protected] QQ:3398171
创建时间: 2007 年 7 月 31 日 星期二
本文以QQ2007Bate3版本(0x1051)为例,介绍QQ2007的登录认证过程与之前版本的变化。本文是以学习为目的的技术研究,不涉及任何商业利益。任何企业和个人与此文有关的商业行为,请与腾讯公司联系。
本文的协议分析过程为黑盒方式,必然会存在不准确的地方,故仅供读者参考。同时,本文借鉴了很多互联网中流传的技术资料,在这里就不一一列举!
转载请注明出处!
本文使用到以下名称,在这里解释一下,方便读者理解
名称 |
描述 |
临时密钥 |
即可以在数据包中直接提取的加密密钥,一般是数据段的前16Bytes。 |
密码密钥 |
QQ密码,经过两次MD5散列后的16Bytes字符串 |
会话密钥 |
登录认证成功后,协商出的密钥(16Bytes),用于后续报文解密使用。 |
CèS |
表示从客户端发向服务器端的报文 |
SèC |
表示从服务器端发向客户端的报文 |
MD5 |
一种不可逆的散列算法,详细资料问google |
TEA |
一种简单(微型)加密算法,QQ的主要加密方法,详细资料还是问google |
B3 |
指QQ2007Bate3版本 |
在B3(好像B2就变了,但没分析)中,登录认证过程发生了较大变化。主要是将密码验证的过程提前在0xdd中完成,之前版本应该是在0x22中完成。同时0x22(CèS)不再是简单的临时密钥加密,而是在0xdd(SèC)中产生密钥,这个包可是密码密钥加密的哦:)
|
|
2007Bate1及之前版本 |
QQ2007 Bate3版本 |
|||
命令 |
方向 |
功能 |
解密 |
功能 |
解密 |
key |
0x91 |
CèS |
找服务器 |
临时密钥 |
找服务器 |
临时密钥 |
前16Bytes |
SèC |
找服务器 |
临时密钥 |
找服务器 |
临时密钥 |
使用上面的 |
|
0x62 |
CèS |
请求登录令牌 |
未加密 |
请求登录令牌 |
未加密 |
- |
SèC |
响应登录令牌 |
未加密 |
响应登录令牌 |
未加密 |
- |
|
0xba |
CèS |
请求登录令牌 |
临时密钥 |
请求登录令牌 |
临时密钥 |
前16Bytes |
SèC |
响应登录令牌 |
临时密钥 |
响应登录令牌 |
临时密钥 |
使用上面的 |
|
0xdd |
CèS |
无 |
|
密码验证 |
临时密钥 |
前16Bytes |
SèC |
无 |
|
响应密码验证 |
密码密钥 |
MD5(MD5(PW)) |
|
0x22 |
CèS |
登录请求 |
临时密钥 |
登录请求 |
临时密钥 |
在0xdd SèC 包中 |
SèC |
登录响应 |
密码密钥 |
登录响应 |
密码密钥 |
MD5(MD5(PW)) |
与之前版本基本没有变化,如下:(UDP承载情况,TCP自己分析去吧,差不多!)
CèS:
字节 |
描述 |
0 |
0x02,报文开始 |
1-2 |
版本号,如2007B3为(0x1051) |
3-4 |
命令 |
5-6 |
序列号 |
7-10 |
QQ号 |
11-N |
数据段,基本是加密的 |
N+1 |
0x03,报文结束 |
SèC:
字节 |
描述 |
0 |
0x02,报文开始 |
1-2 |
版本号,如2007B3为(0x1051) |
3-4 |
命令 |
5-6 |
序列号 |
7-N |
数据段,基本是加密的 |
N+1 |
0x03,报文结束 |
原始数据包的构成基本与原来的版本一致,但略有不同。目前发现在0x22、0x18命令时会在数据段前增加一些结构数据,后文分析。
下面只分析数据段的内容,其它不提了。
此过程客户端会向多台服务器发送查找服务器请求,每个服务器响应是否会接受此连接,如果不接受则返回重定向的IP。
原始数据段为0x30字节,其中前0x10为key(临时密钥),后0x20为密文数据。
初始客户端会发送 15个0x00,作为尝试连接。
后续的请求解密后格式如下
00 01 01 00 00 00 03 00 00 00 00 3a 3c 0e 21
后4Bytes指出从哪个服务器IP定向来的。
密钥使用CèS时的临时密钥。
返回数据分为两种:
密文长度为0x20字节,解密后如
00 01 01 00 00 00 03 00 00 00 00 3a fb 3f 39
开始的00 01 应该表示此服务器不接受连接,指向下一服务器(后4Bytes为 IP)。
密文长度为0x10字节,解密后如
00 00
表示此服务器成功接受连接,不再重定向。
[注:可能会有多个服务器接受连接,客户端一般会选择第一个成功接受的服务器]
这部分与之前版本没什么区别,简单说一下吧。此过程不加密。
数据段为 1Byte 的0x00
数据段为0x 1A Bytes,前0x02 Bytes为令牌长度,后0x18为令牌内容。
00 18 0B 3B AE 38 09 11 99 1F C 0 A 3 A 7 C 1 CD 14
14 27 94 E4 66 EF 7C 3A 3D 8E
数据段为0x40 Bytes,前0x10位临时密钥,后0x30为密文内容。解密后内容为:
18 0b 3b ae 38 09 11 99 1f c 0 a 3 a 7 c 1 cd 14 14
27 94 e4 66 ef 7c 3a 3d 8e 03 00 05 00 00 00 00
00 00 00
第0 字节: 0x18 为令牌长度
第1-24字节:为令牌内容,其实就是0x62(SèC)服务器返回的令牌内容。
第25-34字节:应该是子命令集吧,具体不知道了(固定的)。
注:此数据包客户端会重复连续发3次。
密钥使用上步CèS时的临时密钥。密文长度为0x30Bytes
服务器会返回3次响应,解密后分别为:
03 00 05 00 00 20 4f 50 84 57 e1 ad dc c2 d 9 f 4
3e ca 22 5f 22 01 f 2 25 62 45 a 6 7f 32 5b 20 2c
80 21 96 56 d1 aa
03 00 05 00 00 20 8c 2c 78 00 ea bf ce c2 db 58
d2 bc 98 7a bc cf 28 bb 66 36 92 59 09 91 44 2c
8d 20 b0 81 55 41
03 00 05 00 00 20 da 71 25 30 2d 5c d0 64 5d ae
86 d5 14 86 e1 07 5e ec 3d bb 29 78 82 08 20 f 4
98 3d a2 5e 4e 38
第0-3字节:命令集,固定的
第4-5字节:令牌长度
第6-37字节:为令牌内容
服务器3次反馈的令牌内容不一样,第一次的令牌内容在后面还有用,其它两次的不知道有什么用了。
这部分应该是B3(或B2)新增的命令,用于密码验证,比较重要。
数据段为0xE8 Bytes,前0x10Bytes为临时密钥,后0xD8为密文内容。
解密后内容为:
00 5f 00 00 08 04 01 e0 20 4f 50 84 57 e1 ad dc
c2 d 9 f 4 3e ca 22 5f 22 01 f 2 25 62 45 a 6 7f 32
5b 20 2c 80 21 96 56 d1 aa 00 20 89 39 98 fa 02
65 45 77 c 8 90 9c 29 90 71 12 d1 82 9e 01 a 6 67
73 0f bc 9a f8 d9 d 1 c 8 9e 3b fa 00 14 7c 7d 42
ce f3 32 e5 b2 9d 8e 4d d6 cc 66 31 50 cd fb 1f
d9 00 67 00 10 51 00 ba 5f 15 00 33 da 1b 57 ce
b6 05 31 d7 16 b9 df ae 2e d2 ab 42 c 7 4a f 4 f 3
c7 09 f 1 26 f 9 e 4 a 9 a 2 63 db 1f 28 9c a 6 f 2 ad
53 24 e6 70 78 d 1 f 4 9f b1 23 66 7c 1b 87 f 3 3a
c9 37 9a 76 f 5 63 83 ad 23 d0 59 02 42 0c 03 00
a 3 ac c9 cf b4 ce b 5 c 4 b 5 c 7 c 2 bc b7 bd ca bd
ce aa a1 be b 3 f 5 ca bc b 5 c 7
第0-7字节:命令集,固定的
第8字节:0x20令牌长度
第9-40字节:令牌内容,就是0xba(SèC)第一次服务器返回的响应内容。
第41字节:0x00 分隔符
第42字节:0x20 密码验证串长度
第43-74字节:就叫密码验证串吧。比较重要啊!下面再介绍构成方式。
第75字节:0x00 分隔符
第76字节:0x14 长度
第77-96字节:不知道干什么的,不固定
第97字节:0x00 分隔符
第98字节:0x67 剩余字符长度
第99字节:0x00 某种标示,固定的
第100-101字节:0x1051 版本号,这里是B3版本
第102-103字节:0x00ba 子命令,请求登录令牌
第104-105字节:0x 5f 15 序列号,随机的
第106-109字节:QQ号
第110-125字节:令牌临时密钥
第126-173字节:密文登录令牌,可以用上面的密钥解开的。
第174字节:0x03结束符,其实从第99-174字节就是0xba(Cè S)的密文。估计TX吃饱撑着了,在这里又发一遍!我们的网络带宽就是这么被吞噬了!
第175字节:0x00 分隔符
第176-201字节:是一段中文编码,大概意思是“上次登录方式为【初始登录方式】”,没显示全过,不知道干吗用的。
再说一下上面提到的密码验证串0x20字节的构成方式。
基本思路是:先用密码密钥TEA算法解这0x20字节,解得到0x14字节。而这0x14字节中的前0x10字节,是密码进行一次MD5的结果;后0x04字节是随机数。在这里就不写解开的内容了,结构简单(其实是怕算出我的PW)。由于在这里是登录过程中第一次使用到密码密钥,所以推论应该是在进行密码验证。
数据段长度为0xA8 Bytes,全部为密文。密钥使用密码密钥(如果密码错误则用临时密钥解)。
解密后内容为:
00 97 00 00 00 6d b9 00 20 77 fd ab d6 75 30 5e
03 01 4c 66 9d ce 39 fc ca 0a a7 49 14 ac 15 aa
29 95 89 f 5 1a 81 55 6e bf 00 20 fc 14 62 d4 af
8a a4 88 0b 31 be 69 16 ec a2 29 b9 28 d1 0a a4
f1 b3 28 5d 56 c 6 ad 30 df 68 5c 00 38 09 67 8b
18 df 18 ba b1 6d e 4 a 3 42 7e dd 5e 3d 68 77 2f
6b 77 ba 9f 6b 75 10 ae 90 cc cb 87 1e 74 cf 48
5b 27 ec ec df 62 cc 70 6e 01 81 0b 90 14 d9 1d
51 e2 2d 29 27 68 63 63 65 35 65 57 56 63 61 4e
43 38 65 53 32 00 00 00 00 00 00
第0-7字节:子命令集
第8字节:0x20长度
第9-40字节:内容未知;
第41字节:0x00 分隔符
第42字节:0x20长度
第43-74字节:内容未知;
第75字节:0x00 分隔符
第76字节:0x38 长度
第77-132字节:此段内容将在0x22(Cè S)数据段已明文形式出现,作用不明
第133-148字节:这0x10字节重要啊!将是0x22(Cè S)的临时密钥。
第149-154字节:6个0x00 ,应该是填充字节。
这部分的数据段也有新的变化,数据段长度改变,解密后内容也有变化。
数据段长度为0x 23A Bytes(不确定是定长),密文结构为:
第0-1字节:0x0038 长度
第2-57字节:作用不明,即0xdd(Sè C)解密后的第77-132字节。
第58字节到结束:为密文内容;
其密文内容用0xdd(Sè C)第133-148字节作为临时密钥进行解析。
解析后内容为:
00 00 00 20 a 8 93 88 38 c 4 db 10 d2 1c 89 54 77
75 b1 9d a 9 c 7 1b 3f 91 bb ec 62 e2 d7 60 61 1c
cf cf 97 7e 57 22 c 9 78 f 9 c 8 51 e2 18 1a 28 eb
5f 98 07 d5 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 73 19 5b e2 0d 81 e0 be ae
df 60 39 b8 44 6b e 9 c 4 28 00 00 00 00 00 00 00
00 00 00 00 01 01 00 00 00 03 00 00 00 00 3a 3c
0e 21 fc bc 0a d 4 c 4 6e ea 4c a7 72 75 45 8a 65
e 5 f 7 20 4f 50 84 57 e1 ad dc c2 d 9 f 4 3e ca 22
5f 22 01 f 2 25 62 45 a 6 7f 32 5b 20 2c 80 21 96
56 d1 aa 00 00 00 06 00 00 00 00 00 00 01 40 01
68 a 6 05 d4 00 10 6c 73 8f 7f 01 53 7d a6 1f e8
ca 03 22 5e a8 fd 00 00 00 00 00 00 00 00 00 00
00 01 01 00 00 00 03 00 00 00 00 3a 3c 0e 21 02
8a 65 96 50 00 10 8f 36 b 2 c 6 af 1f 40 1d a4 e4
aa 34 2c ba ef 1c 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
第0-2字节:为0x00
第3字节:0x20 长度
第4-35字节:作用未知,不固定内容
第36-51字节:这0x10Bytes,是密码两次MD5后作密钥,对空串进行TEA加密的结果。
第52-70字节:为0x00,未知
第71-86字节:未知,同一帐号每次好像都一样,基本固定;
第87字节:随机变化
第88字节:登录模式,0x28隐身,0x 0a 上线
第89-98字节:全0x00
第99-113字节:是命令0x91(Cè S)解密后内容。
第114-129字节:这0x10字节,未知
第130字节:0x20,长度
第131-162字节:这0x20字节,命令0xba(S è C)第一次响应的密文内容。
第163-180字节:未知
第181字节:长度
第182-197字节:未知
第198-207字节:全0x00,作用未知
第208-222字节:同第99-113字节;
后续字节,未仔细分析,大部分都是0x00
数据段长度为0xF0 Bytes(不确定是定长),密钥为密码密钥,解密后内容为:
00 54 56 74 49 4a 56 52 49 70 48 56 57 72 56 55
39 00 33 da 1b 7b 74 86 a 6 46 d1 7f 00 00 01 1f
40 46 9e d6 02 03 0a 00 00 7a 22 25 55 a 1 bf bd
69 9c 1b 31 f 1 4e 58 ff 40 8c 73 4f f4 05 25 78
cf bf d 6 ac 10 c 0 0a 1f 40 da 55 8a 43 1f 40 00
81 40 46 00 00 10 00 a 7 ad 98 e3 0a ec 2f d9 58
17 53 0b 49 4d 7a 95 73 86 5e 3d dd dd ec f4 fc
1b 5a 52 0c 40 35 91 ff ff ff fb 20 00 00 00 08
00 00 00 cc cc 6f af 46 9e d1 eb 46 64 f 2 e0 45
57 e5 d8 00 0a 00 0a 01 00 00 0e 10 01 14 8f fe
4f ba 30 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 08 02 04 08 08 08 08 08 04 02 00 28 26 a 8
24 ad ee 79 be c1 b6 cc 10 aa 38 02 55 a 1 1a 2f
58 8e c8 b2 32 a 6 ea 02 82 03 ac 22 07 25 70 13
ce 62 16 a 5 6b 43
第0字节:为0x00,表示登录成功
第1-16字节:为会话密钥,后续都靠它了。
第17-20字节:QQ号
第21-24字节:客户端IP
第25-26字节:客户端端口
第27-30字节:ip 127.0.0.1
第31-32字节:端口8000
第33-36字节:本次登录时间
后续字节,未仔细分析,是一些时间、IP、端口什么的。