huichain/smart-contract-security-lab

GitHub: huichain/smart-contract-security-lab

基于 Foundry 的智能合约安全学习实验室,通过复现真实漏洞、编写 PoC 和提出修复方案帮助开发者系统掌握合约安全技术。

Stars: 0 | Forks: 0

# 智能合约安全实验室 一个基于 Foundry 的实验室,旨在通过复现真实漏洞、编写 PoC 和提出修复方案来学习智能合约安全。 本仓库是**日积月累**构建的,而非一蹴而就。 每天添加一个小而完整的片段:一个存在漏洞的合约、一个攻击者、一个修复方案或一份报告。 ## 状态 - ✅ **Reentrancy** 模块完成 — 包含漏洞合约、攻击者、修复方案、3 个通过的测试、审计风格报告 - ✅ **Access Control** 模块完成 — 包含漏洞及修复合约、5 个通过的测试、审计风格报告 - ✅ **Signature Replay** 模块完成 — 包含漏洞空投、修复实现、3 个通过的测试、审计风格报告 - ✅ **Oracle Manipulation** 模块完成 — 包含漏洞及修复的借贷、TWAP 预言机、4 个通过的测试、审计风格报告 - ✅ **Upgradeable Proxy** 模块完成 — 包含 initializer PoC + storage-layout 碰撞 PoC、修复实现、9 个通过的测试、审计风格报告 ## Reentrancy — 漏洞金库、漏洞利用 PoC、修复及报告 - [x] `src/reentrancy/VulnerableVault.sol` 一个最小化的 ETH 金库,它**在**更新用户余额**之前**将 ETH 发送给用户,这使其容易受到重入攻击。 - [x] `src/reentrancy/ReentrancyAttacker.sol` 攻击者合约,从 `receive()` 重入 `withdraw` 以抽干金库。 - [x] `src/reentrancy/FixedVault.sol` 使用 checks-effects-interactions 模式和 OpenZeppelin 的 `ReentrancyGuard`(深度防御)强化的金库。 - [x] `test/reentrancy/ReentrancyPoC.t.sol` Foundry PoC 测试套件: - `testExploit_DrainsVault` — 攻击者利用 1 ETH 的攻击资金抽干了拥有 10 ETH 的金库 - `testFix_BlocksReentrancy` — 同样的攻击者针对 `FixedVault` 发起交易会 revert,受害者的资金保持安全 - `testFix_AllowsHonestWithdraw` — 完整性检查,确认修复方案不会破坏正常用户的使用 - [x] [`reports/01-reentrancy.md`](reports/01-reentrancy.md) 审计风格报告:严重程度、摘要、根本原因、PoC、建议、修复实现和经验教训。 ## Access Control — 漏洞金库、漏洞利用 PoC、修复 - [x] `src/access-control/VulnerableTreasury.sol` 一个带有 `owner` 字段的协议金库,但 `withdraw` 和 `setOwner` **没有权限检查** — 这是两个独立的漏洞。 - [x] `src/access-control/FixedTreasury.sol` 使用 OpenZeppelin `Ownable` 和在敏感函数上使用 `onlyOwner` 强化的金库(无需单独的攻击者合约;EOA 即可利用漏洞版本)。 - [x] `test/access-control/AccessControlPoC.t.sol` Foundry PoC 测试套件: - `testExploit_AnyoneCanDrainTreasury` — 任何账户都可以调用 `withdraw` 并抽干所有 ETH - `testExploit_AnyoneCanBecomeOwner` — 任何账户都可以调用 `setOwner` 并夺取所有权 - `testFix_BlocksUnauthorizedWithdraw` — 攻击者调用 `withdraw` 会因 `OwnableUnauthorizedAccount` revert - `testFix_BlocksUnauthorizedSetOwner` — 攻击者调用 `setOwner` 会 revert;owner 保持不变 - `testFix_AllowsOwnerFunctions` — 合法的 owner 仍然可以提款和转移所有权 - [x] [`reports/02-access-control.md`](reports/02-access-control.md) 审计风格报告:两个发现(`withdraw`、`setOwner`)、严重程度、PoC、建议、修复实现和经验教训。 ## Signature Replay — 漏洞空投、重放 PoC、修复及报告 - [x] `src/signature-replay/VulnerableAirdrop.sol` 一个故意留下漏洞的 ETH 空投,接受来自受信任签名者的链下签名,但签名消息仅绑定了 `account` 和 `amount`。 - [x] `test/signature-replay/SignatureReplayPoC.t.sol` Foundry PoC 测试套件: - `testExploit_SameSignatureClaimsTwice` — 两次重复使用完全相同的签名,并证明领取者收到了两次空投 - `testFix_BlocksSignatureReplay` — 证明修复后的合约消耗了用户的 nonce 并拒绝了重放的签名 - `testFix_RejectsExpiredSignature` — 证明过期的签名无法被使用 - [x] `src/signature-replay/FixedAirdrop.sol` 修复实现:将签名绑定到 nonce、deadline、chain id 和 `address(this)`。 - [x] [`reports/03-signature-replay.md`](reports/03-signature-replay.md) 审计风格报告:严重程度、重放影响、根本原因、PoC、建议、修复实现和经验教训。 ## Oracle Manipulation — AMM 即时价格 PoC - [x] `src/oracle-manipulation/SimpleAMM.sol` 一个故意简化的恒定乘积 AMM,其即时价格可以通过改变储备金来操纵。 - [x] `src/oracle-manipulation/VulnerableLending.sol` 一个玩具借贷市场,直接信任 AMM 即时价格来计算借款能力。 - [x] `src/oracle-manipulation/TWAPOracle.sol` 记录累积的 AMM 价格,以便借贷可以查询时间加权平均值而不是即时价格。 - [x] `src/oracle-manipulation/FixedLending.sol` 强化的借贷市场,使用 `TWAPOracle.consult()` 而不是 `getSpotPrice()` 对抵押品进行定价。 - [x] `test/oracle-manipulation/OracleManipulationPoC.t.sol` Foundry PoC 测试套件: - `testExploit_SpotPriceManipulationInflatesBorrowLimit` — 证明操纵 AMM 即时价格会抬高借款限额并抽干流动性池 - `testNormalPriceOnlyAllowsLimitedBorrow` — 完整性检查,显示正常价格只允许小得多的借款 - `testFix_BlocksSpotPriceManipulation` — 证明使用 TWAP 定价时,相同的操纵无法抽干资金池 - `testFix_AllowsHonestBorrow` — 完整性检查,确认正常用户仍然可以以 TWAP 价格借款 - [x] [`reports/04-oracle-manipulation.md`](reports/04-oracle-manipulation.md) 审计风格报告:严重程度、即时价格预言机风险、根本原因、PoC、TWAP 缓解措施、修复实现和经验教训。 ## Upgradeable Proxy — 最小化代理、Initialize PoC、修复 - [x] `src/upgradeable-proxy/SimpleProxy.sol` 最小化的 EIP-1967 风格代理:`fallback` 通过 `delegatecall` 将调用转发给实现合约。 - [x] `src/upgradeable-proxy/ImplementationV1.sol` 带有故意未受保护的 `initialize()` 的逻辑合约 — 任何人都可以设置或覆盖代理存储中的 `owner`。 - [x] `src/upgradeable-proxy/FixedImplementationV1.sol` 使用 OpenZeppelin `Initializable` 强化的逻辑合约:一次性 `initializer` 以及在实现合约上调用 `_disableInitializers()`。 - [x] `test/upgradeable-proxy/ProxyPoC.t.sol` Foundry PoC 测试套件: - `testExploit_UnprotectedInitializeLetsAttackerTakeOwnership` — 攻击者通过代理调用 `initialize` 并夺取 `owner` - `testExploit_AttackerCanReinitializeAndOverwriteOwner` — 攻击者在管理员之后重新初始化并覆盖所有权 - `testFix_BlocksReinitialize` — 证明重放的 `initialize` 调用会 revert,并且所有权仍归管理员所有 - `testFix_AllowsLegitimateInit` — 完整性检查,确认合法的初始化和所有者流程仍然有效 - `testFix_BlocksDirectInitializeOnImplementation` — 证明裸实现合约不能被直接初始化 - [x] [`reports/05-upgradeable-proxy.md`](reports/05-upgradeable-proxy.md) 审计风格报告:未受保护的 initializer 风险、delegatecall 存储模型、PoC、`Initializable` 缓解措施和经验教训。 - [x] `src/upgradeable-proxy/ImplementationV2.sol` 故意不安全的 V2,更改了存储顺序并演示了升级后的 slot 重新解释。 - [x] `src/upgradeable-proxy/FixedImplementationV2.sol` 安全的 V2,保留了 V1 的布局并追加了新变量。 - [x] `test/upgradeable-proxy/StorageLayoutPoC.t.sol` Foundry PoC 测试套件: - `testExploit_UpgradeToBadLayoutCorruptsOwnerAndValue` — 证明 slot 重新解释会破坏 owner/value 的语义 - `testExploit_AdminLosesPrivilegesAfterBadUpgrade` — 证明在不兼容的升级后,管理员失去了仅限所有者的访问权限 - `testFix_CompatibleLayoutPreservesOwnerAndValueAcrossUpgrade` — 证明布局安全的 V2 保持状态完好无损 - `testFix_OnlyOwnerCanRunV2Initializer` — 证明 V2 initializer 受到所有者权限控制,并且适用于合法的管理员 - [x] [`reports/06-storage-layout-collision.md`](reports/06-storage-layout-collision.md) 审计风格报告:存储碰撞根本原因、升级 PoC、缓解措施和验证。 ## 项目结构 ``` smart-contract-security-lab/ ├─ foundry.toml # Foundry config + remappings ├─ foundry.lock # Locked dependency versions ├─ .gitmodules # Git submodules (forge-std, openzeppelin-contracts) ├─ .gitignore ├─ remappings.txt # IDE-friendly remappings (mirrors foundry.toml) ├─ README.md ├─ lib/ │ ├─ forge-std/ # Foundry standard testing library (submodule) │ └─ openzeppelin-contracts/ # OpenZeppelin Solidity library (submodule) ├─ src/ │ ├─ reentrancy/ │ │ ├─ VulnerableVault.sol │ │ ├─ ReentrancyAttacker.sol │ │ └─ FixedVault.sol │ ├─ access-control/ │ │ ├─ VulnerableTreasury.sol │ │ └─ FixedTreasury.sol │ ├─ oracle-manipulation/ │ │ ├─ SimpleAMM.sol │ │ ├─ VulnerableLending.sol │ │ ├─ TWAPOracle.sol │ │ └─ FixedLending.sol │ ├─ signature-replay/ │ │ ├─ VulnerableAirdrop.sol │ │ └─ FixedAirdrop.sol │ └─ upgradeable-proxy/ │ ├─ SimpleProxy.sol │ ├─ ImplementationV1.sol │ ├─ FixedImplementationV1.sol │ ├─ ImplementationV2.sol │ └─ FixedImplementationV2.sol ├─ test/ │ ├─ reentrancy/ │ │ └─ ReentrancyPoC.t.sol │ ├─ access-control/ │ │ └─ AccessControlPoC.t.sol │ ├─ oracle-manipulation/ │ │ └─ OracleManipulationPoC.t.sol │ ├─ signature-replay/ │ │ └─ SignatureReplayPoC.t.sol │ └─ upgradeable-proxy/ │ ├─ ProxyPoC.t.sol │ └─ StorageLayoutPoC.t.sol └─ reports/ ├─ 01-reentrancy.md ├─ 02-access-control.md ├─ 03-signature-replay.md ├─ 04-oracle-manipulation.md ├─ 05-upgradeable-proxy.md └─ 06-storage-layout-collision.md ``` ## 依赖项 - [Foundry](https://book.getfoundry.sh) - [forge-std](https://github.com/foundry-rs/forge-std) `v1.16.1` — Foundry 标准测试库 - [OpenZeppelin Contracts](https://github.com/OpenZeppelin/openzeppelin-contracts) `v5.6.1` — 在修复版本中使用的久经考验的 Solidity 组件(Ownable、ReentrancyGuard、ECDSA 等) 所有依赖项都作为 git submodule 安装在 `lib/` 下,并锁定在 `foundry.lock` 中。 ## 快速开始 ### 1. 安装 Foundry 请根据您的操作系统遵循官方安装指南: https://book.getfoundry.sh/getting-started/installation 快速参考: ``` # macOS / Linux / WSL curl -L https://foundry.paradigm.xyz | bash foundryup ``` ``` # Windows (PowerShell) powershell -c "irm https://foundry.paradigm.xyz/install.ps1 | iex" foundryup ``` ### 2. 使用 submodule 克隆 ``` git clone --recurse-submodules https://github.com/huichain/smart-contract-security-lab.git cd smart-contract-security-lab ``` 如果您已经克隆但没有包含 submodule: ``` git submodule update --init --recursive ``` ### 3. 构建 ``` forge build ``` ### 4. 测试 该实验室目前提供了涵盖五个漏洞模块的 **24 个通过的测试**。 **Reentrancy** (`test/reentrancy/`): - `testExploit_DrainsVault` — 证明攻击者用 1 ETH 的资金抽干了 10 ETH 的金库。 - `testFix_BlocksReentrancy` — 证明相同的攻击针对 `FixedVault` 会 revert。 - `testFix_AllowsHonestWithdraw` — 完整性检查,确认正常用户仍然可以工作。 **Access Control** (`test/access-control/`): - `testExploit_AnyoneCanDrainTreasury` — 证明任何人都可以通过 `withdraw` 抽干金库。 - `testExploit_AnyoneCanBecomeOwner` — 证明任何人都可以通过 `setOwner` 夺取所有权。 - `testFix_BlocksUnauthorizedWithdraw` — 证明 `FixedTreasury` 会阻止未经授权的提款。 - `testFix_BlocksUnauthorizedSetOwner` — 证明未经授权的所有权转移会 revert。 - `testFix_AllowsOwnerFunctions` — 完整性检查,确认所有者仍然可以管理金库。 **Signature Replay** (`test/signature-replay/`): - `testExploit_SameSignatureClaimsTwice` — 证明同一个签名可以被重放以两次认领。 - `testFix_BlocksSignatureReplay` — 证明消耗 nonce 会阻止重放同一个签名。 - `testFix_RejectsExpiredSignature` — 证明签名在截止时间之后无法使用。 **Oracle Manipulation** (`test/oracle-manipulation/`): - `testExploit_SpotPriceManipulationInflatesBorrowLimit` — 证明操纵 AMM 即时价格会抬高借款能力。 - `testNormalPriceOnlyAllowsLimitedBorrow` — 证明未被操纵的价格会强制执行预期的较低借款限额。 - `testFix_BlocksSpotPriceManipulation` — 证明 TWAP 定价会阻止相同的即时价格操纵攻击。 - `testFix_AllowsHonestBorrow` — 证明正常用户仍然可以以 TWAP 价格借款。 **Upgradeable Proxy** (`test/upgradeable-proxy/`): - `testExploit_UnprotectedInitializeLetsAttackerTakeOwnership` — 证明未受保护的 `initialize()` 会让攻击者夺取代理所有权。 - `testExploit_AttackerCanReinitializeAndOverwriteOwner` — 证明公开的 initializer 可以覆盖现有的所有者。 - `testFix_BlocksReinitialize` — 证明修复后的实现会阻止重放的初始化。 - `testFix_AllowsitimateInit` — 证明合法的管理员初始化仍然有效。 - `testFix_BlocksDirectInitializeOnImplementation` — 证明逻辑合约地址不能被直接初始化。 - `testExploit_UpgradeToBadLayoutCorruptsOwnerAndValue` — 证明不兼容的 V2 存储布局会重新解释现有的代理状态。 - `testExploit_AdminLosesPrivilegesAfterBadUpgrade` — 证明在错误的升级后管理员会失去仅限所有者的特权。 - `testFix_CompatibleLayoutPreservesOwnerAndValueAcrossUpgrade` — 证明兼容的 V2 在升级后保持 owner/value 不变。 - `testFix_OnlyOwnerCanRunV2Initializer` — 证明只有所有者才能运行 V2 的 reinitializer。 运行所有测试: ``` forge test ``` 运行单个模块: ``` forge test --match-path test/access-control/AccessControlPoC.t.sol -vv ``` ## 路线图(高层级) | 漏洞 | 状态 | | --- | --- | | Reentrancy | ✅ 完成 — 漏洞合约 + 攻击者 + 修复 + 测试 + 报告 | | Access Control | ✅ 完成 — 漏洞合约 + 修复 + 测试 + 报告 | | Signature Replay | ✅ 完成 — 漏洞合约 + 修复空投 + 测试 + 报告 | | Oracle Manipulation | ✅ 完成 — 漏洞合约 + TWAP 修复 + 测试 + 报告 | | Upgradeable Proxy | ✅ 完成 — initializer + storage-layout PoC、修复的 V1/V2、9 个测试、2 份报告 | ## 关于作者 具有 C++ / C# 背景的软件工程师,正在向智能合约安全和 Web3 工具领域转型。 - GitHub: [huichain](https://github.com/huichain) - X: [@vividhui](https://x.com/vividhui)
标签:Foundry, Solidity, 区块链安全, 智能合约, 漏洞复现