通过模糊测试发现燃料虚拟机中定价错误的操作码
开发模糊测试工具与种子语料库
Fuel 虚拟机原本有一个基于 cargo-fuzz 和 libFuzzer 的模糊测试工具,但它存在三个主要缺点:无法调用内部合约、执行速度较慢(约 50 次/秒)、仅能生成随机指令向量作为测试用例。
我们开发的改进方案具有以下特点:
支持调用内部合约的脚本执行
用 LibAFL 项目提供的 shim 替代 libFuzzer
多核并行执行能力(八核机器上可达 1000 次/秒)
通过分析 Sway 编译器输出,我们发现需要重新设计测试输入格式。新格式采用包含脚本汇编、脚本数据和被调用合约汇编的字节向量,各部分用 64 位魔数(0x00ADBEEF5566CEAA)分隔。这使得编译后的 Sway 程序可以直接作为种子输入。
遇到的挑战
依赖冲突:secp256k1 0.27.0 与 cargo-fuzz 存在兼容性问题,需特殊配置
LibAFL 稳定性:当前 shim 尚未发布稳定版本
脚本数据偏移传递:通过修改 fuel-vm,将偏移量写入 0x10 寄存器解决
用模糊测试分析燃料消耗
我们建立了三阶段分析流程:
启动模糊测试活动
使用收集工具生成 gas_statistics.csv
通过 Python 脚本分析数据并绘制执行时间与燃料消耗关系图
关键发现:
操作码 MCLI、SCWQ、K256、SWWQ 和 SRWQ 可能存在定价问题
其中 SCWQ、SWWQ 和 K256 的问题已通过 FuelLabs/fuel-vm#537 修复
SRWQ 的定价问题需要进一步验证
MCLI 的异常数据可能源于噪声干扰
经验总结
建议 Fuel 团队:
每次模糊测试至少持续 72 小时(理想为一周)
发现问题后暂停测试,修复后再继续
将模糊测试整合到开发流程中,特别是重大版本发布时
考虑使用 ClusterFuzzLite 实现 CI 集成(参见 FuelLabs/fuel-vm#727)
未来方向
增强测试断言,特别是区块执行相关检查
解决程序 32 位对齐问题(当前测试可能生成无效程序)
考虑加入 oss-fuzz 项目利用谷歌测试基础设施
优势:免费基础设施、自动问题通知
风险:谷歌会先于开发团队获知关键问题,且 90 天后必须公开漏洞报告
完整源代码见FuelLabs/fuel-vm#724更多精彩内容 请关注我的个人公众号 公众号(办公 AI 智能小助手)公众号二维码

评论