未授权资金转移漏洞技术分析
漏洞影响摘要
攻击者能够从非其所有的锁定账户中转走资金(若账户存在已解锁资金,可能在锁定期结束后)。概念验证(POC)针对周期性锁定账户完成,但由于问题似乎存在于SendCoins函数(被所有锁定账户使用),更多锁定账户可能受影响。
技术原理
当调用函数时,系统从消息msg.Sender传递发送方信息,checkSender函数验证发送方是否与所有者一致。核心问题在于:msg.Sender未在任何地方验证,因为该消息被包装到MsgExecute中。执行时,原始发送方被设置到上下文(context)中。对于多重签名账户,系统能正确从ctx获取发送方(至少在已检查的代码位置如此),但这些锁定账户却从消息中获取发送方信息——而该信息可被任意伪造。
复现步骤
- 环境要求:需安装Go和Rust语言环境
- 代码准备:
- 检出最新版cosmos-sdk并执行
make build
,记录二进制路径 - 创建Rust项目并配置附带的Cargo.toml文件
- 下载所有*.rs文件置于src目录
- 检出最新版cosmos-sdk并执行
- 执行攻击:
- 为setup_chain脚本添加执行权限
- 运行
./setup_chain
启动链 - 执行Rust项目完成攻击演示
支持材料
- setup_chain:链配置启动脚本
- main.rs/msg.rs/types.rs/func.rs/client.rs:攻击实现核心代码
- accounts.mov:POC演示视频(209.6MB)
- 补充文件仓库:https://github.com/h1uf/cosmos_rust_client
影响评估
攻击者可接管他人锁定账户中已解锁的资金。虽然POC针对周期性锁定账户演示,但有充分理由相信更多锁定账户类型受影响。该漏洞导致直接资金损失,仅需单笔交易即可完成利用。
修复与响应
开发团队在报告次日提交修复补丁(PR #23621)。初始评估为高危漏洞,后因代码涉及已取消的v0.52版本发布而调整为临界严重性。最终修复方案以重构形式呈现,但未发布新版本标签,可能导致依赖方无法及时识别漏洞存在。
漏洞根本原因:锁定账户从消息而非上下文获取发送方身份,导致未经验证的发送方可执行未授权资金操作。