🎉 亲爱的广场小伙伴们,福利不停,精彩不断!目前广场上这些热门发帖赢奖活动火热进行中,发帖越多,奖励越多,快来 GET 你的专属好礼吧!🚀
🆘 #Gate 2025年中社区盛典# |广场十强内容达人评选
决战时刻到!距离【2025年中社区盛典】广场达人评选只剩 1 天,你喜爱的达人,就差你这一票冲进 C 位!在广场发帖、点赞、评论就能攒助力值,帮 Ta 上榜的同时,你自己还能抽大奖!iPhone 16 Pro Max、金牛雕塑、潮流套装、合约体验券 等你抱走!
详情 👉 https://www.gate.com/activities/community-vote
1️⃣ #晒出我的Alpha积分# |晒出 Alpha 积分&收益
Alpha 积分党集合!带话题晒出你的 Alpha 积分图、空投中奖图,即可瓜分 $200 Alpha 代币盲盒,积分最高直接抱走 $100!分享攒分秘籍 / 兑换经验,中奖率直线上升!
详情 👉 https://www.gate.com/post/status/12763074
2️⃣ #ETH百万矿王争霸赛# |ETH 链上挖矿晒收益
矿工集结!带话题晒出你的 Gate ETH 链上挖矿收益图,瓜分 $400 晒图奖池,收益榜第一独享 $200!谁才是真 ETH 矿王?开晒见分晓!
详情 👉 https://www.gate.com/pos
Move语言整数溢出漏洞分析:从引用安全到DoS攻击
Move语言中的整数溢出漏洞分析
前言
在对Aptos Moveevm进行深入研究后,我们发现了一个新的整数溢出漏洞。这个漏洞的触发过程相对更加有趣,下面我们将对这个漏洞进行深入分析,并介绍一些Move语言的背景知识。通过本文的讲解,相信你会对Move语言有更深入的理解。
Move语言在执行字节码之前会验证代码单元。验证过程分为4个步骤,而这个漏洞出现在reference_safety步骤中。
Move中的引用安全
Move语言支持两种类型的引用:不可变引用(&)和可变引用(&mut)。不可变引用用于从结构中读取数据,而可变引用用于修改数据。使用适当的引用类型有助于维护安全性并识别读取模块。
在Move的引用安全模块中,会以函数为单位,扫描函数中基本块的字节码指令,以验证所有引用操作是否合法。验证引用安全性的主要流程包括执行基本块、生成后置状态、合并前后状态等步骤。
漏洞分析
漏洞出现在引用安全模块的join_函数中。当函数参数长度和局部变量长度之和大于256时,由于使用u8类型表示local变量,会导致整数溢出。
虽然Move有校验locals个数的过程,但在check bounds模块中只校验了locals,并未包括参数长度。开发人员似乎意识到需要检查参数和本地值的总和,但代码中只校验了本地变量的个数。
从整数溢出到DoS攻击
利用这个整数溢出漏洞,攻击者可以制造一个循环代码块,改变块的状态。当再次执行execute_block函数时,如果指令需要访问的索引在新的AbstractState locals map中不存在,将导致DoS攻击。
在reference safety模块中,MoveLoc/CopyLoc/FreeRef等操作码可能会触发这种情况。例如,在copy_loc函数中,如果LocalIndex不存在会导致panic,进而导致整个节点崩溃。
漏洞复现
可以通过以下PoC代码在git中重现这个漏洞:
move public fun test(a: u64, b: u64, c: u64, d: u64) { let x = 0; loop { if (x == 1) { break }; x = x + 1; } }
触发DoS的步骤如下:
第一次执行execute_block函数,设置parameters和locals均为SignatureIndex(0),导致num_locals为264。执行join_函数后,新的locals map长度变为8。
第二次执行execute_block函数时,执行move代码第一条指令copyloc(57)。由于此时locals只有长度8,offset 57不存在,导致get(57).unwrap()函数返回None,最终引发panic。
总结
这个漏洞表明没有绝对安全的代码。虽然Move语言在代码执行前进行了静态校验,但仍可能被溢出漏洞绕过。这再次强调了代码审计的重要性。
对于Move语言,我们建议在运行时增加更多的检查代码,以防止意外情况发生。目前Move主要在verify阶段进行安全检查,但一旦验证被绕过,运行阶段缺乏足够的安全加固可能导致更严重的问题。
作为Move语言安全研究的领导者,我们将继续深入研究Move的安全问题,并在后续分享更多发现。