the-hugin/smart-contract-risk-triage
GitHub: the-hugin/smart-contract-risk-triage
一个被动的多链智能合约风险分诊系统,通过静态扫描、运行时预检和误报抑制为安全分析师生成带有优先级的审查队列。
Stars: 1 | Forks: 0
# smart-contract-risk-triage
用于智能合约审查队列的被动分类。
该仓库包含两部分:
- EVM 工具:Sourcify 接入、余额/活动过滤、静态资金路径扫描、运行时预检以及持续监控。
- Solana 工具:BPF Upgradeable Loader 监控,带有保守的价值邻近性检查。
其输出是一个审查队列。它不是已确认漏洞的反馈源。
## 边界
这些工具不发送交易、模拟漏洞利用、暴力破解端点,也不收集凭证。它们仅使用公开的源元数据和只读 RPC 调用。
请将它们用于你自己的合约、授权审计、范围内的漏洞赏金工作或被动的公开来源研究。在人工检查范围、运行时状态、可利用性以及程序规则之前,请将每一个发现都视为一个线索。
## 覆盖范围
EVM:
- Sourcify 已验证源代码的列表和下载。
- 原生代币和 ERC20 余额过滤器。
- 最近的日志活动过滤器。
- 针对提现、领取、赎回、清空、救援、派发、接收者重定向、关键地址替换、重入、初始化/升级、delegatecall、签名、预言机和代币转账模式的静态源码分类。
- 针对常见误报的只读预检:EIP-1967 实现或 beacon 槽、Gnosis Safe 阈值、AMM 池状态和 owner 调用。
- 检测后验证门,在选择监控警报之前,将候选者与仅监视和误报的记录区分开来。
- 候选证据包以及用于分析师反馈的仅追加人工裁决循环。
- 由配置驱动的 Ethereum、Base、Arbitrum、Optimism、Polygon、BNB Smart Chain、Avalanche、Linea、Scroll、zkSync Era、Gnosis、Blast、Mantle 和 Celo 监控器。
Solana:
- BPF Upgradeable Loader 签名轮询。
- 部署、升级、关闭和权限更改事件提取。
- 程序和程序数据账户元数据。
- 针对 SOL、WSOL、USDC 和 USDT 的近期交易价值上下文。
- 针对常见噪声的抑制:WSOL 代币账户的 lamports、曲线上钱包、已签名的代币所有者、程序/程序数据租金以及已知的共享价值账户。
Solana 的价值上下文是刻意设计得较为保守的。在程序附近看到的一个大型代币账户并不能证明该程序控制着这些资金。
## 布局
```
config/
smart-contract-evm-chains.json
smart-contract-non-evm-chains.json
scripts/
smart-contract-batch-scan.py
eth-sourcify-list.py
eth-sourcify-intake.py
eth-live-contract-filter.py
eth-runtime-precheck.py
eth-high-value-triage.py
eth-continuous-monitor.py
smart-contract-add-verdict.py
evm-monitor-config.py
solana-program-monitor.py
non-evm-monitor-config.py
run-eth-contract-batch.py
run-eth-live-batch.py
docs/
smart-contract-chain-coverage.md
tests/
fixtures/
run_regression.py
```
有关下一个链家族和检测器工作,请参阅 `ROADMAP.md`。
## 环境要求
- Python 3.11+
- 无需 Python 包依赖
- 可选 Docker
- 用于实时过滤器和监控的 JSON-RPC 端点
公共 RPC 端点适用于小型检查。对于持续监控或大批量任务,请使用具有已知速率限制的端点。
## 快速开始
运行回归测试套件:
```
python tests/run_regression.py
```
扫描本地源文件:
```
python scripts/smart-contract-batch-scan.py tests/fixtures --out-dir tmp/scan
```
Windows:
```
py -3 .\tests\run_regression.py
py -3 .\scripts\smart-contract-batch-scan.py .\tests\fixtures --out-dir .\tmp\scan
```
## EVM 批处理工作流
扫描本地源代码树:
```
python scripts/smart-contract-batch-scan.py ./contracts --out-dir ./runs/local-scan
```
从 Sourcify 下载已验证的源代码并进行扫描:
```
python scripts/run-eth-contract-batch.py \
--chain-id 1 \
--limit 100 \
--run-dir ./runs/eth-mainnet-100 \
--delay-seconds 0.35
```
扫描地址列表:
```
python scripts/run-eth-contract-batch.py \
--chain-id 1 \
--addresses-file ./input/addresses.txt \
--run-dir ./runs/address-list
```
`addresses.txt` 每行接受一个地址。底层的接入脚本也接受 `,` 格式的行。
构建一个实时过滤的队列:
```
python scripts/run-eth-live-batch.py \
--chain-id 1 \
--candidate-limit 5000 \
--keep-limit 200 \
--run-dir ./runs/eth-live-200 \
--require-activity \
--min-recent-logs 1 \
--balance-score-weight
```
通过运行时预检和带排名的分类报告执行更严格的运行:
```
python scripts/run-eth-live-batch.py \
--chain-id 1 \
--candidate-limit 50000 \
--keep-limit 500 \
--run-dir ./runs/eth-live-strict \
--require-threshold-balance \
--require-activity \
--min-recent-logs 1 \
--recent-blocks 2000 \
--balance-score-weight \
--runtime-precheck \
--high-value-triage \
--request-delay 0.1
```
对于非主网的 EVM 链,需显式传入代币过滤器:
```
python scripts/run-eth-live-batch.py \
--chain-id 8453 \
--rpc-url https://base-rpc.publicnode.com \
--candidate-limit 10000 \
--keep-limit 200 \
--run-dir ./runs/base-live \
--eth-min-wei 300000000000000000 \
--token 0x4200000000000000000000000000000000000006=WETH:18:0.3 \
--token 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913=USDC:6:500
```
在依赖非主网运行结果之前,请检查代币地址、小数位数和阈值。默认值为 500 美元样式的价值过滤器,而非价格预言机。
## 持续 EVM 监控
列出已配置的链:
```
python scripts/evm-monitor-config.py list
```
探测单条链:
```
python scripts/evm-monitor-config.py probe --only ethereum
```
生成 systemd 单元:
```
python scripts/evm-monitor-config.py systemd \
--out-dir ./tmp/systemd-evm \
--only ethereum \
--remote-root /opt/smart-contract-risk-triage \
--python /usr/bin/python3 \
--no-telegram
```
直接运行一个周期:
```
python scripts/eth-continuous-monitor.py \
--chain-id 1 \
--chain-label Ethereum \
--workspace . \
--state-dir runs/monitor-state/ethereum \
--rpc-url https://ethereum-rpc.publicnode.com \
--seed-if-empty \
--delete-uninteresting
```
在公共配置中,Telegram 警报默认是关闭的。要启用它们,请设置:
- `SMART_CONTRACT_ALERT_BOT_TOKEN`
- `SMART_CONTRACT_ALERT_CHAT_ID`
该聊天 ID 必须是正数的私有聊天 ID。监控器会在调用 `sendMessage` 之前拒绝频道和群组样式的 ID。
EVM 监控警报仅从验证后的 `candidate`(候选)记录中选择。`false-positive`(误报)、`watch-only`(仅监视)和 `needs-review`(需审查)的记录将保留在分类工件中以供审查,而不会触发 Telegram。
## Solana 监控
列出非 EVM 链:
```
python scripts/non-evm-monitor-config.py list
```
探测 Solana RPC:
```
python scripts/non-evm-monitor-config.py probe --only solana
```
运行一个 loader 监控周期:
```
python scripts/solana-program-monitor.py \
--workspace . \
--state-dir runs/monitor-state/solana \
--rpc-url https://api.mainnet-beta.solana.com \
--candidate-limit 120 \
--transaction-batch-size 1 \
--allow-cursor-skip \
--seed-if-empty \
--delete-uninteresting
```
公共 Solana RPC 可能会对 `getTransaction` 进行速率限制。请保持较小的窗口,使用延迟,并将 `cursorSkipped=true` 视为“已处理最近的有限窗口”,而不是历史的完整性。
## 输出
静态扫描器:
- `contracts-manifest.jsonl`
- `all-signals.jsonl`
- `critical-review.md`
实时过滤器:
- `live-targets.txt`
- `live-filter-results.jsonl`
- `live-filter-summary.json`
运行时和高价值 EVM 分类:
- `runtime-precheck.json`
- `triage/high-value-triage.md`
- `triage/high-value-triage.jsonl`
- `triage/high-value-triage-summary.json`
- `triage/candidate-evidence-packs.md`
- `triage/candidate-evidence-packs.json`
人工 EVM 裁决:
- 默认为 `reports/smart-contract-verdicts.jsonl`
- 通过 `eth-high-value-triage.py --verdicts-file` 自定义 JSONL 路径
- 追加助手:`scripts/smart-contract-add-verdict.py`
Sourcify 接入:
- `sources/`
- `sourcify-summary.json`
- `failures.jsonl`
持续监控会在 `runs/` 目录下写入紧凑的状态和事件文件。使用 `--delete-uninteresting` 参数时,它们会删除没有可审查信号的运行目录。
## 阅读发现
对于 EVM 发现:
- `severity` 表示队列优先级。
- `confidence` 表示检测器对该模式的置信度。
- `score` 表示排序权重。
- `category` 表示风险类别。
- `funds_at_risk` 表示该模式似乎触及了价值转移。
- `manual_check` 说明接下来要验证什么。
- `validation.verdict` 是警报门控:只有 `candidate` 才能触发警报。
- 候选证据包描述了正向门控和下一步的人工检查。
审查顺序:
1. 确认范围。
2. 确认被标记的文件与运行时相关。
3. 检查当前的原生代币和代币余额。
4. 检查状态前置条件:proxy 槽、Safe 阈值、AMM 状态、owner/admin 角色、nonce/domain 防护、领取位图等。
5. 决定程序规则是否允许任何证明步骤。
对于 Solana,不要仅凭价值进行升级处理。检查代币所有者、签名者、PDA 或来源关系、升级权限以及项目上下文。
## 运行时预检数据
从目标列表生成预检数据:
```
python scripts/eth-runtime-precheck.py \
--targets-file ./runs/eth-live/live-filter/live-targets.txt \
--out ./runs/eth-live/runtime-precheck.json \
--rpc-url https://ethereum-rpc.publicnode.com
```
在扫描期间使用它:
```
python scripts/smart-contract-batch-scan.py ./sources \
--out-dir ./runs/scan-with-precheck \
--precheck-json ./runs/eth-live/runtime-precheck.json
```
预检只会降低已知误报类别的优先级。它们并不能证明合约是安全的。
## Docker
```
docker compose build
docker compose run --rm scanner --chain-id 1 --limit 10 --run-dir /runs/eth-mainnet-10
```
挂载路径:
- `./runs` -> `/runs`
- `./input` -> `/input` 只读
## 开发
在更改检测器逻辑之前运行这些:
```
python tests/run_regression.py
python scripts/evm-monitor-config.py list
python scripts/non-evm-monitor-config.py list
python scripts/public-sanity-check.py
```
预期基准:
```
Scanned files: 16
Findings: 39
Severity: critical=8 high=3 medium=15 low=13 info=0
Regression OK
```
预期的关键合成案例:
- `FinanceBank.Collect`
- `MockPoolManager.take`
- `AddressSubstitution.sol` 中的地址替换路径
如果计数发生变化,请更新或添加 fixtures,并在提交中解释行为更改。
## 负责任的使用
不要将未解决的输出作为已确认的漏洞发布。在进行任何外部报告之前,请验证授权、运行时/源代码匹配、当前状态、攻击者前置条件、重复状态和程序规则。
## 局限性
- 静态分析是启发式的。
- 运行时预检仅涵盖已知的误报类别。
- 代币过滤器是特定于链的,并且可能会失效。
- 源代码包可能包含非运行时文件。
- 公共 RPC 端点可能会进行速率限制或省略某些方法。
- 该工具不对完整的协议经济学进行建模。
- Solana 支持是 loader 事件监控和价值邻近性分类,而不是 Rust/Anchor 分析器。
- 严重性标签是分类标签,不是 CVSS 或赏金严重性。
标签:EVM, Solana, 区块链安全, 智能合约审计, 自动化分析, 请求拦截, 跨站脚本, 逆向工具, 错误基检测, 静态代码分析, 风险筛查