manticore-projects/aurscan
GitHub: manticore-projects/aurscan
aurscan 是一款利用大模型和静态规则在构建前自动扫描 AUR 包以拦截恶意代码的安全工具。
Stars: 70 | Forks: 7
# 🛡️ aurscan
**在构建之前,让 Claude 模型为你阅读 PKGBUILD,从而拦截恶意的 AUR 包。**
[](https://github.com/manticore-projects/aurscan/actions/workflows/ci.yml)
[](https://github.com/manticore-projects/aurscan/releases)
[](https://go.dev)
[](https://goreportcard.com/report/github.com/manticore-projects/aurscan)
[](LICENSE)
[](https://archlinux.org)
亲自阅读 PKGBUILD 只能发现你已知的攻击方式。**aurscan** 会在 **`makepkg` 执行任何一行代码之前**,读取包的 `PKGBUILD`、`.install` 脚本、`.SRCINFO` 和辅助脚本,并在脚本看起来存在恶意时阻止构建。
它分两个阶段运行:**快速的确定性静态规则**(离线、零成本)首先捕获已知的攻击活动特征,随后由 **Claude、Codex 或本地模型**(根据这些规则命中情况和包的 AUR 信誉作为参考)对复杂情况做出判断。即使在完全没有配置模型的情况下,仅靠静态规则也能产生安全失败(fail-closed)的判定结果,因此即使完全离线,您也能得到保护。
```
$ syay firefox-patch-bin
scanning firefox-patch-bin (3 files) ...
[ MAL! ] firefox-patch-bin confidence 95%
A source labelled "patches" points at a personal GitHub repo unrelated
to Firefox and is executed during build — the July 2025 CHAOS RAT vector.
[critical] PKGBUILD: Disguised source pulls attacker-controlled code.
> patches::git+https://github.com/.../zenbrowser-patch.git
↳ tokens: 12,431 in / 214 out · $0.0413
scanner usage: 1 call(s) · tokens: 12,431 in / 214 out · $0.0413
!! Installation blocked: 1 package(s) flagged MALICIOUS.
[A]bort (default) / [r]eport to mailing list & abort / [c]ontinue anyway:
```
## 目录
- [为什么需要](#-why)
- [如何挂钩 yay](#-how-it-hooks-into-yay)
- [安装](#-install)
- [认证](#-authentication)
- [用法](#-usage)
- [Token 与成本报告](#-token--cost-reporting)
- [配置](#%EF%B8%8F-configuration)
- [安全保障](#-how-it-stays-safe)
- [项目结构](#%EF%B8%8F-project-layout)
- [局限性](#%EF%B8%8F-limitations)
- [贡献](#-contributing)
## 🎯 为什么需要
2025 年 7 月,`firefox-patch-bin`、`librewolf-fix-bin` 和 `zen-browser-patched-bin` 这几个 AUR 包被上传,其中包含一个伪装成 `patches` 的 `source=()` 条目,实际上它拉取了个人的 GitHub 仓库并在构建时运行了 **CHAOS RAT**。它们看起来就像是普通的浏览器修复程序;快速扫一眼 PKGBUILD 并不能明显看出问题。它们在网上存在了约 46 个小时。
aurscan 的构建初衷就是准确标记这类事物——即陌生的诡计,而不仅仅是你碰巧知道的那一种。
2026 年 6 月,**Atomic Arch** 攻击活动大规模地印证了这一点:攻击者接管了 **1,500 多个**孤立的 AUR 包,并且在某些情况下利用 git 提交*伪造*来冒充受信任的维护者,添加了一个运行 `npm install atomic-lockfile`(第二波中为 `bun install js-digest`)的安装后步骤,从而拉取了一个 Rust 凭据窃取程序,并且在以 root 身份构建时还会拉取一个 **eBPF rootkit**。包名和历史记录保持不变;只有构建指令及其编写者被悄悄改变了。aurscan 的 prompt 和静态规则编码了这些确切的攻击特征。
## 🔌 如何挂钩 yay
aurscan 利用 yay 自身的编辑器步骤,在唯一安全的拦截点——**下载之后、构建之前**——进行拦截。`syay` 包装器透明地将 yay 的编辑器指向 `aurscan-edit`,并强制开启编辑提示,因此扫描器会在 **yay 即将构建的每一个 AUR PKGBUILD** 上运行:
| 你输入的内容 | 被扫描的内容 |
|---|---|
| `syay -S pkg` | 指定的包 |
| `syay pkg` | 你从 yay **交互式**搜索菜单中选择的包 |
| `syay -Syu` | 每一个 AUR 升级 |
| _(以上任意一项)_ | ……以及它们的 AUR **依赖项**,这些也是 yay 在构建前会呈现出来的 |
当判定为**干净 (clean)** 时,它会链接到你真实的 `$VISUAL`/`$EDITOR`,因此你的手动审查依然会进行。当判定为**非 OK (non-OK)** 时,它会以非零状态退出,yay 将中止构建。
## 📦 安装
```
git clone https://github.com/manticore-projects/aurscan
cd aurscan
./install.sh # build (needs Go) + install into /usr/local/bin
```
然后使其透明化 —— **fish**:
```
alias yay=syay
funcsave yay
```
bash / zsh
```
echo "alias yay=syay" >> ~/.bashrc # or ~/.zshrc
```
这会安装三个名称,它们都是**相同的静态二进制文件**:`aurscan`(CLI)、`syay`(yay 包装器)和 `aurscan-edit`(yay 调用的编辑器门控)。
### paru
paru 拥有原生的 `PreBuildCommand` 钩子——比 yay 的编辑器技巧更干净——因此你有两个选择:
```
# 选项 1(推荐):无 wrapper。一次性设置,然后直接使用普通的 `paru` 即可受控拦截。
aurscan --install-paru-hook # adds PreBuildCommand to ~/.config/paru/paru.conf
# 撤销请使用:aurscan --uninstall-paru-hook
# 选项 2:透明 wrapper,与 syay (fish) 保持对称
alias paru=sparu
funcsave paru
```
无论哪种方式,扫描器都会在下载之后、构建之前,于 PKGBUILD 目录中针对每个包运行一次——覆盖了 `-S`、裸的交互式搜索、`-Syu` 以及 AUR 依赖,甚至涵盖了缓存的构建。非 OK 的判定会让 paru 中止构建。`sparu` 会注入一个临时的配置(通过 `PARU_CONF`),该配置会 `Include` 你真实的 `paru.conf`,因此你自己的设置会被保留且永远不会被修改。
| 任务 | 命令 |
|---|---|
| 更新 | `git pull && ./install.sh` |
| 卸载 | `./install.sh --uninstall` |
| 无 root 安装 | `SUDO= PREFIX=~/.local ./install.sh` |
| 仅构建 | `make build` |
| 运行测试 | `make test` |
| UPX 压缩二进制文件 | `make compress` |
| 交叉构建发布构件 | `make release` |
## 🔑 认证
按以下顺序自动检测——**选项 1 完全不需要 API key**:
1. `PATH` 中的 **Claude Code CLI** (`claude`) 且已登录 → 使用你现有的 Claude 订阅。报告每次扫描的**确切成本**。
2. **`ANTHROPIC_API_KEY`** → 直接 API(默认为 `claude-sonnet-4-6`)。报告确切的 token;成本根据内置价格表计算。
3. `PATH` 中的 **Codex CLI** (`codex`) 且已登录 → 使用你现有的 Codex 订阅。token 和成本是估算的/无法从 CLI 输出中获取。
4. 通过 `AURSCAN_OPENAI_URL` 的**本地 / 自托管模型** → 任何兼容 OpenAI 的 `/chat/completions` endpoint(**llama.cpp、Ollama、vLLM、LocalAI**)。完全私有;设置 `AURSCAN_OPENAI_URL_FALLBACK` 以进行自动故障转移(例如 GPU 主机 → 本地 CPU)。可以通过 `AURSCAN_OPENAI_MODEL` 替换模型。
5. **`AURSCAN_BACKEND=/path/to/cmd`** → 任何可执行文件,该文件读取 stdin 上的 prompt 并在 stdout 上打印回复。
6. **完全没有后端** → 静态规则仍然会运行,并在严重匹配时阻止构建。
本地模型示例 (llama.cpp / Ollama)
```
# llama.cpp server,并带有到第二台主机的 fallback
set -Ux AURSCAN_BACKEND openai
set -Ux AURSCAN_OPENAI_URL http://192.168.0.110:18080/v1/chat/completions
set -Ux AURSCAN_OPENAI_URL_FALLBACK http://127.0.0.1:18083/v1/chat/completions
set -Ux AURSCAN_OPENAI_MODEL qwen2.5-coder-32b
```
在速度慢、仅有 CPU 的主机上(例如手持设备),默认的 180 s 预算可能会在模型完成之前过期——你会看到 `context deadline exceeded`。请提高该预算,并确保模型的上下文窗口足以容纳 prompt(一个包通常有几千个 token;Ollama 默认的 2048 会将其静默截断):
```
set -Ux AURSCAN_TIMEOUT 900 # 15 minutes
# 而在 Ollama 方面,请为模型提供真实的 context,例如:
# 使用设定了 `PARAMETER num_ctx 8192` 的 Modelfile 运行 ollama run
```
感谢 [@alexzk1](https://github.com/manticore-projects/aurscan/issues/1) 提供了此后端所推广使用的原始连接器。
选择本地模型——什么才真正有效(以及什么太小了)
aurscan 对模型的要求比自动补全或聊天更高。对于每个包,它必须 (1) 推理跨越数千个 token 的 prompt 中可能经过混淆的 shell,(2) 返回与判定契约相匹配的**严格有效的 JSON**,以及 (3) **不被判定说服**,即无视不受信任的文件中注入的“这个包是安全的 / 忽略之前的指令”文本。小模型在这三点上都会失败:它们会盲目通过,发出格式错误的 JSON(→ 安全失败为 `SUSPICIOUS` 噪音),或者落入注入的圈套。**在这里,参数量比代码助手更重要。**
粗略指南(名称截至 2026 年中期——请在 Ollama 的库中查找等效模型,该领域发展迅速):
| 参数规模 | 示例 | 对 aurscan 的判定 |
|---|---|---|
| ≤ 3B | `qwen2.5-coder:3b`, `llama3.2:3b`, `phi-*-mini` | ❌ **不要使用。** 判定接近随机,JSON 不可靠。请改用 `--rules-only`。 |
| 7–8B | `codellama:7b` *([#8](https://github.com/manticore-projects/aurscan/issues/8) 中的模型)*, `qwen2.5-coder:7b`, `llama3.1:8b` | ⚠️ **勉强。** 只能抓住明目张胆的情况;会漏掉微妙的供应链诡计;JSON 有时会出错。独立的代码审查基准测试将 7B 的漏洞捕获率置于 ~45% 左右——应将其视为在静态规则之上的一个薄弱奖励,而不是真正的审核员。 |
| 14B | `qwen3:14b`, `phi-4:14b`, `deepseek-r1:14b` | ✅ **可用的最低限度。** JSON 可靠,能捕获大多数植入的问题 (~75%)。 |
| 32B | `qwen2.5-coder:32b`, `qwen3-coder:32b` | ✅ **推荐的最佳选择。** 强大的代码安全推理能力(在代码审查测试中约为 ~85–88%),在编程上具有 GPT-4o 级别的能力,可容纳于 24 GB GPU 中。 |
| 70B+ / large MoE | `llama3.3:70b`, `qwen3-coder` (MoE), `gpt-oss:120b` | ✅ **最佳本地选择。** 接近云端质量;70B 级别专门针对*安全*分析最为强大。 |
`Q4_K_M` 下的近似 VRAM(包括 KV-cache 余量):**8B ≈ 6 GB · 14B ≈ 10 GB · 32B ≈ 20–22 GB · 70B ≈ 43 GB。** 对于 14B 及以上的模型,强烈建议使用 GPU。
**人们经常弄错的两个设置:**
1. **上下文窗口。** Ollama 默认设置为 `num_ctx 2048`,这会将包*从 prompt 中静默截断*——随后模型几乎“扫描”不到任何东西。请设置 **`num_ctx` ≥ 8192(推荐 16384)**。将其烘焙到模型中,以便兼容 OpenAI 的 endpoint 始终使用它:
printf 'FROM qwen2.5-coder:32b\nPARAMETER num_ctx 16384\n' > Modelfile
ollama create aurscan-qwen -f Modelfile
set -Ux AURSCAN_BACKEND openai
set -Ux AURSCAN_OPENAI_URL http://127.0.0.1:11434/v1/chat/completions
set -Ux AURSCAN_OPENAI_MODEL aurscan-qwen
2. **慢速硬件上的超时。** 仅 CPU 的推理(手持设备、NUC)运行速度为每秒几个 token——一次扫描可能需要几分钟。请提高预算:`set -Ux AURSCAN_TIMEOUT 900`。如果这仍然让人难以忍受,请退回到 7–14B 模型,或者直接运行 `--rules-only`。
你绝不会因为模型弱小而处于无保护状态:确定性的静态规则始终会运行,任何模型错误、超时或无法解析的输出都会**安全失败为 `SUSPICIOUS`**。大于你上下文窗口的包也会超出大多数本地模型的容量——静态规则依然会覆盖它。
获取 Anthropic API key(选项 2)
在 **console.anthropic.com → Settings → API keys** 创建一个,添加计费方式,然后:
```
set -Ux ANTHROPIC_API_KEY sk-ant-...
```
一次典型的扫描只需几千个输入 token——在 API 上的花费远低于一美分,如果使用订阅则是免费的。
## 🚀 用法
```
syay
# normal yay usage; the scanner gates AUR builds
aurscan [...] # standalone scan (fetches the AUR snapshot in memory)
aurscan ./builddir # scan a local build directory
aurscan --update-check # audit pending AUR updates without installing anything
aurscan --gen-file # write pending AUR updates to ./aurscan.paclist
aurscan --scan-file # scan packages listed in ./aurscan.paclist
```
**离线管理员工作流。** 如果你维护的机器没有配置 LLM 后端,请在那里安装 aurscan 并:
```
aurscan --gen-file
```
这会使用来自 `yay -Qua` 的结构化待处理 AUR 更新列表覆盖 `./aurscan.paclist`。将该单个文件复制到你的扫描机器上并运行:
```
aurscan --scan-file
```
scan 命令要求当前目录中存在 `aurscan.paclist`,验证它是否为 aurscan 生成的文件,并通过与 `--update-check` 相同的递归 AUR 扫描器扫描所列出的包。
当包被标记时:
- **中止** —— 默认操作;按下 Enter 始终是安全的。
- **报告** —— 生成 `/tmp/aurscan-report-.txt` 草稿,并提议打开你的邮件客户端发送至 [`aurscan@manticore-projects.com`](mailto:aurscan@manticore-projects.com),报告会在进行任何上游披露之前被汇总和处理,同时提醒你提交 AUR 删除请求。**绝不会自动发送。**
- **继续** —— 需要输入 `INSTALL`,防止下意识操作导致漏网之鱼。
**退出代码:** `0` 干净/批准 · `1` 可疑-中止 · `2` 恶意-中止 · `3` 操作错误。
## 🧩 自定义检测
**添加你自己的审核员指南。** 将 Markdown 文件放在 `~/.config/aurscan/instructions.md`(或将 `AURSCAN_INSTRUCTIONS` 指向任何路径)。其内容会*追加*到内置指令中——它可以使审核员更加敏锐,但绝不会削弱核心规则或 prompt 注入防护。在 [`packaging/instructions.example.md`](packaging/instructions.example.md) 中提供了一个可直接复制的示例;它告诉审核员要更加严格地对待低人气包、最近的维护者变更以及没有明显技术原因的变更。
**静态规则优先运行。** 一个确定性目录(改编自 [KiefStudioMA/ks-aur-scanner](https://github.com/KiefStudioMA/ks-aur-scanner),GPL-3.0,代码保持兼容)可离线且免费地匹配已知模式——`curl|bash`、反向 shell、凭据/浏览器配置文件访问、systemd 持久化、`npm install atomic-lockfile` / `bun install js-digest` 攻击活动特征、eBPF-rootkit 构件等等。每一次命中都会作为先验上下文反馈给模型。无需调用模型即可单独运行它们:
```
aurscan --rules-only # or set AURSCAN_RULES_ONLY=1
```
## 🔌 脚本集成
对于 CI 或自定义钩子,`--score` 会扫描单个目标并将结果映射到退出代码:成功时为 **0-100 的信任分数**(分数越高 = 越安全;MALICIOUS 0-33,SUSPICIOUS 34-66,OK 67-100),如果扫描未能完成则为 **255**。分数也会打印到 stdout;人类可读的判定结果会输出到 stderr,因此捕获它非常清晰:
```
aurscan --score ./PKGBUILD # exit code = trust score
aurscan --score ./builddir # a directory works too
makepkg --printsrcinfo >/dev/null; cat PKGBUILD | aurscan --score - # from stdin
score=$(aurscan --score - < PKGBUILD) # capture just the number
[ "$score" -ge 67 ] || echo "risky (score $score)"
```
注意:退出代码 `0` 表示信任分数为 0(最危险),因此请测试数值本身,而不是依赖 `&&`/`||`。
## 🐞 调试 LLM 通信
如果扫描返回“格式错误的 JSON”,或者你想确切查看发送给模型以及从模型返回的内容,请添加 `--debug`(在命令行的任何位置)。它会向 stderr 追踪所选的后端、完整的请求 payload、原始响应以及解析失败的任何原因:
```
aurscan --debug rocketchat-desktop
aurscan --debug --score ./PKGBUILD
```
## 💸 Token 与成本报告
每次扫描都会打印出每个包的使用情况和会话总计:
```
↳ tokens: 12,431 in / 214 out · $0.0413
scanner usage: 1 call(s) · tokens: 12,431 in / 214 out · $0.0413
```
| 后端 | Token | 成本 |
|---|---|---|
| Claude Code CLI | 确切 | 确切 (`total_cost_usd`) |
| Codex CLI | 估算 (`~`) | `cost n/a` |
| API key | 确切 | 根据价格表计算 |
| 自定义命令 | 估算 (`~`) | `cost n/a` |
覆盖 API 价格表(每百万 token 的 USD 价格),让你永远不必依赖过时的内置价格:`AURSCAN_PRICE_IN` / `AURSCAN_PRICE_OUT`。
## ⚙️ 配置
| 变量 | 默认值 | 含义 |
|---|---|---|
| `AURSCAN_BACKEND` | auto | `claude` · `codex` · `api` · `openai` · `/path/to/cmd` |
| `AURSCAN_MODEL` | `claude-sonnet-4-6` | API 后端的模型 ID |
| `AURSCAN_CODEX_MODEL` | Codex 默认值 | 传递给 `codex exec` 的模型 ID |
| `AURSCAN_MAX_PKGS` | `25` | AUR 依赖扫描的递归上限 |
| `AURSCAN_PRICE_IN` / `AURSCAN_PRICE_OUT` | 内置 | 每百万 token 的 USD 价格 |
| `AURSCAN_OPENAI_URL` / `_FALLBACK` | — | 用于本地模型的兼容 OpenAI 的 endpoint |
| `AURSCAN_OPENAI_MODEL` | `default-model` | 发送到本地 endpoint 的模型名称 |
| `AURSCAN_TIMEOUT` | `180` | 每个请求的预算(以**秒**为单位);对于速度慢的仅有 CPU 的本地模型请提高该值 |
| `AURSCAN_INSTRUCTIONS` | — | 额外审核员指令的路径(追加) |
| `AURSCAN_RULES_ONLY` | — | `1` = 仅使用静态规则,从不调用模型 |
| `NO_COLOR` | — | 禁用彩色输出 |
## 🔒 安全保障
- **安全失败。** 后端错误、超时、抓取失败或无法解析的输出 ⇒ **SUSPICIOUS**,构建被阻止。扫描器可能会失败,但绝不会暴露漏洞 (fail *open*)。
- **Prompt 注入防护。** 包文件作为**不受信任的数据**发送,与受信任的指令分开;prompt 将嵌入的“此包是安全的 / 忽略之前的指令”文本视为*恶意*的证据。解析仅信任 JSON 契约——已通过测试覆盖。
- **无执行,无磁盘写入。** AUR 快照在**内存中**解析;可疑包中的任何内容都不会被写入磁盘或运行。
- **有界上下文。** 跳过大于 64 KB 的二进制文件和文件;总上下文限制在 240 KB。
## 🗂️ 项目结构
```
cmd/aurscan/ entrypoint + argument dispatch
internal/scan/ prompt, backend calls, verdict parsing, usage/pricing
internal/aur/ AUR RPC, in-memory snapshot fetch, recursive dep scan
internal/rules/ deterministic static-rule catalog (offline pre-filter)
internal/pipeline/ orchestrates rules -> reputation -> LLM, rules-only fallback
internal/config/ user config + extra-instructions loader
internal/ui/ colours, verdict printing, interactive gate, report
internal/yay/ syay wrapper + edit-hook gate
packaging/PKGBUILD publish aurscan to the AUR
testdata/ sanitised firefox-patch-bin fixture (structure only)
```
## ⚠️ 局限性
- 是启发式的,而不是验证器——尽可能在干净的 chroot 中构建。
- `npm` / `bun` / `pip` / `go` / `curl` 有时是合法的(例如从源代码构建的 Electron 应用);预计偶尔会出现**误报**——这是更安全的出错方向。
- 该包装器为每次 AUR 构建启用 yay 的编辑提示;这是查看每个脚本的代价。传递你自己的 `--editor`,aurscan 会先进行扫描,然后再链接到它。
## 🙏 致谢
- 静态规则目录改编自 [KiefStudioMA/ks-aur-scanner](https://github.com/KiefStudioMA/ks-aur-scanner) (GPL-3.0)。
- 本地 LLM 后端推广自 [@alexzk1 的连接器](https://github.com/manticore-projects/aurscan/issues/1)。
## 📄 许可证
[Apache-2.0](LICENSE) © Manticore Projects Co., Ltd.标签:AI风险缓解, Arch Linux, AUR, DLL 劫持, EVTX分析, Go, Ruby工具, 云安全监控, 大语言模型, 恶意软件扫描, 日志审计, 网络信息收集, 镜像安全, 静态分析