智能合约¶
ETH · 知识域。合约漏洞利用主战场。标签:合约漏洞分析、合约代码审计、合约逻辑漏洞、合约权限控制、合约重入攻击、合约溢出漏洞。
触发特征¶
- Ethernaut/Damn Vulnerable DeFi/paradigm-ctf 形态:部署实例 → 让
isSolved()为真。
重入攻击(DAO 模式)¶
- 经典:external call(转账)在状态更新前 → 回调再入取款(DefCamp 2017 原型 DAO 事件)。
- 变体:ERC777 hook 重入、ERC721
onReceived重入、receive/fallback逻辑。 - 检查点:状态更新与外部调用顺序;reentrancy guard 缺失;跨函数重入(经共享状态变量)。
溢出漏洞¶
- Solidity <0.8 无内置检查:加/减/乘溢出(
SafeMath缺失);0.8+ 用 unchecked 块的溢出。 - 类型截断:uint256→uint32 强转;epoch 时间截断。
- 变体:批量铸造数组长度伪造(短地址历史攻击)。
权限控制¶
tx.origin鉴权(钓鱼合约代发交易绕过);msg.sender与 delegatecall 上下文混淆。- delegatecall 存储上下文滥用:库/代理调用下存储槽错位覆盖 owner(EHAX 2026)。
- 初始化函数未设防(可重复 init);
selfdestruct强制注 ETH 破坏"余额等于 X"判定(0.8 后 selfdestruct 仍可强制发币给合约)。 -修饰器逻辑 bug:非真条件短路。
逻辑漏洞¶
- 整数精度:除法先乘后除顺序、精度丢失套利偏差。
- 预言机操纵:spot price(.balance/getReserves)被闪电贷操纵;TWAP 短窗操纵。
- 闪电贷组合攻击:无自有资金完成"需要大量本金"的操作(damnvulnerabledefi 核心思想)。
- 合约随机数问题:块变量(blockhash/timestamp/prevrandao)可预测/可操纵;commit-reveal 缺失。
- DoS:revert 拒绝(循环内退款给恶意合约)、gas 耗尽(无上限循环)。
Proxy模式漏洞(代理与升级)¶
- EIP-1967 代理利用:implementation slot 劫持、未初始化的 implementation 直接 init(原题范式)。
- UUPS 升级函数无权限 → 自升级恶意逻辑;存储碰撞(变量槽位重叠)。
- ABI Coder v1/v2 差异:dirty address 位绕过;非标准 calldata 编码解析分歧;bytes32 字符串编码。
- Solidity transient storage(0.8.28-0.8.33):helper 冲突清零导致的重入窗口(0xFun 2026 系列)。
- CBOR 元数据剥离:codehash 判定绕过。
合约代币标准与授权漏洞(ERC20 系)¶
- ERC20 漏洞:approve 竞态(先 approve 新额度前旧额度仍可被 spender 用掉——先减到 0 再 approve);decimals 处理错误导致数量放大;transfer 返回值未检查(bool false 静默失败,非 revert)→ 记账错乱;
transferFrom边界。 - 合约授权漏洞:无限授权(
approve(type(uint256).max))后代币被任意划走(钓鱼签名/恶意合约,链上钓鱼主通道,→ 交易分析 钓鱼模式);permit2 离线签名钓鱼;increaseAllowance实现错误。 - 合约多重签名漏洞:签名收集流程竞态(门限恰好达成瞬间状态变更)、owner 重复签名计数、execute 与 confirm 未分离导致的单签执行。
合约实现细节漏洞¶
- 合约函数可见性:本应 external/private 的函数被标 public → 关键初始化/清算函数可被任意调用;initializer 未加防重入标志(→ 权限控制节初始化)。
- 合约函数选择器冲突:两个函数 4 字节选择器相同(EIP-165 思想的滥用)→ 调用 A 实际进 B;Solidity 0.4.22 前
fallback与函数选择器碰撞的历史 CVE。 - 合约短地址攻击:ABI 编码在 calldata 尾部缺字节时,部分旧路由器/pad 逻辑会错位解析参数(ERC20 transfer 地址尾零被吃)——现代编译器已校验 calldata 长度,CTF 场景经手写汇编/低级调用复刻。
- 合约编译器漏洞:Solidity 版本锁定后查编译器已知 bug(abi.encodePacked 哈希碰撞、0.8 前 unchecked 溢出、optimizer 缺陷列表,SWC 注册表);
forge inspect看编译器版本匹配。 - Gas限制与操控(Gas Griefing),即合约拒绝服务攻击:循环无上限 → 阻塞调用(out of gas DoS);强制小 gas 转发(63/64 规则)让 fallback 逻辑失效;
gasleft()当随机数/条件 → 可被 gas 操纵。 - 合约自毁漏洞:未鉴权的
selfdestruct/suicide→ 强制转 ETH 破坏"余额==X"不变量、销毁金库(0.8 后 selfdestruct 仅剩强制发 ETH 语义,仍可用于不变量攻击);代理合约被 selfdestruct 后逻辑永久丢失。 -
合约时间戳依赖:
block.timestamp(可被矿工/出块者 ±数秒操纵)与block.number参与关键判定 → 竞标的最后一刻操纵(→ 逻辑漏洞节随机数条目同源)。 -
Groth16 证明伪造:setup 参数 delta==gamma 时直接构造假证明(A=alpha,B=beta,C=-vk_x);无 nullifier 追踪时无限重放(DiceCTF 2026 治理场景)。
- DV-SNARG 伪造:oracle 下学习秘密 v 后 CRS 消除伪造;KZG 配对 oracle 恢复置换(→ Crypto-Z3/ECC)。
- Phantom market 不结算 + 强注资金组合(DiceCTF 2026)。
合约访问控制(权限面补充)¶
- 访问控制缺失总检:external 函数逐个过"谁能调"——modifier 缺失、msg.sender 与 tx.origin 混用、角色检查写错(
require(hasRole(x))参数序)、代理上下文下的权限存储错位(delegatecall 上下文,→ 权限控制节)。 - 角色管理漏洞:OpenZeppelin AccessControl 的 grant/revoke 流程滥用、角色继承链过宽、admin 角色单点。
- 合约整数溢出在代币语义下的放大:mint/burn 路径的 unchecked 运算 → 凭空增发/余额下溢成天文数字(→ 溢出漏洞节)。
审计工具与流程¶
slither ./target --print inheritance-graph # 静态审计
echidna-test contract.yaml # 性质 fuzz
forge test -vvv # 写 PoC 测试
# 审计清单:重入 → 权限 → 溢出 → 预言机 → 随机数 → 升级 → DoS
转向¶
- 密码学组件(Groth16/KZG)→ Crypto-ECC;链下基础设施(Web/API)→ WEB