✈️ Gate 广场【Gate Travel 旅行分享官召集令】
广场家人们注意啦!Gate Travel 已经上线~ 机票+酒店一站式预订,还能用加密货币直接付款 💸
所以说,你的钱包和你的旅行梦终于可以谈恋爱了 😎 💕
现在广场开启 #GateTravel旅行分享官# 活动,邀你来秀旅行灵感 & 使用体验!💡
🌴 参与方式:
1️⃣ 在【广场】带话题 #Gate Travel 旅行分享官# 发帖
2️⃣ 你可以:
你最想用 Gate Travel 去的目的地(私藏小岛 or 网红打卡点都行)
讲讲用 Gate Travel 订票/订酒店的奇妙体验
放放省钱/使用攻略,让大家省到笑出声
或者直接写一篇轻松的 Gate Travel 旅行小故事
📦 奖励安排,走起:
🏆 优秀分享官(1 名):Gate 旅行露营套装
🎖️ 热门分享官(3 名):Gate 旅行速干套装
🎉 幸运参与奖(5 名):Gate 国际米兰旅行小夜灯
*海外用户 旅行露营套装 以 $100 合约体验券,旅行速干套装 以 $50 合约体验券折算,国际米兰旅行小夜灯以 $30合约体验券折算。
📌 优质内容将有机会得到官方账号转发翻牌提升社区曝光!
📌 帖文将综合互动量、内容丰富度和创意评分。禁止小号刷贴,原创分享更容易脱颖而出!
🕒 8月20 18:00 - 8月28日 24:00 UTC+
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的安全问题,并在后续分享更多发现。