{/ Эта страница автоматически создается на основе файла SKILL.md навыка с помощью сайта site/scripts/generate-skill-docs.py. Редактируйте исходный код SKILL.md, а не эту страницу. /}
Осс Криминалистика
Расследование цепочки поставок, восстановление доказательств и судебно-медицинский анализ для репозиториев GitHub.
Охватывает восстановление удаленных коммитов, обнаружение принудительной отправки, извлечение IOC, доказательства из нескольких источников.
сбор, формирование/проверка гипотез и структурированные судебно-медицинские отчеты.
Вдохновлен криминалистической системой OSS RAPTOR, состоящей из более чем 1800 строк.
Метаданные навыков
Источник
Необязательно — установите с помощью hermesskills installofficial/security/oss-forensics
Путь
optional-skills/security/oss-forensics
Платформы
Linux, MacOS, Windows
Ссылка: полная версия SKILL.md:::информация
Ниже приведено полное определение навыка, которое Гермес загружает при активации этого навыка. Это то, что агент видит в качестве инструкций, когда навык активен.
Навыки криминалистической экспертизы безопасности OSS
Семиэтапная многоагентная система расследований для исследования атак на цепочки поставок с открытым исходным кодом.
Адаптировано из криминалистической системы RAPTOR. Охватывает архив GitHub, Wayback Machine, API GitHub,
локальный анализ git, извлечение IOC, формирование и проверка научно обоснованных гипотез,
и составление окончательного отчета судебно-медицинской экспертизы.
⚠️ Ограждения против галлюцинаций
Прочтите их перед каждым шагом расследования. Нарушение их делает отчет недействительным.
Правило доказательства прежде всего: Каждое утверждение в любом отчете, гипотезе или резюме ДОЛЖНО содержать хотя бы один идентификатор доказательства («EV-XXXX»). Утверждения без цитат запрещены.
ОСТАВАЙТЕСЬ НА СВОЕЙ ДОРОЖКЕ: каждый субагент (следователь) имеет единственный источник данных. НЕ смешивайте источники. Исследователь архива GH не запрашивает API GitHub, и наоборот. Ролевые границы жесткие.
Разделение фактов и гипотез. Отметьте все непроверенные выводы значком «[ГИПОТЕЗА]». В качестве фактов могут выступать только утверждения, проверенные на основе первоисточников.
Нет фальсификации доказательств. Прежде чем принять гипотезу, специалист по проверке гипотез ДОЛЖЕН механически проверить, что каждый цитируемый идентификатор доказательства действительно существует в хранилище доказательств.
Опровержение, требующее доказательств. Гипотезу нельзя отвергнуть без конкретного, подтвержденного доказательствами контраргумента. «Никаких доказательств не найдено» недостаточно для опровержения — оно только делает гипотезу неубедительной.
Двойная проверка SHA/URL. Любая фиксация SHA, URL-адрес или внешний идентификатор, указанный в качестве доказательства, должна быть независимо подтверждена как минимум из двух источников, прежде чем она будет помечена как проверенная.
Правило подозрительного кода: никогда не запускайте код, найденный в исследуемом репозитории, локально. Анализируйте только статически или используйте «execute_code» в изолированной среде.
Секретное редактирование. Любые ключи API, токены или учетные данные, обнаруженные в ходе расследования, должны быть отредактированы в окончательном отчете. Регистрируйте их только внутри компании.
Примеры сценариев
Сценарий A: Путаница зависимостей: Вредоносный пакет «internal-lib-v2» загружается в NPM с более высокой версией, чем внутренняя. Исследователь должен отслеживать, когда этот пакет был впервые обнаружен и обновил ли какой-либо PushEvents в целевом репозитории package.json до этой версии.
Сценарий B: Поглощение сопровождающего: учетная запись долгосрочного участника используется для отправки зашифрованного .github/workflows/build.yml. Следователь ищет PushEvents от этого пользователя после длительного периода бездействия или с нового IP-адреса или местоположения (если его можно обнаружить с помощью BigQuery).
Сценарий C: Скрыть с помощью принудительного нажатия: разработчик случайно фиксирует производственный секрет, а затем принудительно «исправляет» его. Исследователь использует git fsck и GH Archive, чтобы восстановить исходный SHA коммита и проверить, что произошло в результате утечки.
Соглашение о пути: во всем этом навыке SKILL_DIR относится к корню этого навыка.
каталог установки (папка, содержащая этот SKILL.md). Когда навык загружен,
разрешить SKILL_DIR в фактический путь — например. ~/.hermes/skills/security/oss-forensics/
или эквивалент optional-skills/. Все ссылки на скрипты и шаблоны относятся к нему.
Фаза 0: Инициализация
Создайте рабочий каталог расследования:
bash
mkdir investigation_$(echo "REPO_NAME" | tr '/' '_')
cd investigation_$(echo "REPO_NAME" | tr '/' '_')
Инициализируйте хранилище доказательств:
bash
python3 SKILL_DIR/scripts/evidence-store.py --store evidence.json list
Создайте файл iocs.md для отслеживания индикаторов компрометации по мере их обнаружения.
Запишите время начала расследования, целевой репозиторий и заявленную цель расследования.
Этап 1: быстрый анализ и извлечение IOC
Цель: извлечь все структурированные объекты расследования из запроса пользователя.
Действия:
- Разберите приглашение пользователя и извлеките:
- Целевой репозиторий («владелец/репо»)
- Целевые участники (дескрипторы GitHub, адреса электронной почты)
- Временной интервал, представляющий интерес (диапазоны дат фиксации, временные метки PR)
- Предоставленные индикаторы компрометации: фиксация SHA, пути к файлам, имена пакетов, IP-адреса, домены, ключи/токены API, вредоносные URL-адреса.
- Любые связанные отчеты о безопасности поставщиков или сообщения в блогах.
Инструменты: только рассуждения или execute_code для извлечения регулярных выражений из больших текстовых блоков.
Выход: Заполните iocs.md извлеченными IOC. Каждый МОК должен иметь:
– Тип (из: COMMIT_SHA, FILE_PATH, API_KEY, SECRET, IP_ADDRESS, DOMAIN, PACKAGE_NAME, ACTOR_USERNAME, MALICIOUS_URL, OTHER)
- Ценность
- Источник (предоставленный пользователем, предполагаемый)
Создайте до 5 субагентов-специалистов-следователей, используя delegate_task (пакетный режим, максимум 3 одновременно). Каждый следователь имеет один источник данных и не должен смешивать источники.
Примечание для оркестратора. Передайте список IOC из этапа 1 и окно времени расследования в поле «контекст» каждой делегированной задачи.
Следователь 1: Локальный следователь Git
ГРАНИЦА РОЛИ: вы запрашиваете ТОЛЬКО ЛОКАЛЬНЫЙ РЕПОЗИТОРИЙ GIT. Не вызывайте никакие внешние API.
Действия:
# Clone repository
gitclonehttps://github.com/OWNER/REPO.gittarget_repo&&cdtarget_repo
# Full commit log with stats
gitlog--all--full-history--stat--format="%H|%ae|%an|%ai|%s">../git_log.txt
# Detect force-push evidence (orphaned/dangling commits)
gitfsck--lost-found--unreachable2>&1|grepcommit>../dangling_commits.txt
# Check reflog for rewritten history
gitreflog--all>../reflog.txt
# List ALL branches including deleted remote refs
gitbranch-a-v>../branches.txt
# Find suspicious large binary additions
gitlog--all--diff-filter=A--name-only--format="%H %ai"--"*.so""*.dll""*.exe""*.bin">../binary_additions.txt
# Check for GPG signature anomalies
gitlog--show-signature--format="%H %ai %aN">../signature_check.txt2>&1
Доказательства для сбора (добавьте через python3 SKILL_DIR/scripts/evidence-store.py add):
- Каждый висячий коммит SHA → введите: git
- Доказательства принудительного нажатия (рефлог, показывающий перезапись истории) → введите: git
— Неподписанные коммиты от проверенных участников → введите: git
- Подозрительные дополнения к двоичным файлам → введите: git
ГРАНИЦА РОЛЕЙ: вы запрашиваете ТОЛЬКО GITHUB REST API. Не запускайте команды git локально.
Действия:
# Commits (paginated)
curl-s"https://api.github.com/repos/OWNER/REPO/commits?per_page=100">api_commits.json
# Pull Requests including closed/deleted
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
# Contributors and collaborator changes
curl-s"https://api.github.com/repos/OWNER/REPO/contributors">api_contributors.json
# Repository events (last 300)
curl-s"https://api.github.com/repos/OWNER/REPO/events?per_page=100">api_events.json
# Check specific suspicious commit SHA details
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
# Check if a specific commit exists (force-pushed commits may 404 on commits/ but succeed on git/commits/)
curl-s"https://api.github.com/repos/OWNER/REPO/commits/SHA"|jq.sha
Цели перекрестных ссылок (помечайте расхождения как доказательство):
- PR существует в архиве, но отсутствует в API → свидетельство удаления
- Участник в архиве событий, но не в списке участников → свидетельство отзыва разрешения
- Фиксация в архиве PushEvents, но не в списке фиксации API → свидетельство принудительного нажатия/удаления.
# Search for archived snapshots of the repo main page
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
# Search for a specific deleted 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
# Search for a specific deleted 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
# Fetch the best snapshot of a page# Use the Wayback Machine URL: https://web.archive.org/web/TIMESTAMP/ORIGINAL_URL# Example: https://web.archive.org/web/20240101000000*/github.com/OWNER/REPO# Advanced: Search for deleted releases/tags
curl-s"https://web.archive.org/cdx/search/cdx?url=github.com/OWNER/REPO/releases/tag/*&output=json">wayback_tags.json
# Advanced: Search for historical wiki changes
curl-s"https://web.archive.org/cdx/search/cdx?url=github.com/OWNER/REPO/wiki/*&output=json">wayback_wiki.json
Доказательства, которые необходимо собрать:
- Архивированные снимки удаленных выпусков/запросов с их содержанием.
- Исторические версии README, показывающие изменения.
- Доказательства наличия контента в архиве, но его отсутствия в текущем состоянии GitHub.
ГРАНИЦА РОЛЕЙ: вы запрашиваете GITHUB ARCHIVE ТОЛЬКО через BIGQUERY. Это защищенная от несанкционированного доступа запись всех публичных событий GitHub.
Предварительные требования: требуются учетные данные Google Cloud с доступом к BigQuery («вход в приложение gcloud auth по умолчанию»). Если он недоступен, пропустите этого следователя и отметьте его в отчете.
Правила оптимизации затрат (ОБЯЗАТЕЛЬНЫЕ):
1. ВСЕГДА запускайте --dry_run перед каждым запросом, чтобы оценить стоимость.
2. Используйте _TABLE_SUFFIX для фильтрации по диапазону дат и минимизации сканированных данных.
3. ВЫБЕРИТЕ только те столбцы, которые вам нужны.
4. Добавьте LIMIT, если не агрегируете.
# Template: safe BigQuery query for PushEvents to OWNER/REPO
bqquery--use_legacy_sql=false--dry_run"SELECT created_at, actor.login, payload.commits, payload.before, payload.head, payload.size, payload.distinct_sizeFROM \`githubarchive.month.*\`WHERE _TABLE_SUFFIX BETWEEN 'YYYYMM' AND 'YYYYMM' AND type = 'PushEvent' AND repo.name = 'OWNER/REPO'LIMIT 1000"# If cost is acceptable, re-run without --dry_run# Detect force-pushes: zero-distinct_size PushEvents mean commits were force-erased# payload.distinct_size = 0 AND payload.size > 0 → force push indicator# Check for deleted branch events
bqquery--use_legacy_sql=false"SELECT created_at, actor.login, payload.ref, payload.ref_typeFROM \`githubarchive.month.*\`WHERE _TABLE_SUFFIX BETWEEN 'YYYYMM' AND 'YYYYMM' AND type = 'DeleteEvent' AND repo.name = 'OWNER/REPO'LIMIT 200"
Evidence to collect:
- Force-push events (payload.size > 0, payload.distinct_size = 0)
- DeleteEvents for branches/tags
- WorkflowRunEvents for suspicious CI/CD automation
- PushEvents that precede a "gap" in the git log (evidence of rewrite)
ROLE BOUNDARY: You enrich EXISTING IOCs from Phase 1 using passive public sources ONLY. Do not execute any code from the target repository.
Actions:
- For each commit SHA: attempt recovery via direct GitHub URL (github.com/OWNER/REPO/commit/SHA.patch)
- For each domain/IP: check passive DNS, WHOIS records (via web_extract on public WHOIS services)
- For each package name: check npm/PyPI for matching malicious package reports
- For each actor username: check GitHub profile, contribution history, account age
- Recover force-pushed commits using 3 methods (see recovery-techniques.md)
Phase 3: Evidence Consolidation
After all investigators complete:
Run python3 SKILL_DIR/scripts/evidence-store.py --store evidence.json list to see all collected evidence.
For each piece of evidence, verify the content_sha256 hash matches the original source.
Group evidence by:
Timeline: Sort all timestamped evidence chronologically
Actor: Group by GitHub handle or email
IOC: Link evidence to the IOC it relates to
Identify discrepancies: items present in one source but absent in another (key deletion indicators).
Flag evidence as [VERIFIED] (confirmed from 2+ independent sources) or [UNVERIFIED] (single source only).
Phase 4: Hypothesis Formation
A hypothesis must:
- State a specific claim (e.g., "Actor X force-pushed to BRANCH on DATE to erase commit SHA")
- Cite at least 2 evidence IDs that support it (EV-XXXX, EV-YYYY)
- Identify what evidence would disprove it
- Be labeled [HYPOTHESIS] until validated
Common hypothesis templates (see investigation-templates.md):
- Maintainer Compromise: legitimate account used post-takeover to inject malicious code
- Dependency Confusion: package name squatting to intercept installs
- CI/CD Injection: malicious workflow changes to run code during builds
- Typosquatting: near-identical package name targeting misspellers
- Credential Leak: token/key accidentally committed then force-pushed to erase
For each hypothesis, spawn a delegate_task sub-agent to attempt to find disconfirming evidence before confirming.
Phase 5: Hypothesis Validation
The validator sub-agent MUST mechanically check:
For each hypothesis, extract all cited evidence IDs.
Verify each ID exists in evidence.json (hard failure if any ID is missing → hypothesis rejected as potentially fabricated).
Verify each [VERIFIED] piece of evidence was confirmed from 2+ sources.
Check logical consistency: does the timeline depicted by the evidence support the hypothesis?
Check for alternative explanations: could the same evidence pattern arise from a benign cause?
Output:
- VALIDATED: All evidence cited, verified, logically consistent, no plausible alternative explanation.
- INCONCLUSIVE: Evidence supports hypothesis but alternative explanations exist or evidence is insufficient.
- REJECTED: Missing evidence IDs, unverified evidence cited as fact, logical inconsistency detected.
Rejected hypotheses feed back into Phase 4 for refinement (max 3 iterations).
Phase 6: Final Report Generation
Populate investigation-report.md using the template in forensic-report.md.
Mandatory sections:
- Executive Summary: one-paragraph verdict (Compromised / Clean / Inconclusive) with confidence level
- Timeline: chronological reconstruction of all significant events with evidence citations
- Validated Hypotheses: each with status and supporting evidence IDs
- Evidence Registry: table of all EV-XXXX entries with source, type, and verification status
- IOC List: all extracted and enriched Indicators of Compromise
- Chain of Custody: how evidence was collected, from what sources, at what timestamps
- Recommendations: immediate mitigations if compromise detected; monitoring recommendations
Report rules:
- Every factual claim must have at least one [EV-XXXX] citation
- Executive Summary must state confidence level (High / Medium / Low)
- All secrets/credentials must be redacted to [REDACTED]
Phase 7: Completion
Run final evidence count: python3 SKILL_DIR/scripts/evidence-store.py --store evidence.json list
Note disclosure obligations (if a public package: coordinate with the package registry)
Present the final investigation-report.md to the user.
Ethical Use Guidelines
This skill is designed for defensive security investigation — protecting open-source software from supply chain attacks. It must not be used for:
Harassment or stalking of contributors or maintainers
Doxing — correlating GitHub activity to real identities for malicious purposes
Competitive intelligence — investigating proprietary or internal repositories without authorization
False accusations — publishing investigation results without validated evidence (see anti-hallucination guardrails)
Investigations should be conducted with the principle of minimal intrusion: collect only the evidence necessary to validate or refute the hypothesis. When publishing results, follow responsible disclosure practices and coordinate with affected maintainers before public disclosure.
If the investigation reveals a genuine compromise, follow the coordinated vulnerability disclosure process:
1. Notify the repository maintainers privately first
2. Allow reasonable time for remediation (typically 90 days)
3. Coordinate with package registries (npm, PyPI, etc.) if published packages are affected
4. File a CVE if appropriate
API Rate Limiting
GitHub REST API enforces rate limits that will interrupt large investigations if not managed.
Authenticated requests: 5,000/hour (requires GITHUB_TOKEN env var or gh CLI auth)
Unauthenticated requests: 60/hour (unusable for investigations)
Best practices:
- Always authenticate: export GITHUB_TOKEN=ghp_... or use gh CLI (auto-authenticates)
- Use conditional requests (If-None-Match / If-Modified-Since headers) to avoid consuming quota on unchanged data
- For paginated endpoints, fetch all pages in sequence — don't parallelize against the same endpoint
- Check X-RateLimit-Remaining header; if below 100, pause for X-RateLimit-Reset timestamp
- BigQuery has its own quotas (10 TiB/day free tier) — always dry-run first
- Wayback Machine CDX API: no formal rate limit, but be courteous (1-2 req/sec max)
If rate-limited mid-investigation, record the partial results in the evidence store and note the limitation in the report.