智能合约安全学习笔记
合约缺陷:
Solidity Layer:
- 重入:经典fallback()起手,或者利用ERC-777的before/after机制
- DoS with failed call:让调用链的某个环节失败
- Dos with gas consumption:通过assert/require相对低成本操控tx Position
- 整数上溢/下溢:经典问题,solidity 8.00+已修复
- 未检查返回值:call()/send() 失败不回退,要查下值才知道结果
- 错误未捕获:字面意思,may影响caller状态更新
- 函数可见性:可能把本应internal的函数设成public,然后被利用
- 错误配置constructor:可能会错误配置一些关键变量
- 权限控制:字面意思(突然想到zksync之前有个项目好像就是因为没加权限相关modify被掏了)
- Call to the Unknown:假设call的合约是安全的,但其实不安全,然后就寄了
- Freezing Ether:合约没预留call功能/依赖的proxy不稳定
- Unprotected Selfdestruct:合约自毁后依赖就乱了,但可以用CREATE2缓解
- Gasless Send:.transfer里作复杂操作会out of gas,然后revert,可能卡住合约
- Delegatecall:proxy可能失效
- 验证签名信息不充分:没加nonce/nullifer符之类的就容易被重放
- 双重授权漏洞:可以从某个较为薄弱的授权入手攻击
- 变量错误使用:字面意思,都用错了当然什么问题都可能出现
- 未保护的Eth withdrawl:逻辑/权限控制有问题,然后eth就被提走了
- Dead Code:不会被执行到的代码,可能存在风险
- 存储碰撞漏洞:delegate不规范,slots会乱(
- 未指定指针:老版solidity变量没显示声明引用类型的data location,指针就会默认指向slot0,现在修了
EVM层:
- 合约部署后不可变:(感觉这是特性,不算缺陷)
- 栈深度限制:栈太深就报错了
链层
- 时间戳依赖:时间戳可以被操纵,所以尽量用区块高度来代替时间戳(想到了个好笑的事,但这不方便写xD)
- 交易顺序依赖:swap可能被三明治攻击,某些交proof的可能被抢跑
- 生成随机数:有些随机源很好被预测,业内现在在推VRF
- 重放攻击:防护措施见EIP-1599
检测方法
形式化验证:
- 定理证明:给出断言后证明
- 模型检查 在有限域内探索所有分支,对可达状态穷举,重点在状态
- 符号执行:对路径求约束判断可达性,重点在路径
Fuzz
- 基于生成的Fuzzing:用各种方法从头搓exploit
- 基于变异的Fuzzing:从已有tx上搓exploit
深度学习
- Sequence-based:把源码/bytecode/opcode看成一串有序token喂给模型
- Graph-based:把代码转成图再喂,特征可能会更清晰点(?
- Hybrid methods:都可以喂(
程序分析
- 抽象解释方法:忽略一些指令,抽象一下程序,能用比如说逻辑驱动方式检测安全性
- IR方法:将源码/bytecode转成结构化的中间表示形式,有利于安全分析
其他
- 污点分析:分析外部源对合约的影响
- Online Detection:提前监控链上可能存在的攻击意图
- 逆向工程:逆向出高级伪代码(Dedaub应该是top1吧)
- 异常交易识别:识别链上异常交易
修复
- off-chain repair:在合约部署前修复合约本身
- on-chain repair:修已经部署了的合约
评论已关闭