th13vn/w3goaudit

GitHub: th13vn/w3goaudit

一个基于 Go 的 Solidity 智能合约安全审计工具,通过 WQL 查询语言和规则模板实现自动化的漏洞模式扫描与报告生成。

Stars: 0 | Forks: 0

# W3GoAudit [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](./LICENSE) [![Go Reference](https://pkg.go.dev/badge/github.com/th13vn/w3goaudit.svg)](https://pkg.go.dev/github.com/th13vn/w3goaudit) 一个基于 Go 的 CLI 和 SDK,用于通过基于规则的模板和 WQL 查询语言审计 Solidity 智能合约。 ## 快速开始 ``` # Install (templates download on first run; embedded pack is the offline fallback) go install github.com/th13vn/w3goaudit/cmd/w3goaudit@latest # Scan contracts → writes a ./contracts-audit result folder # (the "-audit" suffix is the collision guard: the output can't overwrite the scanned dir) w3goaudit ./contracts/ # Scan one file into a named folder w3goaudit Token.sol -o audit/ # Use a custom template directory w3goaudit ./contracts/ -t ./my-templates/ # Only high + critical findings w3goaudit ./contracts/ -s high,critical # Print the summary only, write nothing w3goaudit ./contracts/ -q # Build database w3goaudit build ./contracts/ -o database.json # Extract contract info — every extract subcommand can build from a source # path (like the scan) or load a pre-built database with --db w3goaudit extract main ./contracts/ w3goaudit extract inheritance MyToken ./contracts/ w3goaudit extract entry MyToken --db database.json ``` 控制台输出示例: ``` ▶ Reading sources: ./contracts/ ▶ Building database: 74 files, 164 contracts, 1203 functions ▶ Scanning: 25 templates (~/.w3goaudit/templates) ▶ Writing report: ./contracts-audit 81 findings: 65 HIGH, 16 MEDIUM · scanned 74 contracts in 51ms ── Findings ────────────────────────────────────────────── 🟠 HIGH (65 findings) 1. Arbitrary transferFrom Call 2. Unchecked ERC20 transfer / transferFrom Return Value ... (titles only on console; full detail in findings.md, or use --verbose) 📂 Results written to: ./contracts-audit ``` 结果将生成在一个文件夹中 —— `README.md`(落地页)、`summary.md`、 `overview.md`、`findings.md`、`results.sarif`、`run.log`,一个机器可读的 `data/` 文件夹(JSON + 数据库 + manifest 索引),以及一个 `contracts/` 树(每个主合约一个子文件夹,映射源码路径),其中包含针对每个入口的工作流文件和状态更改报告。请参阅[结果文件夹布局](#result-folder-layout)。 `overview.md` 是报告索引,并链接到详细的产出物。 ## 功能 - **AST 解析** - 使用 [solast-go](https://github.com/th13vn/solast-go) 解析 Solidity - **合约数据库** - 包含继承关系、入口点、调用图的全面数据库 - **语义类型事实** - 参数、状态变量、局部变量、类型转换和调用接收者携带轻量级的类型事实,因此 WQL 可以保持简单,同时调用分类变得更加精确 - **C3 线性化** - 正确的 Solidity 继承解析 - **函数标识** - `Function.Selector` 存储规范文本,例如 `transfer(address,uint256)`;`Function.Signature` 存储其四字节的 Keccak 值,例如 `a9059cbb` - **调用图** - 过滤内置函数并进行优化样式的递归追踪 - **精确标识** - 内部合约使用 `absPath#Contract`;函数使用 `absPath#Contract.selector(types)`。精确的 C3 `LinearizedBaseIDs` 和已解析的导入来源可防止不同文件中的重名发生交叉串联。 - **精确位置** - 从 1 开始、半开的 Unicode 码点列,以及从 0 开始、半开的 UTF-8 字节偏移量。SARIF 声明 `columnKind: unicodeCodePoints`,并且绝不将字节偏移量作为 `charOffset`/`charLength` 发出。这些不是 LSP 位置;LSP 的行和字符是从 0 开始的,并且通常使用 UTF-16 码元。 - **WQL 模板** - 用于安全模式匹配的强大查询语言,具备加载时验证(正则表达式、预设名称、过滤器/匹配器放置),确保拼写错误能快速失败,而不是默默地产生零结果的扫描。包含一个用于罕见原始来源谓词的源码范围 `regex` 匹配器,以及用于同合约局部/继承组合规则的合约范围 AST 匹配。 - **结果文件夹** - 每次扫描生成一个专属文件夹:一个 `README.md` 落地页,`summary.md`,`overview.md`(指标 + 范围内合约索引),`findings.md`,始终生成的 `results.sarif` + `run.log`,一个机器可读的 `data/`(`manifest.json`、可重用的 `database.json`、findings/overview、始终生成的 `diagnostics.json`,以及用于编辑器扩展的 nav/explorer/xref 数据),以及一个映射源码路径的 `contracts/` 树。可选择通过 `--html` 开启**完全离线**的 HTML 镜像(内嵌图形库 —— 无 CDN 请求)。 - **针对每个入口的工作流文件** - 为每个入口函数提供一个独立的上下文块(签名、认证 / 访问控制、守卫与检查、分支条件、传递的状态影响、Mermaid 调用工作流)—— 专为提供给人类或 AI 审计员而构建。 - **状态更改矩阵** - 针对每个合约,将每个状态变量映射到对其进行写入的函数,以及能够到达写入操作的入口点(反向调用图遍历)。 - **自提供模板** - 首次运行时下载最新的 [`w3goaudit-templates`](https://github.com/th13vn/w3goaudit-templates) 发行版(nuclei 风格,无需 git clone),可通过 `--update-templates` 刷新;内置的官方包是始终可用的离线后备方案。解压缩具有大小/文件数量上限,并通过回滚安全的分阶段目录交换进行安装。GitHub zipball 通过 TLS 进行身份验证,但未校验校验和/签名。 - **感知可达性的发现** - 每个发现都可以携带从外部可调用入口一直到托管危险语句的函数的完整调用链:结构化的 `reachability.steps[]` + `entryPoint`(审计员的修复指向标)+ JSON 中的 `primaryAst`,SARIF 中的 `relatedLocations`,Markdown / HTML 中的点级别追踪块,以及 `--verbose` 控制台上的 `↳ via …` 延续行。多位置发现还携带 `related[]`,Markdown 会渲染所有具有完整函数上下文的匹配位置。 - **SARIF 2.1.0** - 始终为 GitHub Code Scanning 生成 (`results.sarif`),带有可移植的相对 URI + `srcRoot`;故障时封闭的模板加载,支持 `NO_COLOR` 的控制台。 - **编辑器交叉引用** - `data/xref.json` 将 `declarations[]` 跳转目标与携带声明 `refId` 的 `references[]` 出现位置配对,因此编辑器可以进行精准的 go-to-definition 和 find-references(状态变量、参数、局部变量、已解析的调用、库 `using`、UDVT `wrap`/`unwrap`、类型转换、`revert`/`emit` 目标、应用的 modifier),而无需正则表达式兜底。请参阅[扩展输出](./docs/extension-output.md)。 - **项目检测** - 自动检测 Foundry、Hardhat、Truffle - **导入解析** - 优先使用 Foundry remappings(感知配置文件和上下文,针对每个子项目),然后是 `node_modules/`/`lib/`/根目录搜索,最后是作为最后手段的约定布局和唯一后缀启发式方法,从而确保未提供 remappings 文件的区块浏览器抓取的源码依然能链接。启发式方法仅接受扫描树中已存在的文件,并在出现歧义时弃权;任何仍未解析的内容都会记录在 `data/diagnostics.json` 中。 - **Git 集成** - 自动检测 git 仓库并生成指向 GitHub/GitLab 的可点击文件链接 - **高级指标** - nSLOC、访问控制分析、分组入口点 - **源码提取** - 提取函数源码、上下文包以及完整的传递工作流源码 ## 文档 可在 [`docs/`](./docs) 中获取综合指南: - **[工作流](./docs/workflows.md)** - 带有图表的详细内部工作流 - **[使用指南](./docs/usage.md)** - 完整的 CLI 和 SDK 参考 - **[SDK 文档](./docs/sdk.md)** - 全面的 SDK API 参考和集成指南 - **[WQL 语法](./docs/wql-syntax.md)** - 模板编写参考 - **[扩展输出](./docs/extension-output.md)** - 用于编辑器集成的 `data/nav.json` + `data/explorer.json` + `data/xref.json` 架构 - **[项目概述](./docs/project-overview.md)** - 架构与设计 - **[内部原理](./docs/internals.md)** - 深入技术解析:函数、工作流、算法(C3、污点分析、访问控制)以及精度/边缘情况决策 ## 安装 ### 从源码安装 ``` # Clone the repository git clone https://github.com/th13vn/w3goaudit cd w3goaudit # Build go build -o w3goaudit ./cmd/w3goaudit # Move to PATH (optional) sudo mv w3goaudit /usr/local/bin/ ``` ### 通过 Go Install 安装 ``` go install github.com/th13vn/w3goaudit/cmd/w3goaudit@latest ``` ### 自我更新 ``` w3goaudit --update # re-runs `go install …@latest` (requires the Go toolchain) ``` ## 结果文件夹布局 每次扫描(除非使用 `--stdout/-q`)都会写入一个结果文件夹,该文件夹经过优化,专为提供给人类或 AI 审计员而设计: ``` / ├── README.md # landing page: counts + links to everything ├── summary.md # metrics + findings-by-severity + rules-hit tables ├── overview.md # metrics + in-scope contract index (table, links into contracts/) ├── findings.md # human-readable findings ├── results.sarif # SARIF 2.1.0 (always) ├── run.log # full verbose detail (always; replaces --log) ├── data/ # machine-readable output │ ├── manifest.json # index: tool, scope, counts, file list, per-contract refs │ ├── database.json # canonical DB — reuse via --db data/database.json │ ├── findings.json │ ├── overview.json │ ├── diagnostics.json # analysis-quality diagnostics; [] when complete │ ├── nav.json # flat symbol/caller/interface-impl index (extension) │ ├── explorer.json # per-main-contract model: constants, storage, entry/getter fns │ └── xref.json # precise xref: declarations[] + references[] (go-to-def / find-refs) └── contracts/ # one sub-tree per main contract, mirroring source paths └── / └── / ├── README.md # per-contract landing: findings + architecture detail ├── state-changes.md # state var → Written By (fns) → Reachable From (entries) └── workflows/ ├── .md # one file per entry function └── __.md # overloads disambiguated by 4-byte selector ``` 默认文件夹名称是被扫描项目的目录名(或 `.sol` 文件名); `-o/--output` 可以覆盖它,如果默认名称与被扫描目录冲突,则会追加 `-audit`。每个 `workflows/.md` 记录签名 (选择器、4 字节、是否 payable、版本)、认证 / 访问控制(modifier、 `msg.sender` 检查、⚠ 无保护、⚠ tx.origin)、守卫/检查、分支 条件、传递的状态影响,以及 Mermaid 调用工作流图。 `data/manifest.json` 区分检测到的 `projectRoot` 和原始的 `scanTarget`(`target` 是兼容性别名),将声明类别的计数进行分类,公开 `analysisComplete`/诊断计数,并为每个发出的产出物建立索引。发现/内容的排序是确定性的;除非 SDK 调用者注入固定的报告/捆绑包时钟,否则生成的时间戳会有所不同。 ## CLI 快速参考 ### 命令 | 命令 | 描述 | | --------------------- | ------------------------------------------------------------------------------------------------ | | *(默认)* | 扫描合约 — 统计信息、概览、发现结果 | | `build` | 构建合约数据库 (JSON) | | `extract main` | 项目中的主(可部署)合约 | | `extract entry` | 合约的入口点函数 | | `extract inheritance` | C3 线性化 (派生 → 基类) — 必须是主合约 | | `extract statevar` | 状态变量 (包含继承的变量、存储顺序) | | `extract selector` | 函数选择器 (4 字节哈希) | | `extract involve` | 每个到达某个函数的入口点工作流,每个入口点对应一张 Mermaid 图表 | | `extract workflow` | 入口函数的完整传递源码 (可直接用于报告) | | `extract bundle` | **适配 LLM** 的单文档上下文:源码 + 调用者 + 被调用者 + 状态 + 继承 + 选择器 | | `extract context` | 函数的组合上下文包 | | `extract source` | 函数的原始 Solidity 源码 | | `extract diff` | 比较两个预构建的数据库 | | `completion` | 生成 shell 自动补全脚本 | | `version` | 显示版本信息 | 根命令**即为**扫描(没有 `scan` 子命令)。每个扫描 flag 都有长和短格式:`-o/--output`、`-t/--template`、`-d/--db`、 `-v/--verbose`、`-s/--severity`(精确匹配集合)、`-m/--min-severity`(阈值)、 `-i/--include`、`-e/--exclude`、`-l/--list-templates`、`-H/--html`、 `-q/--stdout`、`--strict-imports`、`-T/--update-templates`、`-u/--update`。 `--severity` 和 `--min-severity` 是互斥的。默认情况下,导入解析具有容错性;当未解析的导入必须导致源码扫描或等效的 `--db` 缓存扫描失败时,请使用 `--strict-imports`。导入警告始终写入 stderr。 `extract` 子命令按范围从大到小列出(项目 → 合约 → 函数 → 实用工具)。与扫描一样,其中每一个(除了 `diff`)都可以**从源码路径构建** — `extract ./contracts/` — 或者使用 `--db` 加载预构建的数据库。提取输出默认为 **markdown**;传递 `--format=json`(或 `-o file.json`)以获取机器可读的格式。 合约查询接受精确的 `file#Contract` ID 或唯一名称。函数 查询接受精确的函数 ID、`Contract.selector`、完整的选择器、4 字节签名或唯一的裸名称。模糊查询将失败并显示排序后的候选列表,而不是按 map 顺序进行选择;`--contract` 遵循相同的精确 ID 或唯一名称规则。 ### 示例 ``` # Default scan → writes a ./contracts-audit result folder (collision guard adds "-audit") w3goaudit ./contracts/ # Scan one file into a named folder w3goaudit Token.sol -o audit/ # Use a custom template directory w3goaudit ./contracts/ -t ./templates/official/ # Only high + critical (exact set), or a threshold + exclude glob w3goaudit ./contracts/ -s high,critical w3goaudit ./contracts/ -m medium -e 'HIGH-WEAK-PRNG' # Also emit the HTML mirror, or print the summary only (write nothing) w3goaudit ./contracts/ -H w3goaudit ./contracts/ -q # List the active template set (no path needed) w3goaudit -l # Re-scan a pre-built database (e.g. the DB from a previous run) w3goaudit -d ./contracts/data/database.json # Fail closed when any persisted/source import is unresolved w3goaudit ./contracts/ --strict-imports w3goaudit -d ./contracts/data/database.json --strict-imports # Refresh templates from the latest release; update the tool itself w3goaudit --update-templates w3goaudit --update # Extract directly from source (builds the database on the fly) w3goaudit extract main ./contracts/ w3goaudit extract statevar MyToken ./contracts/ # …or build once and reuse the database across many extracts w3goaudit build ./contracts/ -o db.json w3goaudit extract entry MyToken --db db.json w3goaudit extract selector MyToken --db db.json w3goaudit extract diff --db1 old.json --db2 new.json # LLM-ready bundle: one markdown document with source + callers/callees + state + inheritance w3goaudit extract bundle withdraw --db db.json --contract MyToken -o bundle.md # Every workflow that reaches a function, as markdown for AI agents w3goaudit extract involve withdraw --db db.json --format=md # Shell completion source <(w3goaudit completion bash) ``` 有关完整用法,请参阅[使用指南](./docs/usage.md)。 ## SDK 快速参考 ``` import ( "log" "github.com/th13vn/w3goaudit/pkg/reader" "github.com/th13vn/w3goaudit/pkg/builder" "github.com/th13vn/w3goaudit/pkg/engine" ) // Read sources r := reader.New() inputPath := "./contracts/" projectRoot, err := reader.DetectProjectRoot(inputPath) if err != nil { log.Fatal(err) } sources, err := r.Read(inputPath) if err != nil { log.Fatal(err) } if err := r.ResolveImports(projectRoot); err != nil { log.Fatal(err) } sources = r.GetAllSources() // Build database b := builder.New() db, err := b.Build(sources) if err != nil { log.Fatal(err) } // Execute template e := engine.New(db) tmpl, err := engine.LoadTemplate("./template.yaml") if err != nil { log.Fatal(err) } findings := e.Execute(tmpl) ``` 有关完整的 SDK 文档,请参阅[使用指南](./docs/usage.md#sdk-usage)。 ## WQL 模板示例 ``` meta: id: SEC-REEN-001 title: Potential Reentrancy severity: HIGH confidence: MEDIUM description: External call before state variable update recommendation: Apply Check-Effects-Interactions pattern query: from: entry_function # public/external functions of main contracts where: - not: { preset: reentrancy_guarded } - sequence: - block: outgoing_call - block: state_write ``` 这是 **WQL** (W3GoAudit Query Language)。WQL 文档由元数据加上一个 query: 块组成。 该块包含 `select`/`from`/`where`,或者一个查询级别的 `and:`/`or:` 组合。所有 106 个代码库模板(25 个官方、5 个功能测试、以及 76 个基准测试)都在使用它;请参阅 [WQL 语法指南](./docs/wql-syntax.md) 获取完整的语言参考。 ## 项目结构 ``` w3goaudit/ ├── cmd/w3goaudit/ # CLI entry point (root scan, build, extract, completion) ├── pkg/ │ ├── reader/ # File discovery and loading │ ├── logging/ # Immutable scan-local logger │ ├── builder/ # Database construction (7 phases incl. per-fn effects) │ ├── engine/ # WQL template execution │ ├── home/ # ~/.w3goaudit config + template home (release download) │ ├── types/ # Core data structures │ └── report/ # Result-folder bundle, state matrix, console/MD/HTML/SARIF ├── templates/ # WQL detection templates (official/ embedded via go:embed) │ ├── official/ # Curated official pack (embedded fallback; split by severity: critical/ high/ medium/) │ └── test/ # Engine feature-exercise templates ├── benchmarks/ # Stored dated benchmark reports + Git-ignored results/ scratch # (the benchmark harness itself lives in the git-ignored, dev-only scripts/) ├── test-data/ # Test contracts (core/, security/) └── docs/ # Comprehensive documentation ``` ## 核心工作流 ### 1. 扫描工作流 ``` Input → Reader → Builder → Database → Engine → Findings → Result-folder bundle ``` 1. 发现 `.sol` 文件 2. 使用 solast-go 进行解析 3. 构建数据库(继承关系、调用图、选择器、每个函数的影响) 4. 加载 WQL 模板(主目录 → 内置后备方案) 5. 执行查询 6. 生成发现结果 7. 写入结果文件夹(概览、发现、SARIF、run.log、data/、针对每个合约的工作流 + 状态变更) ### 2. 构建工作流 构建阶段: 1. 解析文件 2. 构建 AST、数据流和语义类型事实 3. 计算规范的 `Function.Selector` 文本和 4 字节的 `Function.Signature` 值 4. 构建继承关系 (C3) 5. 构建调用图 6. 计算入口点 7. 分析每个函数的影响(状态写入、守卫、访问控制) ### 3. 默认扫描(组合)工作流 默认扫描结合了统计信息、概览索引和发现结果: - 统计信息(文件、合约、函数、nSLOC) - 链接到每个合约架构报告的合约索引 - 安全发现(当提供模板时) 有关详细工作流,请参阅[工作流文档](./docs/workflows.md)。 ## 数据库结构 合约数据库包含: - **合约** - 所有具有类型、继承关系、函数、状态变量的合约 - **函数** - 可见性、modifier、参数、选择器、AST 树 - **继承关系** - 用于正确进行方法解析的 C3 线性化 - **调用图** - 带有行号的内部/外部调用边 - **入口点** - 每个主合约的 public/external 函数 - **主合约** - 按继承深度排序的可部署合约 ## 测试 开发使用 `go.mod` 中声明的确切 Go 版本(目前为 Go 1.26.5)。这个基于安全考量的最低版本限制包含了 govulncheck 所需的标准库修复。在发布之前,运行格式化、`go mod tidy -diff`、 vet、staticcheck、圈复杂度、Markdown 链接检查、 normal/race/shuffled 测试、宿主机和 Linux ARM64 构建、govulncheck、完整的 官方扫描/产出物冒烟测试,以及在本地或用户拥有的外部自动化环境中运行 Docker Compose 竞争基准测试。 ``` # Build database w3goaudit build test-data/core/build-database/ -o test-db.json --verbose # Security scan → writes a test-data/security result folder w3goaudit test-data/security/ --template templates/official/ -o scan-report/ # Project overview (always part of the scan — see overview.md in the folder) w3goaudit test-data/core/build-database/ -o overview-out/ # Competitive quality gate (maintainer-only): the benchmark harness under # scripts/ is dev-only and git-ignored, so these commands run only where the # harness is checked out; a fresh clone does not include it. # Gate: precision >= 0.65, recall >= 0.95, failed cases = 0. Local CLI, no Docker. go build -o /tmp/w3goaudit ./cmd/w3goaudit python3 scripts/benchmark/run_benchmark.py --suite competitive --tools w3goaudit \ --w3goaudit-bin /tmp/w3goaudit --out benchmarks/results/latest python3 scripts/benchmark/assert_thresholds.py benchmarks/results/latest/benchmark.json # Docker Compose only for the multi-tool comparison (Slither/Semgrep/4naly3er). docker compose -f scripts/benchmark/compose.yaml run --rm benchmark ``` 已存储、受版本控制的基准测试报告位于 `benchmarks/` 目录下,表现为按日期命名的 `yyyy-mm-dd-.md` 文件;生成这些报告的测试工具仅用于开发。 测试合约记录在以下文件中: - [test-data/security/README.md](./test-data/security/README.md) - [test-data/core/build-database/README.md](./test-data/core/build-database/README.md) ## 路线图 ### 当前功能 - AST 解析和合约数据库 - C3 继承线性化 - 递归调用图构建 - 针对每个函数的影响分析(状态写入、守卫、访问控制) - WQL 查询语言 - 结果文件夹输出:Markdown + SARIF + JSON data/ + 针对每个入口的工作流 + 状态更改矩阵 - 自提供模板主目录 (`~/.w3goaudit`),支持发行版下载 + 内置后备方案 - CLI 和 SDK - 用于报告编写的源码/上下文/工作流提取 ### 计划功能 🔜 - 代码库扫描 - 链上合约获取 - 增强的数据流分析 - 可视化导出 - 面向 IDE 支持的 LSP 集成 - 模板市场 有关完整的路线图,请参阅[项目概述](./docs/project-overview.md#roadmap)。 ## 许可证 [MIT](./LICENSE) © th13vn. 第三方依赖和商标声明位于 [NOTICE](./NOTICE)。 ## 链接 - **文档**: [docs/](./docs) - **模板**: [templates/](./templates) - **测试数据**: [test-data/](./test-data) - **AST 解析器**: [solast-go](https://github.com/th13vn/solast-go)
标签:EVTX分析, Go语言, Solidity, 区块链安全, 日志审计, 智能合约审计, 程序破解, 自动化payload嵌入