前言
很早之前就逆向了DNF的通讯协议加解密算法,最近试了下利用其进行中间人攻击,并整理出此文。为防止对游戏环境产生影响,一些关键性技术细节已隐去。
本文仅作交流学习,请勿非法利用,损害相关公司的合法权益,如作他用所承受的法律责任一概与作者无关。若有侵权,请联系删除。
抓包分析
使用Wireshark抓包,设置好捕获过滤器,拿到进入频道的封包:
接收
00 01 00 be 01 00 00 3d 02 e7 a9 3d 02 e7 a9 00 .......= ...=....
7c d2 d6 d6 96 d2 be ed de b9 a6 9b 6d 02 91 1b |....... ....m...
45 73 ff 3c c2 30 a9 e4 39 8c 40 4a f9 6f 7c 4c Es.<.0.. 9.@J.o|L
4a b0 39 5d eb 1e fd ac e2 49 1d 25 a6 d9 6b d2 J.9].... .I.%..k.
省略若干行
发送
01 12 06 1d 00 00 00 30 7b ed e7 00 00 c3 5e a7 .......0 {.....^.
01 05 0f 2c 4b f9 87 6f 20 30 6d b5 7b ...,K..o 0m.{
接收
00 36 07 20 00 00 00 b4 23 af c8 b4 23 af c8 00 .6. .... #...#...
14 4b 37 b3 eb 09 e5 b1 46 e8 06 16 77 fc 8a 92 .K7..... F...w...
初步分析,前3个字节为封包类型,之后是4个字节的封包长度(带包头),然后是checksum。发送与接收的包头略有不同。
封包类型可以从客户端搜索"PACKET"字符串得到:
封包解密
从上文提到的ENUM_CMDPACKET_XXX等字符串入手,可以找到封包加解密的位置。
第一个封包是建立连接后服务端主动发送的ENUM_NOTIPACKET_CHANNELINFO
,加密为简单的位移与异或。根据调试分析,内容为一些频道信息及后续封包加解密的key。
除了该密钥包的位移异或以外,DNF还使用了14种加密算法,对封包类型取余数决定使用哪一种。
根据密钥、block大小,配合Detect It Easy
的“鲜明特征”功能可以快速定位每种加密算法。
封包头部
封包解密后,仍会遇到一些问题:
- 一些封包解密后仍为乱码,内容开头为0x78
- 一些封包无法解密,封包类型为ANTIBOT与DPROTO相关
第一个很明显为zlib压缩的文件头,同时观察到封包头部最后一个字节为0x01,判断后用zlib uncompress解密即可。
第二个为国服的加密协议,没有走DNF自己的加密逻辑,不需要进行加解密处理,排除掉即可。
整理出封包头部结构体如下:
#pragma pack(push, 1)
struct CS_Header
{
uint8_t cmd; //0为NOTIPACKET,1为CMDPACKET
uint16_t type; //封包类型
uint32_t length; //含封包头部的整个封包长度
uint32_t checksum; //CRC32,含seq
uint16_t seq; //序列id,自增
};
struct SC_Header
{
uint8_t cmd;
uint16_t type;
uint32_t length;
uint32_t checksum1;
uint32_t checksum2;
uint8_t compress; //压缩
};
#pragma pack(pop)
中间人攻击
为了修改DNF的封包数据,我用c#编写了一个简单的socks5 server,并使用Proxifier让DNF.exe走自己设置的socks5代{过}{滤}理。
测试1:修改封包内容
通过分析封包内容可知,ENUM_NOTIPACKET_USERINFO
为角色信息,包含角色名字、职业、等级以及武器等信息。这里以修改装备数值为例:
测试2:伪造收包
这里以BUFF封包为例。
加入公会后,可以获得一个工会buff,实际上为服务端发送ENUM_NOTIPACKET_CHARACTER_ADD_BUFF
封包给角色添加buff。
01 FD 04 00 00 00 00 00 00 00 00 00 00 01 00 00 00 90 4E 53 6C 00 00 00
猜测第二个字节开始为buff ID。尾部去掉padding,好像是有4个字节的checksum?
自行构造封包,通过代{过}{滤}理服务器发送给客户端:
可能客户端并没有校验尾部的checksum,亦或者它不是checksum,反正是生效了。当然,仅部分本地效果可以生效。
测试3:伪造发包
太懒了没做,需要修改后续封包的seq。(不知道封包尾部疑似checksum的东西会不会有校验,阿巴阿巴)
后记
理论上,破解了封包加密算法后,是可以制作出脱机外挂乃至模拟服务端的,但因为国服有Antibot组件,还需要处理它的加密算法。不过独立模块也可能很轻易被调用,还没有研究过。外服应该就可以很轻易脱机了。
关于服务端的模拟,视频不是很好上传。有心人自己找找可以在油管上搜到的。