很早之前就逆向了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"字符串得到:

packet.png (854.32 KB, 下载次数: 2)
下载附件
packet
2021-12-18 17:05 上传
封包解密从上文提到的ENUM_CMDPACKET_XXX等字符串入手,可以找到封包加解密的位置。
第一个封包是建立连接后服务端主动发送的ENUM_NOTIPACKET_CHANNELINFO,加密为简单的位移与异或。根据调试分析,内容为一些频道信息及后续封包加解密的key。
除了该密钥包的位移异或以外,DNF还使用了14种加密算法,对封包类型取余数决定使用哪一种。

cipher.png (113.38 KB, 下载次数: 1)
下载附件
cipher
2021-12-18 17:05 上传
根据密钥、block大小,配合Detect It Easy的“鲜明特征”功能可以快速定位每种加密算法。

die.png (239.93 KB, 下载次数: 2)
下载附件
die
2021-12-18 17:06 上传
封包头部封包解密后,仍会遇到一些问题:
一些封包解密后仍为乱码,内容开头为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代{过}{滤}理。

proxy.png (214.63 KB, 下载次数: 1)
下载附件
proxy
2021-12-18 17:06 上传
测试1:修改封包内容通过分析封包内容可知,ENUM_NOTIPACKET_USERINFO为角色信息,包含角色名字、职业、等级以及武器等信息。这里以修改装备数值为例:

weapon.png (872.91 KB, 下载次数: 1)
下载附件
weapon
2021-12-18 17:07 上传
测试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?
自行构造封包,通过代{过}{滤}理服务器发送给客户端:

buff1.png (43.25 KB, 下载次数: 2)
下载附件
2021-12-18 17:07 上传

buff2.png (97 KB, 下载次数: 1)
下载附件
2021-12-18 17:07 上传
可能客户端并没有校验尾部的checksum,亦或者它不是checksum,反正是生效了。当然,仅部分本地效果可以生效。
测试3:伪造发包太懒了没做,需要修改后续封包的seq。(不知道封包尾部疑似checksum的东西会不会有校验,阿巴阿巴)
后记理论上,破解了封包加密算法后,是可以制作出脱机外挂乃至模拟服务端的,但因为国服有Antibot组件,还需要处理它的加密算法。不过独立模块也可能很轻易被调用,还没有研究过。外服应该就可以很轻易脱机了。
关于服务端的模拟,视频不是很好上传。有心人自己找找可以在油管上搜到的。

















查看全部评分