从密码学的角度看腾讯QQ通信协议

0.分析目的

制作一款命令行QQ软件。可以在命令行下登录qq,以及处理一些简单的文本消息。

1.怎么通信

A->server
server->B

2.采用何种协议

QICQ:用于更新数据库中的状态(在线,离线,隐身…),
传递对称加密的密钥(sessionkey)。
UDP:data本身是经过加密的。用上一步得到的sessionkey进行加密。

3.攻击者的角度

  • 唯密文攻击
  • 已知明文攻击
  • 选择明文攻击
  • 选择密文攻击
  • 选择文本攻击

4.猜测的登录流程

M=…+QQ密码+…
client A:
tea(M);

5.别人分析的流程,不知道真伪

https://blog.csdn.net/mingzznet/article/details/46910437

6.OICQ协议分析

命令字 解释

1	log out	
2	hert message
4	跟新用户信息	
5	搜索用户
6	获取用户信息	
9	不需认证方式添加好友
10	删除好友	
11	需要认证的方式添加好友
13	设置隐身、示忙等状态	
18	确认收到系统消息
22	发送消息	
23	receive message
29	request key	
39	get friend online
60	group name operation	
62	memo operation
88	download group operation	
92	get level
101	request extra information	
103	signature operation

7.wireshark分析

QQ发送消息用的是运输层的UDP协议。

而登录,初始化协商对称加密密钥,服务器端不断地验证客户端是否在线同时客户端不断地索要服务器端自己的好友数据这些则用OCIQ协议完成。

8.结构体

在这里插入图片描述

typedef _oicqhdr {
    uint8_t flag;
    uint16_t ver;
    uint16_t command;
    uint16_t sequence;
    uint32_t qq;
} __attribute__((packed)) oicqhdr;

9.实战中获取到的信息

1>qq客户端如何获取QQ服务器端IP地址

qq客户端怎么知道腾讯的IP?
通过DNS协议。
目前检测到的tencent的域名有,(域名是腾讯写死在软件里的)

sz.tencent.com
sz2.tencent.com
sz3.tencent.com
sz4.tencent.com
sz5.tencent.com
sz6.tencent.com
sz7.tencent.com
sz8.tencent.com
sz9.tencent.com
rs.qq.com
rs7.qq.com

对应的几个IP地址池:(1类IP)

123.*
111..*
125.*

通过不让QQ登录成功来得到结果

2>想象一下登录流程

登录其实就是从tx的服务器池里面选出了一台机器进行处理你的消息。
这些服务器应该是类似于docker形式部署的实例
一个IP就只服务一个用户吗?
通过网上的数据,qq月活跃用户数达到了7.07亿,
也就是7.07 * 10^8
而假设以111.*.*.*为例服务用户,那么共有2^24=16,777,216个机器。
即使使用1类IP地址,也还是无法解决如此大的用户量。
那么复用是必然的。
可能一个用户掉线后立马回收这个资源给另一个用户使用。
服务器端接受消息,那么服务器端必然不能只给一个用户使用。那样太浪费了。
综上所述,登录QQ就是从tx的服务器中找一台为自己服务。这台服务器可能还同时为其他人服务。然后自己下线后,这个服务器就会将自己保存在服务器上的数据进行转存等等。情空你的信息后为其他人服务。
嗯,应该是这样。

3>联想一下怎么得到QQ好友的地理位置

A和B通信。需要经过tx的服务器转发。

但是A,B都是在内网。那么他们上网会获得一个临时的公网IP。腾讯服务器就会记录这个IP。干什么呢?

假如A和B要直接通信,(为什么不中继转发?这样会对服务器造成压力很大。)

那么就通过tx的服务器告诉对方的IP地址。
这样就实现了判断好友在哪儿。

10.算法搜集

tea算法,md5加密算法。

11.参考资料

https://wenku.baidu.com/view/241747906bec0975f465e25e.html

12.大致思路

Login verify:客户端向server发送
Login verifyUDPpacket = key2 + Tea(key2,Tea(key1,PlainUDPPacket))

这个算法好像3des?
用了两个密钥,而且密钥2还是公开的。
密钥key1只有用户自己知道,就像私钥。
引入key2纯属为了防止穷举暴破。
穷举的时间复杂度为2^(key1和key2的有效位数求和)

已知key1=MD5(MD5(password)+QQ号))
现在key1,key2已知,可以得出PlainUDPPacket.
PlainUDPPacket中包含login_verify_key.
tx为什么要对PlainUDPPacket加密?且和用户的密码绑定?一定有不可告人的秘密。
Login verify key:服务器返回的报文。
发送报文后服务器返回的报文。使用login_verify_key解密可以得到login_verify_reply_key.
Login session:服务器发回来的报文。
使用login_verify_key可以解密得到session_key.

13.软件怎么做

  • gocui
  • go command line UI.做界面的。
    https://github.com/jroimartin/gocui
    可以先做一个命令行的UI界面。
    然后将QQ的一些东西封装进函数。
    按下按键就会激活相应的功能。
    先建立一个仓库吧。
    https://github.com/jroimartin/gocui
    https://github.com/happysmile12321/lazyqq.git

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值