首页
社区
课程
招聘
[原创] 某手游客户端 RPC 洪泛拒绝服务漏洞分析
发表于: 16小时前 442

[原创] 某手游客户端 RPC 洪泛拒绝服务漏洞分析

16小时前
442

该漏洞属于 Resource-Exhaustion DoS via Unbounded RPC Flood

游戏版本: 0.16.7.421589
资源版本: 75506 ~ 75885

在B站看到一个外挂的视频,介绍了一种方法可以使同房间内的玩家游戏崩溃,经初步观察得出如下触发条件

经过长达半小时的分析和手搓之后,复现得到了同样的崩溃结果,顺带测试了一下 stuffType 设为0-9,只有 8 会导致崩溃

logcat日志里还会出现大量的 [W] Invalid PurchaseFxItem3D configuration

既然有崩溃那么自然会产生崩溃文件转储,保存在/data/user/0/com.xxxxxx.sky/files/uniTrace/crashhunter/目录下,可以提取出来分析

杂活交给大肥鱼去干,过了 1 分钟就得到了崩溃点

IDA分析一下,对应函数是 WingBuffVisual::Initialize,在调用 fx->flags 的时候用于空指针导致了异常,前面也没有对空指针进行校验

找交叉引用回到上层PurchaseFx::Initialize,大致重要的代码如下,顺带解释了前面日志里大量的Invalid PurchaseFxItem3D configuration字符串来源,只要stuffType不为1那么就会有这条日志,看起来和崩溃没有直接关系

stuffType 0~7走的都是同一个模型改改颜色和大小,9是换了个模型,只有8是特殊的。注意到在调用WingBuffVisual::Initialize初始化前,会先调用一个工厂函数WingBuffBarn::CreateWingBuffVisual

跟进分析一下,可以发现当 purchaseFxPool 内的对象数量大于容量后,函数就会返回空,而在调用WingBuffVisual::Initialize前也没有校验过,最终就会触发空指针异常崩溃

到这一步,受害者客户端里的崩溃链路就完整了。那么这些事件是怎么从攻击者那边跑到受害者那边去的呢

回到 PlayPurchaseFX。PlayPurchaseFX::OnStart 会创建一个子事件

一次脚本调用就是一个子事件、一个 stuffType=8 的 item。子事件创建出来时 broadcastEnabled 默认是 true。PurchaseFx 的构造函数 sub_221B504 里可以确认

在 PurchaseFx::Update 里有一段RPC发送逻辑

PurchaseFxRpc::Run是接收端对应的处理函数,只校验了发送者身份和有没有可见角色,没校验频率,也没校验报文里的 stuffType

所以大致是这么一个链路

那么 purchaseFxPool 为什么会满而不会自己清理呢

回到 PurchaseFx::Update 里,fx->elapsed 是每帧累加事件的存活时间,PurchaseFx 的整个生命周期都靠它驱动

把 j = 0 带入计算(该特效只会有一个item), 第 0 个item的 release 条件是 elapsed / 4.0 > 0.95,意味着至少要到 3.8 秒才会释放

所以我们可以推测一下,既然接收端是没有限速的,那么攻击者只要在3.8s这个窗口内尽可能多的发送RPC即可。回到崩溃日志,查看Invalid PurchaseFxItem3D configuration数量按时间分一下组,数据刚好对上,只花了大概 1.12 秒就资源耗尽了

同时我们还注意到,攻击者在执行有效的攻击后自己本身并不会崩溃,这里推测是因为加速挂把游戏时钟也一起加快了。下面是AI分析的小结论


传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!!

最后于 16小时前 被fu11p7r编辑 ,原因: 喵喵喵
收藏
点赞 ・18
打赏
分享
最新回复 (3)
雪    币: 9015
活跃值: (4661)
能力值: (RANK:168 )
在线值:
发帖
回帖
粉丝
2 楼
超赞 人类友好型文章
16小时前
0
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
3 楼
666
9小时前
0
雪    币: 1901
活跃值: (6183)
能力值: ( LV4,RANK:44 )
在线值:
发帖
回帖
粉丝
4 楼
6666
1小时前
0
游客
登录 | 注册 方可回帖
返回