2015年6月,《全民主公》安全测试中发现,由于一个int类型使用错误,形成游戏内“刷”武将等级的漏洞,危害程度爆表。若外挂团队或者是玩家利用此漏洞,可将武将直接刷到顶级。《全民主公》项目经过紧急排查,已经迅速修复了这个漏洞。
1、使用突飞猛进令请求中包含totalExp字段,表示本次使用增加的经验值
2、如下图,使用腾讯安全雷达先获取此协议,将totalExp该成一个极小值-2147483648(int32下限),发送请求,武将经验竟变成负值,等级变为0
3、再把totalExp改成相对较大值-2147403647,发送,武将经验变为5241,等级直接升到48!为什么会这样 = =!
协议安全测试时,测试同学先尝试将经验值字段直接改成较大值,如60000,发送请求,然而并没有什么暖用,角色属性数值没有变化。推测服务器处理这个请求时,有设置异常校验逻辑。
但测试同学把经验值设置成极小值(-2147483648,int32类型下限),发送后竟然生效,武将经验变成负数!
由此可以推测:
1、服务器后台用于保存武将经验totalExp变量是使用有符号类型
2、后台对吃突飞猛将令请求的异常处理仅仅是判断totalExp是否大于n(n为开发设定的某个正整数)。
如果totalExp>n,走进程序异常处理分支,被后台程序丢弃;
如果totalExp<n,走程序正常处理分支,将totalExp按正常逻辑进行运算并保存
基于服务器这样的校验规则,测试人员尝试了下面“刷”的办法,这里不得不提到数值型变量在计算机内存中存储和运算的基础概念:
原码是:1111 1111 1111 1111 1111 1111 1111 1111
补码是:1000 0000 0000 0000 0000 0000 0000 0001
原码是:1111 1111 1111 1110 1100 0111 0111 1111
补码是:1000 0000 0000 0001 0011 1000 1000 0001
1000 0000 0000 0000 0000 0000 0000 0001
+
1000 0000 0000 0001 0011 1000 1000 0001
于是符号位上溢,得到正值:
0000 0000 0000 0001 0011 1000 1000 0010 ,换算成十进制即为 80002
总结一下,由于游戏协议结构定义与后台存放经验值变量类型使用不当,导致出现符号位上溢“刷”经验的漏洞。这是多么痛的领悟..与君共勉吧!~
利用漏洞可直接把所有武将刷到满级,使商城中出售的高级突飞猛将令、以及游戏中精心设定出掉落该物品的关卡、掠夺等内容变得没有意义。
漏洞若流出外网,由于利益关系,容易在玩家间形成病毒式传播,一方面影响游戏商城营收,另一方面也会使游戏很多玩法形同虚设,因为此时角色已经不需要更多经验值了。
同时,有关漏洞的效果截图或刷上游戏排行榜截图容易被玩家在各大游戏分发平台论坛传播,对游戏口碑造成的影响也不容小觑。
另外,SR接入的《拳皇98OL》游戏中也出现类似问题,由于游戏服务器原因,测试环境受限,业务方测试人员后续将测试评估此漏洞影响面。《拳皇98OL》为此开启应急预案,也迅速的修复了该漏洞。这里,提醒其他游戏开发者也注意关注此类数值型变量上下溢出的风险。
1、协议本身设计不合理,吃经验的请求中不需要上报增加经验值字段,只需要指定使用物品的ID或物品类型,由服务器根据ID或类型处理具体增加多少经验
2、后台应改用无符号整型存储武将经验值
3、后台对于客户端请求的异常处理分支当然是不能少的