以前一直没太关注网络游戏外挂这方面的东西。前几天跟同事聊天,听他说起外挂这事儿,于是周日就下了一个网游:新三国策IV,随便玩儿一下,顺便分析其认证及数据报文加解密的算法。
这款游戏登陆时候的用户名及密码认证的安全性实在是不敢恭维。用户名是明文传递,密码只是经过了简单的加密运算,就在网络上传递用户的关键信息了。密码的加密算法居然是可逆的!!可逆意味着什么?可逆就意味着有心人只要拿到用户登陆的报文,就可以轻易得到用户的用户名和密码信息。想象一下,用户辛辛苦苦打得一身NB装备,然后轻易就被人把id盗走了,GM还好意思跟我说报文加密是为了用户的安全~~~。哎,我就奇怪了,怎么网络安全性到了现在这个时候还能被这么忽视?!其数据报文的加密算法倒是稍微复杂一些。
然而,外挂方面的东西终究了解得不够。对解密后的报文做过一些分析以后,尝试修改服务器回给客户端的数据,可以随便买卖东西,修改持有的物品及玩家属性等,客户端显示的的确是修改后的数据,然而服务器上的数据显然没法修改。黔驴技穷了,呼呼~。最后给自己做了个客户端yy版外挂,草草收场,丢人~~~
把报文的解密算法贴出来,也算是这几天的生活总结吧。有兴趣的也可以研究研究~。要想修改服务端返回的数据,就自己研究一下加密算法部分吧。如果谁有什么好的思路,希望知会我一下,我学习学习哈~~网游方面的知识确实太少了,唉~
/*************************************报文解密部分************************************************************
* key是根据上一个报文生成的。初始key是根据当前时间生成,经典的rand算法,hoho *
****************************************************************************************************************/
BYTE Decode_Recv_Bytes(BYTE *recv_buf, int recv_len, BYTE key)
{
BYTE last_recv_byte = key;
for(int i=0; i<recv_len; i++)
{
int temp1 = last_recv_byte & 7;
int temp2 = 1 << temp1;
int temp3 = recv_buf[i];
if ((temp2 & last_recv_byte) != 0)
{
recv_buf[i] ^= last_recv_byte;
}
else
{
int temp1 = (last_recv_byte & 3);
int temp2 = 1 << temp1;
if ((temp2 & last_recv_byte) == 0)
{
recv_buf[i] += last_recv_byte;
}
else
{
recv_buf[i] -= last_recv_byte;
}
}
last_recv_byte = temp3;
}
return last_recv_byte;
}
/*****************************不负责任的公司的加密算法*************************************
* 中间还跟GM提起,但是GM不太关心,哼哼~~ *
***********************************************************************************************/
void ggonline_encrypt_pwd(char *pwd_param)
{
char *pwd = pwd_param;
char pOldPwd0 = pwd_param[0];
char pOldPwdB = pwd_param[11];
pwd[0] = pwd[4];
pwd[4] = pwd[2];
pwd[2] = pwd[5];
pwd[5] = pwd[9];
pwd[9] = pwd[0];
pwd[11] = pOldPwd;
pwd[0] = pwd[13];
pwd[13] = pOldPosB;
for(int i=0; i<14; i++)
{
pwd[i] = pwd[i] ^ pwd[i+1];
}
memmove(pwd+1, pwd, 15);
pwd[0] = 0x20;
}