通过模糊测试发现燃料虚拟机中定价错误的操作码
开发模糊测试工具与种子语料库
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智能小助手)
公众号二维码