forked from Zakaria/hermes-agent
Hermes-agent
This commit is contained in:
+173
@@ -0,0 +1,173 @@
|
||||
---
|
||||
title: "1Password — 设置并使用 1Password CLI (op)"
|
||||
sidebar_label: "1Password"
|
||||
description: "设置并使用 1Password CLI (op)"
|
||||
---
|
||||
|
||||
{/* This page is auto-generated from the skill's SKILL.md by website/scripts/generate-skill-docs.py. Edit the source SKILL.md, not this page. */}
|
||||
|
||||
# 1Password
|
||||
|
||||
设置并使用 1Password CLI (op)。适用于安装 CLI、启用桌面应用集成、登录,以及为命令读取/注入密钥的场景。
|
||||
|
||||
## Skill 元数据
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
| 来源 | 可选 — 通过 `hermes skills install official/security/1password` 安装 |
|
||||
| 路径 | `optional-skills/security/1password` |
|
||||
| 版本 | `1.0.0` |
|
||||
| 作者 | arceus77-7,由 Hermes Agent 增强 |
|
||||
| 许可证 | MIT |
|
||||
| 平台 | linux, macos, windows |
|
||||
| 标签 | `security`, `secrets`, `1password`, `op`, `cli` |
|
||||
|
||||
## 参考:完整 SKILL.md
|
||||
|
||||
:::info
|
||||
以下是 Hermes 在触发此 skill 时加载的完整 skill 定义。这是 skill 激活时 agent 所看到的指令内容。
|
||||
:::
|
||||
|
||||
# 1Password CLI
|
||||
|
||||
当用户希望通过 1Password 管理密钥,而非使用明文环境变量或文件时,使用此 skill。
|
||||
|
||||
## 前置要求
|
||||
|
||||
- 1Password 账户
|
||||
- 已安装 1Password CLI(`op`)
|
||||
- 以下之一:桌面应用集成、服务账户令牌(`OP_SERVICE_ACCOUNT_TOKEN`)或 Connect 服务器
|
||||
- `tmux` 可用,用于在 Hermes 终端调用期间保持稳定的已认证会话(仅限桌面应用流程)
|
||||
|
||||
## 使用场景
|
||||
|
||||
- 安装或配置 1Password CLI
|
||||
- 使用 `op signin` 登录
|
||||
- 读取形如 `op://Vault/Item/field` 的密钥引用
|
||||
- 使用 `op inject` 将密钥注入配置/模板
|
||||
- 通过 `op run` 以密钥环境变量运行命令
|
||||
|
||||
## 认证方式
|
||||
|
||||
### 服务账户(推荐用于 Hermes)
|
||||
|
||||
在 `~/.hermes/.env` 中设置 `OP_SERVICE_ACCOUNT_TOKEN`(skill 首次加载时会提示输入)。
|
||||
无需桌面应用。支持 `op read`、`op inject`、`op run`。
|
||||
|
||||
```bash
|
||||
export OP_SERVICE_ACCOUNT_TOKEN="your-token-here"
|
||||
op whoami # verify — should show Type: SERVICE_ACCOUNT
|
||||
```
|
||||
|
||||
### 桌面应用集成(交互式)
|
||||
|
||||
1. 在 1Password 桌面应用中启用:设置 → 开发者 → 与 1Password CLI 集成
|
||||
2. 确保应用已解锁
|
||||
3. 运行 `op signin` 并通过生物识别提示授权
|
||||
|
||||
### Connect 服务器(自托管)
|
||||
|
||||
```bash
|
||||
export OP_CONNECT_HOST="http://localhost:8080"
|
||||
export OP_CONNECT_TOKEN="your-connect-token"
|
||||
```
|
||||
|
||||
## 设置步骤
|
||||
|
||||
1. 安装 CLI:
|
||||
|
||||
```bash
|
||||
# macOS
|
||||
brew install 1password-cli
|
||||
|
||||
# Linux (official package/install docs)
|
||||
# See references/get-started.md for distro-specific links.
|
||||
|
||||
# Windows (winget)
|
||||
winget install AgileBits.1Password.CLI
|
||||
```
|
||||
|
||||
2. 验证:
|
||||
|
||||
```bash
|
||||
op --version
|
||||
```
|
||||
|
||||
3. 选择上述认证方式之一并进行配置。
|
||||
|
||||
## Hermes 执行模式(桌面应用流程)
|
||||
|
||||
Hermes 终端命令默认为非交互式,且在多次调用之间可能丢失认证上下文。
|
||||
若要在桌面应用集成下可靠使用 `op`,请在专用 tmux 会话中执行登录和密钥操作。
|
||||
|
||||
注意:使用 `OP_SERVICE_ACCOUNT_TOKEN` 时**无需**此操作 — 令牌会在终端调用之间自动持久化。
|
||||
|
||||
```bash
|
||||
SOCKET_DIR="${TMPDIR:-/tmp}/hermes-tmux-sockets"
|
||||
mkdir -p "$SOCKET_DIR"
|
||||
SOCKET="$SOCKET_DIR/hermes-op.sock"
|
||||
SESSION="op-auth-$(date +%Y%m%d-%H%M%S)"
|
||||
|
||||
tmux -S "$SOCKET" new -d -s "$SESSION" -n shell
|
||||
|
||||
# Sign in (approve in desktop app when prompted)
|
||||
tmux -S "$SOCKET" send-keys -t "$SESSION":0.0 -- "eval \"\$(op signin --account my.1password.com)\"" Enter
|
||||
|
||||
# Verify auth
|
||||
tmux -S "$SOCKET" send-keys -t "$SESSION":0.0 -- "op whoami" Enter
|
||||
|
||||
# Example read
|
||||
tmux -S "$SOCKET" send-keys -t "$SESSION":0.0 -- "op read 'op://Private/Npmjs/one-time password?attribute=otp'" Enter
|
||||
|
||||
# Capture output when needed
|
||||
tmux -S "$SOCKET" capture-pane -p -J -t "$SESSION":0.0 -S -200
|
||||
|
||||
# Cleanup
|
||||
tmux -S "$SOCKET" kill-session -t "$SESSION"
|
||||
```
|
||||
|
||||
## 常用操作
|
||||
|
||||
### 读取密钥
|
||||
|
||||
```bash
|
||||
op read "op://app-prod/db/password"
|
||||
```
|
||||
|
||||
### 获取 OTP
|
||||
|
||||
```bash
|
||||
op read "op://app-prod/npm/one-time password?attribute=otp"
|
||||
```
|
||||
|
||||
### 注入模板
|
||||
|
||||
```bash
|
||||
echo "db_password: {{ op://app-prod/db/password }}" | op inject
|
||||
```
|
||||
|
||||
### 以密钥环境变量运行命令
|
||||
|
||||
```bash
|
||||
export DB_PASSWORD="op://app-prod/db/password"
|
||||
op run -- sh -c '[ -n "$DB_PASSWORD" ] && echo "DB_PASSWORD is set" || echo "DB_PASSWORD missing"'
|
||||
```
|
||||
|
||||
## 使用限制
|
||||
|
||||
- 除非用户明确请求该值,否则不得将原始密钥打印给用户。
|
||||
- 优先使用 `op run` / `op inject`,而非将密钥写入文件。
|
||||
- 若命令报错"account is not signed in",请在同一 tmux 会话中重新运行 `op signin`。
|
||||
- 若桌面应用集成不可用(无头环境/CI),请使用服务账户令牌流程。
|
||||
|
||||
## CI / 无头环境说明
|
||||
|
||||
非交互式使用时,请通过 `OP_SERVICE_ACCOUNT_TOKEN` 进行认证,避免使用交互式 `op signin`。
|
||||
服务账户需要 CLI v2.18.0+。
|
||||
|
||||
## 参考资料
|
||||
|
||||
- `references/get-started.md`
|
||||
- `references/cli-examples.md`
|
||||
- https://developer.1password.com/docs/cli/
|
||||
- https://developer.1password.com/docs/service-accounts/
|
||||
+421
@@ -0,0 +1,421 @@
|
||||
---
|
||||
title: "Oss Forensics — GitHub 仓库的供应链调查、证据恢复与取证分析"
|
||||
sidebar_label: "Oss Forensics"
|
||||
description: "GitHub 仓库的供应链调查、证据恢复与取证分析"
|
||||
---
|
||||
|
||||
{/* This page is auto-generated from the skill's SKILL.md by website/scripts/generate-skill-docs.py. Edit the source SKILL.md, not this page. */}
|
||||
|
||||
# Oss Forensics
|
||||
|
||||
GitHub 仓库的供应链调查、证据恢复与取证分析。
|
||||
涵盖已删除提交的恢复、强制推送检测、IOC 提取、多源证据收集、
|
||||
假设形成与验证,以及结构化取证报告生成。
|
||||
灵感来源于 RAPTOR 的 1800+ 行 OSS Forensics 系统。
|
||||
|
||||
## Skill 元数据
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
| 来源 | 可选 — 通过 `hermes skills install official/security/oss-forensics` 安装 |
|
||||
| 路径 | `optional-skills/security/oss-forensics` |
|
||||
| 平台 | linux, macos, windows |
|
||||
|
||||
## 参考:完整 SKILL.md
|
||||
|
||||
:::info
|
||||
以下是 Hermes 在触发此 skill 时加载的完整 skill 定义。这是 agent 在 skill 激活时所看到的指令内容。
|
||||
:::
|
||||
|
||||
# OSS 安全取证 Skill
|
||||
|
||||
一个用于研究开源供应链攻击的 7 阶段多 agent 调查框架。
|
||||
改编自 RAPTOR 的取证系统。涵盖 GitHub Archive、Wayback Machine、GitHub API、
|
||||
本地 git 分析、IOC 提取、基于证据的假设形成与验证,以及最终取证报告生成。
|
||||
|
||||
---
|
||||
|
||||
## ⚠️ 反幻觉(Anti-Hallucination)防护规则
|
||||
|
||||
在每个调查步骤前必须阅读这些规则。违反这些规则将使报告失效。
|
||||
|
||||
1. **证据优先原则**:任何报告、假设或摘要中的每一项声明都必须引用至少一个证据 ID(`EV-XXXX`)。禁止无引用的断言。
|
||||
2. **职责边界**:每个子 agent(调查员)只有一个数据源,不得混用。GH Archive 调查员不查询 GitHub API,反之亦然。职责边界是硬性规定。
|
||||
3. **事实与假设分离**:所有未经验证的推断必须标注 `[HYPOTHESIS]`。只有经原始来源验证的陈述才可作为事实表述。
|
||||
4. **禁止捏造证据**:假设验证器必须机械地检查每个被引用的证据 ID 在证据库中确实存在,然后才能接受假设。
|
||||
5. **反驳需有证据**:驳斥一个假设必须提供具体的、有证据支撑的反驳论点。"未找到证据"不足以推翻假设——这只能使假设变为不确定状态。
|
||||
6. **SHA/URL 双重验证**:任何作为证据引用的提交 SHA、URL 或外部标识符,必须在被标记为已验证之前从至少两个来源独立确认。
|
||||
7. **可疑代码规则**:绝不在本地运行被调查仓库中发现的代码。仅进行静态分析,或在沙箱环境中使用 `execute_code`。
|
||||
8. **密钥脱敏**:调查过程中发现的任何 API 密钥、token 或凭据必须在最终报告中脱敏处理,仅在内部日志中记录。
|
||||
|
||||
---
|
||||
|
||||
## 示例场景
|
||||
|
||||
- **场景 A:依赖混淆**:恶意包 `internal-lib-v2` 以更高版本号上传至 NPM,高于内部版本。调查员需追踪该包首次出现的时间,以及目标仓库中是否有 PushEvent 将 `package.json` 更新为该版本。
|
||||
- **场景 B:维护者账户接管**:一名长期贡献者的账户被用于推送带有后门的 `.github/workflows/build.yml`。调查员在该用户长期不活跃或来自新 IP/位置(如可通过 BigQuery 检测)之后,查找其 PushEvent。
|
||||
- **场景 C:强制推送隐藏**:开发者意外提交了生产环境密钥,随后强制推送以"修复"。调查员使用 `git fsck` 和 GH Archive 恢复原始提交 SHA,并验证泄露内容。
|
||||
|
||||
---
|
||||
|
||||
> **路径约定**:在本 skill 中,`SKILL_DIR` 指本 skill 安装目录的根目录(包含此 `SKILL.md` 的文件夹)。加载 skill 时,请将 `SKILL_DIR` 解析为实际路径——例如 `~/.hermes/skills/security/oss-forensics/` 或对应的 `optional-skills/` 路径。所有脚本和模板引用均相对于该目录。
|
||||
|
||||
## 阶段 0:初始化
|
||||
|
||||
1. 创建调查工作目录:
|
||||
```bash
|
||||
mkdir investigation_$(echo "REPO_NAME" | tr '/' '_')
|
||||
cd investigation_$(echo "REPO_NAME" | tr '/' '_')
|
||||
```
|
||||
2. 初始化证据库:
|
||||
```bash
|
||||
python3 SKILL_DIR/scripts/evidence-store.py --store evidence.json list
|
||||
```
|
||||
3. 复制取证报告模板:
|
||||
```bash
|
||||
cp SKILL_DIR/templates/forensic-report.md ./investigation-report.md
|
||||
```
|
||||
4. 创建 `iocs.md` 文件,用于追踪发现的入侵指标(Indicators of Compromise,IOC)。
|
||||
5. 记录调查开始时间、目标仓库及调查目标说明。
|
||||
|
||||
---
|
||||
|
||||
## 阶段 1:Prompt 解析与 IOC 提取
|
||||
|
||||
**目标**:从用户请求中提取所有结构化调查目标。
|
||||
|
||||
**操作**:
|
||||
- 解析用户 prompt(提示词),提取:
|
||||
- 目标仓库(`owner/repo`)
|
||||
- 目标参与者(GitHub 用户名、电子邮件地址)
|
||||
- 关注的时间窗口(提交日期范围、PR 时间戳)
|
||||
- 提供的入侵指标:提交 SHA、文件路径、包名、IP 地址、域名、API 密钥/token、恶意 URL
|
||||
- 任何关联的供应商安全报告或博客文章
|
||||
|
||||
**工具**:仅推理,或对大段文本使用 `execute_code` 进行正则提取。
|
||||
|
||||
**输出**:将提取的 IOC 填入 `iocs.md`。每个 IOC 必须包含:
|
||||
- 类型(从以下选择:COMMIT_SHA、FILE_PATH、API_KEY、SECRET、IP_ADDRESS、DOMAIN、PACKAGE_NAME、ACTOR_USERNAME、MALICIOUS_URL、OTHER)
|
||||
- 值
|
||||
- 来源(用户提供、推断得出)
|
||||
|
||||
**参考**:IOC 分类法见 [evidence-types.md](https://github.com/NousResearch/hermes-agent/blob/main/optional-skills/security/oss-forensics/references/evidence-types.md)。
|
||||
|
||||
---
|
||||
|
||||
## 阶段 2:并行证据收集
|
||||
|
||||
使用 `delegate_task`(批量模式,最多 3 个并发)派生最多 5 个专业调查员子 agent。每个调查员只有**一个数据源**,不得混用。
|
||||
|
||||
> **编排器注意**:在每个委托任务的 `context` 字段中传入阶段 1 的 IOC 列表和调查时间窗口。
|
||||
|
||||
---
|
||||
|
||||
### 调查员 1:本地 Git 调查员
|
||||
|
||||
**职责边界**:仅查询**本地 Git 仓库**,不调用任何外部 API。
|
||||
|
||||
**操作**:
|
||||
```bash
|
||||
# 克隆仓库
|
||||
git clone https://github.com/OWNER/REPO.git target_repo && cd target_repo
|
||||
|
||||
# 完整提交日志(含统计信息)
|
||||
git log --all --full-history --stat --format="%H|%ae|%an|%ai|%s" > ../git_log.txt
|
||||
|
||||
# 检测强制推送证据(孤立/悬空提交)
|
||||
git fsck --lost-found --unreachable 2>&1 | grep commit > ../dangling_commits.txt
|
||||
|
||||
# 检查 reflog 中的历史重写
|
||||
git reflog --all > ../reflog.txt
|
||||
|
||||
# 列出所有分支,包括已删除的远程引用
|
||||
git branch -a -v > ../branches.txt
|
||||
|
||||
# 查找可疑的大型二进制文件添加
|
||||
git log --all --diff-filter=A --name-only --format="%H %ai" -- "*.so" "*.dll" "*.exe" "*.bin" > ../binary_additions.txt
|
||||
|
||||
# 检查 GPG 签名异常
|
||||
git log --show-signature --format="%H %ai %aN" > ../signature_check.txt 2>&1
|
||||
```
|
||||
|
||||
**需收集的证据**(通过 `python3 SKILL_DIR/scripts/evidence-store.py add` 添加):
|
||||
- 每个悬空提交 SHA → 类型:`git`
|
||||
- 强制推送证据(reflog 显示历史重写)→ 类型:`git`
|
||||
- 已验证贡献者的未签名提交 → 类型:`git`
|
||||
- 可疑二进制文件添加 → 类型:`git`
|
||||
|
||||
**参考**:访问强制推送提交的方法见 [recovery-techniques.md](https://github.com/NousResearch/hermes-agent/blob/main/optional-skills/security/oss-forensics/references/recovery-techniques.md)。
|
||||
|
||||
---
|
||||
|
||||
### 调查员 2:GitHub API 调查员
|
||||
|
||||
**职责边界**:仅查询 **GitHub REST API**,不在本地运行 git 命令。
|
||||
|
||||
**操作**:
|
||||
```bash
|
||||
# 提交(分页)
|
||||
curl -s "https://api.github.com/repos/OWNER/REPO/commits?per_page=100" > api_commits.json
|
||||
|
||||
# Pull Request(含已关闭/已删除)
|
||||
curl -s "https://api.github.com/repos/OWNER/REPO/pulls?state=all&per_page=100" > api_prs.json
|
||||
|
||||
# Issues
|
||||
curl -s "https://api.github.com/repos/OWNER/REPO/issues?state=all&per_page=100" > api_issues.json
|
||||
|
||||
# 贡献者及协作者变更
|
||||
curl -s "https://api.github.com/repos/OWNER/REPO/contributors" > api_contributors.json
|
||||
|
||||
# 仓库事件(最近 300 条)
|
||||
curl -s "https://api.github.com/repos/OWNER/REPO/events?per_page=100" > api_events.json
|
||||
|
||||
# 查看特定可疑提交 SHA 的详情
|
||||
curl -s "https://api.github.com/repos/OWNER/REPO/git/commits/SHA" > commit_detail.json
|
||||
|
||||
# Releases
|
||||
curl -s "https://api.github.com/repos/OWNER/REPO/releases?per_page=100" > api_releases.json
|
||||
|
||||
# 检查特定提交是否存在(强制推送的提交在 commits/ 可能返回 404,但在 git/commits/ 可能成功)
|
||||
curl -s "https://api.github.com/repos/OWNER/REPO/commits/SHA" | jq .sha
|
||||
```
|
||||
|
||||
**交叉比对目标**(将差异标记为证据):
|
||||
- PR 存在于归档中但 API 中缺失 → 删除证据
|
||||
- 贡献者出现在归档事件中但不在贡献者列表中 → 权限撤销证据
|
||||
- 提交出现在归档 PushEvent 中但不在 API 提交列表中 → 强制推送/删除证据
|
||||
|
||||
**参考**:GH 事件类型见 [evidence-types.md](https://github.com/NousResearch/hermes-agent/blob/main/optional-skills/security/oss-forensics/references/evidence-types.md)。
|
||||
|
||||
---
|
||||
|
||||
### 调查员 3:Wayback Machine 调查员
|
||||
|
||||
**职责边界**:仅查询 **Wayback Machine CDX API**,不使用 GitHub API。
|
||||
|
||||
**目标**:恢复已删除的 GitHub 页面(README、issues、PR、releases、wiki 页面)。
|
||||
|
||||
**操作**:
|
||||
```bash
|
||||
# 搜索仓库主页的归档快照
|
||||
curl -s "https://web.archive.org/cdx/search/cdx?url=github.com/OWNER/REPO&output=json&limit=100&from=YYYYMMDD&to=YYYYMMDD" > wayback_main.json
|
||||
|
||||
# 搜索特定已删除 issue
|
||||
curl -s "https://web.archive.org/cdx/search/cdx?url=github.com/OWNER/REPO/issues/NUM&output=json&limit=50" > wayback_issue_NUM.json
|
||||
|
||||
# 搜索特定已删除 PR
|
||||
curl -s "https://web.archive.org/cdx/search/cdx?url=github.com/OWNER/REPO/pull/NUM&output=json&limit=50" > wayback_pr_NUM.json
|
||||
|
||||
# 获取页面的最佳快照
|
||||
# 使用 Wayback Machine URL:https://web.archive.org/web/TIMESTAMP/ORIGINAL_URL
|
||||
# 示例:https://web.archive.org/web/20240101000000*/github.com/OWNER/REPO
|
||||
|
||||
# 高级:搜索已删除的 releases/tags
|
||||
curl -s "https://web.archive.org/cdx/search/cdx?url=github.com/OWNER/REPO/releases/tag/*&output=json" > wayback_tags.json
|
||||
|
||||
# 高级:搜索历史 wiki 变更
|
||||
curl -s "https://web.archive.org/cdx/search/cdx?url=github.com/OWNER/REPO/wiki/*&output=json" > wayback_wiki.json
|
||||
```
|
||||
|
||||
**需收集的证据**:
|
||||
- 已删除 issue/PR 的归档快照及其内容
|
||||
- 显示变更的历史 README 版本
|
||||
- 存在于归档中但在当前 GitHub 状态中缺失的内容证据
|
||||
|
||||
**参考**:CDX API 参数见 [github-archive-guide.md](https://github.com/NousResearch/hermes-agent/blob/main/optional-skills/security/oss-forensics/references/github-archive-guide.md)。
|
||||
|
||||
---
|
||||
|
||||
### 调查员 4:GH Archive / BigQuery 调查员
|
||||
|
||||
**职责边界**:仅通过 **BigQuery** 查询 **GitHub Archive**。这是所有公开 GitHub 事件的防篡改记录。
|
||||
|
||||
> **前提条件**:需要具有 BigQuery 访问权限的 Google Cloud 凭据(`gcloud auth application-default login`)。如不可用,跳过此调查员并在报告中注明。
|
||||
|
||||
**成本优化规则**(强制执行):
|
||||
1. 每次查询前必须先运行 `--dry_run` 以估算成本。
|
||||
2. 使用 `_TABLE_SUFFIX` 按日期范围过滤,最小化扫描数据量。
|
||||
3. 只 SELECT 所需列。
|
||||
4. 除非进行聚合,否则添加 LIMIT。
|
||||
|
||||
```bash
|
||||
# 模板:安全的 BigQuery 查询,用于查询 OWNER/REPO 的 PushEvent
|
||||
bq query --use_legacy_sql=false --dry_run "
|
||||
SELECT created_at, actor.login, payload.commits, payload.before, payload.head,
|
||||
payload.size, payload.distinct_size
|
||||
FROM \`githubarchive.month.*\`
|
||||
WHERE _TABLE_SUFFIX BETWEEN 'YYYYMM' AND 'YYYYMM'
|
||||
AND type = 'PushEvent'
|
||||
AND repo.name = 'OWNER/REPO'
|
||||
LIMIT 1000
|
||||
"
|
||||
# 如果成本可接受,去掉 --dry_run 重新运行
|
||||
|
||||
# 检测强制推送:distinct_size 为零的 PushEvent 表示提交被强制擦除
|
||||
# payload.distinct_size = 0 AND payload.size > 0 → 强制推送指标
|
||||
|
||||
# 检查已删除分支事件
|
||||
bq query --use_legacy_sql=false "
|
||||
SELECT created_at, actor.login, payload.ref, payload.ref_type
|
||||
FROM \`githubarchive.month.*\`
|
||||
WHERE _TABLE_SUFFIX BETWEEN 'YYYYMM' AND 'YYYYMM'
|
||||
AND type = 'DeleteEvent'
|
||||
AND repo.name = 'OWNER/REPO'
|
||||
LIMIT 200
|
||||
"
|
||||
```
|
||||
|
||||
**需收集的证据**:
|
||||
- 强制推送事件(payload.size > 0,payload.distinct_size = 0)
|
||||
- 分支/标签的 DeleteEvent
|
||||
- 可疑 CI/CD 自动化的 WorkflowRunEvent
|
||||
- 在 git 日志出现"空白"之前的 PushEvent(历史重写证据)
|
||||
|
||||
**参考**:所有 12 种事件类型及查询模式见 [github-archive-guide.md](https://github.com/NousResearch/hermes-agent/blob/main/optional-skills/security/oss-forensics/references/github-archive-guide.md)。
|
||||
|
||||
---
|
||||
|
||||
### 调查员 5:IOC 富化调查员
|
||||
|
||||
**职责边界**:仅使用**被动公开来源**对阶段 1 中的**现有 IOC** 进行富化。不执行目标仓库中的任何代码。
|
||||
|
||||
**操作**:
|
||||
- 对每个提交 SHA:尝试通过直接 GitHub URL(`github.com/OWNER/REPO/commit/SHA.patch`)恢复
|
||||
- 对每个域名/IP:检查被动 DNS、WHOIS 记录(通过 `web_extract` 访问公开 WHOIS 服务)
|
||||
- 对每个包名:检查 npm/PyPI 中是否有匹配的恶意包报告
|
||||
- 对每个 actor 用户名:检查 GitHub 个人资料、贡献历史、账户注册时间
|
||||
- 使用 3 种方法恢复强制推送的提交(见 [recovery-techniques.md](https://github.com/NousResearch/hermes-agent/blob/main/optional-skills/security/oss-forensics/references/recovery-techniques.md))
|
||||
|
||||
---
|
||||
|
||||
## 阶段 3:证据整合
|
||||
|
||||
所有调查员完成后:
|
||||
|
||||
1. 运行 `python3 SKILL_DIR/scripts/evidence-store.py --store evidence.json list` 查看所有已收集证据。
|
||||
2. 对每条证据,验证 `content_sha256` 哈希值与原始来源一致。
|
||||
3. 按以下维度对证据分组:
|
||||
- **时间线**:将所有带时间戳的证据按时间顺序排列
|
||||
- **参与者**:按 GitHub 用户名或电子邮件分组
|
||||
- **IOC**:将证据与其关联的 IOC 链接
|
||||
4. 识别**差异**:存在于一个来源但在另一个来源中缺失的条目(关键删除指标)。
|
||||
5. 将证据标记为 `[VERIFIED]`(已从 2 个以上独立来源确认)或 `[UNVERIFIED]`(仅单一来源)。
|
||||
|
||||
---
|
||||
|
||||
## 阶段 4:假设形成
|
||||
|
||||
一个假设必须:
|
||||
- 陈述具体声明(例如:"参与者 X 于某日期对 BRANCH 进行强制推送以擦除提交 SHA")
|
||||
- 引用至少 2 个支持它的证据 ID(`EV-XXXX`、`EV-YYYY`)
|
||||
- 指明哪些证据可以推翻它
|
||||
- 在验证之前标注 `[HYPOTHESIS]`
|
||||
|
||||
**常见假设模板**(见 [investigation-templates.md](https://github.com/NousResearch/hermes-agent/blob/main/optional-skills/security/oss-forensics/references/investigation-templates.md)):
|
||||
- 维护者账户被攻陷:合法账户在被接管后用于注入恶意代码
|
||||
- 依赖混淆:包名抢注以拦截安装
|
||||
- CI/CD 注入:恶意 workflow 变更以在构建期间运行代码
|
||||
- 仿冒命名(Typosquatting):针对拼写错误者的高度相似包名
|
||||
- 凭据泄露:token/密钥意外提交后强制推送以擦除
|
||||
|
||||
对每个假设,派生一个 `delegate_task` 子 agent,在确认之前尝试寻找反驳证据。
|
||||
|
||||
---
|
||||
|
||||
## 阶段 5:假设验证
|
||||
|
||||
验证器子 agent 必须机械地检查:
|
||||
|
||||
1. 对每个假设,提取所有被引用的证据 ID。
|
||||
2. 验证每个 ID 在 `evidence.json` 中存在(如有任何 ID 缺失则硬性失败 → 假设因可能捏造而被拒绝)。
|
||||
3. 验证每条 `[VERIFIED]` 证据已从 2 个以上来源确认。
|
||||
4. 检查逻辑一致性:证据所描绘的时间线是否支持该假设?
|
||||
5. 检查替代解释:相同的证据模式是否可能源于良性原因?
|
||||
|
||||
**输出**:
|
||||
- `VALIDATED`:所有证据已引用、已验证、逻辑一致,且不存在合理的替代解释。
|
||||
- `INCONCLUSIVE`:证据支持假设,但存在替代解释或证据不足。
|
||||
- `REJECTED`:证据 ID 缺失、将未验证证据作为事实引用、检测到逻辑不一致。
|
||||
|
||||
被拒绝的假设反馈至阶段 4 进行修正(最多 3 次迭代)。
|
||||
|
||||
---
|
||||
|
||||
## 阶段 6:最终报告生成
|
||||
|
||||
使用 [forensic-report.md](https://github.com/NousResearch/hermes-agent/blob/main/optional-skills/security/oss-forensics/templates/forensic-report.md) 中的模板填写 `investigation-report.md`。
|
||||
|
||||
**必填章节**:
|
||||
- 执行摘要:一段式结论(已被攻陷 / 干净 / 不确定),含置信度等级
|
||||
- 时间线:所有重要事件的时间顺序重建,含证据引用
|
||||
- 已验证假设:每条假设含状态及支持证据 ID
|
||||
- 证据注册表:所有 `EV-XXXX` 条目的表格,含来源、类型和验证状态
|
||||
- IOC 列表:所有提取和富化的入侵指标
|
||||
- 证据保管链:证据的收集方式、来源及收集时间戳
|
||||
- 建议:如检测到攻陷,提供即时缓解措施;以及监控建议
|
||||
|
||||
**报告规则**:
|
||||
- 每项事实声明必须至少有一个 `[EV-XXXX]` 引用
|
||||
- 执行摘要必须说明置信度等级(高 / 中 / 低)
|
||||
- 所有密钥/凭据必须脱敏为 `[REDACTED]`
|
||||
|
||||
---
|
||||
|
||||
## 阶段 7:完成
|
||||
|
||||
1. 运行最终证据统计:`python3 SKILL_DIR/scripts/evidence-store.py --store evidence.json list`
|
||||
2. 归档完整调查目录。
|
||||
3. 如确认存在攻陷:
|
||||
- 列出即时缓解措施(轮换凭据、固定依赖哈希、通知受影响用户)
|
||||
- 识别受影响的版本/包
|
||||
- 注明披露义务(如为公开包:与包注册表协调)
|
||||
4. 向用户呈现最终 `investigation-report.md`。
|
||||
|
||||
---
|
||||
|
||||
## 道德使用准则
|
||||
|
||||
本 skill 专为**防御性安全调查**而设计——保护开源软件免受供应链攻击。不得用于:
|
||||
|
||||
- **骚扰或跟踪**贡献者或维护者
|
||||
- **人肉搜索(Doxing)**——将 GitHub 活动与真实身份关联用于恶意目的
|
||||
- **竞争情报**——未经授权调查专有或内部仓库
|
||||
- **虚假指控**——在没有经过验证的证据的情况下发布调查结果(参见反幻觉防护规则)
|
||||
|
||||
调查应遵循**最小侵入原则**:仅收集验证或反驳假设所必需的证据。发布结果时,遵循负责任披露实践,在公开披露前与受影响的维护者协调。
|
||||
|
||||
如果调查揭示了真实的攻陷,请遵循协调漏洞披露流程:
|
||||
1. 首先私下通知仓库维护者
|
||||
2. 给予合理的修复时间(通常为 90 天)
|
||||
3. 如涉及已发布包,与包注册表(npm、PyPI 等)协调
|
||||
4. 如适用,提交 CVE
|
||||
|
||||
---
|
||||
|
||||
## API 速率限制
|
||||
|
||||
GitHub REST API 强制执行速率限制,如不加以管理,将中断大型调查。
|
||||
|
||||
**已认证请求**:5,000 次/小时(需要 `GITHUB_TOKEN` 环境变量或 `gh` CLI 认证)
|
||||
**未认证请求**:60 次/小时(不适用于调查)
|
||||
|
||||
**最佳实践**:
|
||||
- 始终进行认证:`export GITHUB_TOKEN=ghp_...` 或使用 `gh` CLI(自动认证)
|
||||
- 使用条件请求(`If-None-Match` / `If-Modified-Since` 请求头),避免对未变更数据消耗配额
|
||||
- 对分页端点,按顺序获取所有页面——不要对同一端点并行请求
|
||||
- 检查 `X-RateLimit-Remaining` 响应头;如低于 100,暂停至 `X-RateLimit-Reset` 时间戳
|
||||
- BigQuery 有其自身配额(免费层每日 10 TiB)——始终先进行 dry-run
|
||||
- Wayback Machine CDX API:无正式速率限制,但请保持礼貌(最多 1-2 次请求/秒)
|
||||
|
||||
如在调查中途遭遇速率限制,将部分结果记录到证据库中,并在报告中注明该限制。
|
||||
|
||||
---
|
||||
|
||||
## 参考资料
|
||||
|
||||
- [github-archive-guide.md](https://github.com/NousResearch/hermes-agent/blob/main/optional-skills/security/oss-forensics/references/github-archive-guide.md) — BigQuery 查询、CDX API、12 种事件类型
|
||||
- [evidence-types.md](https://github.com/NousResearch/hermes-agent/blob/main/optional-skills/security/oss-forensics/references/evidence-types.md) — IOC 分类法、证据来源类型、观察类型
|
||||
- [recovery-techniques.md](https://github.com/NousResearch/hermes-agent/blob/main/optional-skills/security/oss-forensics/references/recovery-techniques.md) — 恢复已删除的提交、PR、issues
|
||||
- [investigation-templates.md](https://github.com/NousResearch/hermes-agent/blob/main/optional-skills/security/oss-forensics/references/investigation-templates.md) — 按攻击类型预置的假设模板
|
||||
- [evidence-store.py](https://github.com/NousResearch/hermes-agent/blob/main/optional-skills/security/oss-forensics/scripts/evidence-store.py) — 用于管理证据 JSON 库的 CLI 工具
|
||||
- [forensic-report.md](https://github.com/NousResearch/hermes-agent/blob/main/optional-skills/security/oss-forensics/templates/forensic-report.md) — 结构化报告模板
|
||||
+208
@@ -0,0 +1,208 @@
|
||||
---
|
||||
title: "Sherlock — 跨 400+ 社交网络的 OSINT 用户名搜索"
|
||||
sidebar_label: "Sherlock"
|
||||
description: "跨 400+ 社交网络的 OSINT 用户名搜索"
|
||||
---
|
||||
|
||||
{/* This page is auto-generated from the skill's SKILL.md by website/scripts/generate-skill-docs.py. Edit the source SKILL.md, not this page. */}
|
||||
|
||||
# Sherlock
|
||||
|
||||
跨 400+ 社交网络的 OSINT(开源情报)用户名搜索。通过用户名追踪社交媒体账号。
|
||||
|
||||
## Skill 元数据
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
| 来源 | 可选 — 使用 `hermes skills install official/security/sherlock` 安装 |
|
||||
| 路径 | `optional-skills/security/sherlock` |
|
||||
| 版本 | `1.0.0` |
|
||||
| 作者 | unmodeled-tyler |
|
||||
| 许可证 | MIT |
|
||||
| 平台 | linux, macos, windows |
|
||||
| 标签 | `osint`, `security`, `username`, `social-media`, `reconnaissance` |
|
||||
|
||||
## 参考:完整 SKILL.md
|
||||
|
||||
:::info
|
||||
以下是 Hermes 在触发此 skill 时加载的完整 skill 定义。这是 skill 激活时 agent 所看到的指令内容。
|
||||
:::
|
||||
|
||||
# Sherlock OSINT 用户名搜索
|
||||
|
||||
使用 [Sherlock Project](https://github.com/sherlock-project/sherlock) 跨 400+ 社交网络通过用户名追踪社交媒体账号。
|
||||
|
||||
## 使用时机
|
||||
|
||||
- 用户要求查找与某用户名关联的账号
|
||||
- 用户想检查用户名在各平台的可用性
|
||||
- 用户正在进行 OSINT 或侦察研究
|
||||
- 用户询问"这个用户名在哪里注册了?"或类似问题
|
||||
|
||||
## 前置要求
|
||||
|
||||
- 已安装 Sherlock CLI:`pipx install sherlock-project` 或 `pip install sherlock-project`
|
||||
- 或者:可用的 Docker(`docker run -it --rm sherlock/sherlock`)
|
||||
- 可访问网络以查询社交平台
|
||||
|
||||
## 操作流程
|
||||
|
||||
### 1. 检查 Sherlock 是否已安装
|
||||
|
||||
**在执行任何操作之前**,先验证 sherlock 是否可用:
|
||||
|
||||
```bash
|
||||
sherlock --version
|
||||
```
|
||||
|
||||
如果命令失败:
|
||||
- 提议安装:`pipx install sherlock-project`(推荐)或 `pip install sherlock-project`
|
||||
- **不要**尝试多种安装方式 — 选择一种并继续
|
||||
- 如果安装失败,告知用户并停止
|
||||
|
||||
### 2. 提取用户名
|
||||
|
||||
**如果用户消息中明确说明了用户名,直接从中提取。**
|
||||
|
||||
以下情况**不应**使用 clarify(澄清):
|
||||
- "Find accounts for nasa" → 用户名为 `nasa`
|
||||
- "Search for johndoe123" → 用户名为 `johndoe123`
|
||||
- "Check if alice exists on social media" → 用户名为 `alice`
|
||||
- "Look up user bob on social networks" → 用户名为 `bob`
|
||||
|
||||
**仅在以下情况使用 clarify:**
|
||||
- 提到了多个可能的用户名("search for alice or bob")
|
||||
- 表述模糊("search for my username" 但未指定)
|
||||
- 完全未提及用户名("do an OSINT search")
|
||||
|
||||
提取时,**原样**保留用户名 — 保留大小写、数字、下划线等。
|
||||
|
||||
### 3. 构建命令
|
||||
|
||||
**默认命令**(除非用户明确要求,否则使用此命令):
|
||||
```bash
|
||||
sherlock --print-found --no-color "<username>" --timeout 90
|
||||
```
|
||||
|
||||
**可选标志**(仅在用户明确要求时添加):
|
||||
- `--nsfw` — 包含 NSFW 站点(仅在用户要求时)
|
||||
- `--tor` — 通过 Tor 路由(仅在用户要求匿名时)
|
||||
|
||||
**不要通过 clarify 询问选项** — 直接运行默认搜索。用户如有需要可自行请求特定选项。
|
||||
|
||||
### 4. 执行搜索
|
||||
|
||||
通过 `terminal` 工具运行。根据网络状况和站点数量,命令通常需要 30-120 秒。
|
||||
|
||||
**终端调用示例:**
|
||||
```json
|
||||
{
|
||||
"command": "sherlock --print-found --no-color \"target_username\"",
|
||||
"timeout": 180
|
||||
}
|
||||
```
|
||||
|
||||
### 5. 解析并呈现结果
|
||||
|
||||
Sherlock 以简单格式输出找到的账号。解析输出并呈现:
|
||||
|
||||
1. **摘要行:** "Found X accounts for username 'Y'"
|
||||
2. **分类链接:** 如有帮助,按平台类型分组(社交、职业、论坛等)
|
||||
3. **输出文件位置:** Sherlock 默认将结果保存至 `<username>.txt`
|
||||
|
||||
**输出解析示例:**
|
||||
```
|
||||
[+] Instagram: https://instagram.com/username
|
||||
[+] Twitter: https://twitter.com/username
|
||||
[+] GitHub: https://github.com/username
|
||||
```
|
||||
|
||||
尽可能以可点击链接的形式呈现结果。
|
||||
|
||||
## 常见问题
|
||||
|
||||
### 未找到结果
|
||||
如果 Sherlock 未找到任何账号,这通常是正确的 — 该用户名可能未在已检查的平台上注册。建议:
|
||||
- 检查拼写或变体
|
||||
- 使用 `?` 通配符尝试相似用户名:`sherlock "user?name"`
|
||||
- 用户可能设置了隐私保护或已删除账号
|
||||
|
||||
### 超时问题
|
||||
部分站点响应缓慢或屏蔽自动请求。使用 `--timeout 120` 增加等待时间,或使用 `--site` 限制搜索范围。
|
||||
|
||||
### Tor 配置
|
||||
`--tor` 需要 Tor 守护进程运行。如果用户需要匿名但 Tor 不可用,建议:
|
||||
- 安装 Tor 服务
|
||||
- 使用 `--proxy` 配合其他代理
|
||||
|
||||
### 误报
|
||||
部分站点由于响应结构问题始终返回"已找到"。对意外结果进行人工交叉核验。
|
||||
|
||||
### 速率限制
|
||||
频繁搜索可能触发速率限制。批量用户名搜索时,在调用之间添加延迟,或使用 `--local` 配合缓存数据。
|
||||
|
||||
## 安装
|
||||
|
||||
### pipx(推荐)
|
||||
```bash
|
||||
pipx install sherlock-project
|
||||
```
|
||||
|
||||
### pip
|
||||
```bash
|
||||
pip install sherlock-project
|
||||
```
|
||||
|
||||
### Docker
|
||||
```bash
|
||||
docker pull sherlock/sherlock
|
||||
docker run -it --rm sherlock/sherlock <username>
|
||||
```
|
||||
|
||||
### Linux 软件包
|
||||
适用于 Debian 13+、Ubuntu 22.10+、Homebrew、Kali、BlackArch。
|
||||
|
||||
## 合规使用
|
||||
|
||||
此工具仅用于合法的 OSINT 和研究目的。请提醒用户:
|
||||
- 仅搜索自己拥有或有权调查的用户名
|
||||
- 遵守各平台服务条款
|
||||
- 不得用于骚扰、跟踪或非法活动
|
||||
- 分享结果前请考虑隐私影响
|
||||
|
||||
## 验证
|
||||
|
||||
运行 sherlock 后,验证:
|
||||
1. 输出列出了带 URL 的已找到站点
|
||||
2. 如使用文件输出,已创建 `<username>.txt` 文件(默认输出)
|
||||
3. 如使用 `--print-found`,输出应仅包含匹配的 `[+]` 行
|
||||
|
||||
## 交互示例
|
||||
|
||||
**用户:** "Can you check if the username 'johndoe123' exists on social media?"
|
||||
|
||||
**Agent 操作流程:**
|
||||
1. 检查 `sherlock --version`(验证已安装)
|
||||
2. 已提供用户名 — 直接继续
|
||||
3. 运行:`sherlock --print-found --no-color "johndoe123" --timeout 90`
|
||||
4. 解析输出并呈现链接
|
||||
|
||||
**响应格式:**
|
||||
> Found 12 accounts for username 'johndoe123':
|
||||
>
|
||||
> • https://twitter.com/johndoe123
|
||||
> • https://github.com/johndoe123
|
||||
> • https://instagram.com/johndoe123
|
||||
> • [... 其他链接]
|
||||
>
|
||||
> Results saved to: johndoe123.txt
|
||||
|
||||
---
|
||||
|
||||
**用户:** "Search for username 'alice' including NSFW sites"
|
||||
|
||||
**Agent 操作流程:**
|
||||
1. 检查 sherlock 已安装
|
||||
2. 已提供用户名及 NSFW 标志
|
||||
3. 运行:`sherlock --print-found --no-color --nsfw "alice" --timeout 90`
|
||||
4. 呈现结果
|
||||
Reference in New Issue
Block a user