
Turn any codebase, with its docs, SQL schemas, configs, and PDFs, into a queryable knowledge graph. A /graphify skill for Claude Code, Cursor, Codex, and Gemini CLI: local deterministic AST parsing, every edge explained, no vector store.
CTI Expert turns Claude into a structured intelligence analyst for OSINT and cyber threat work. It combines command files, typed tools, hooks, and a deep case pipeline that collects evidence, expands pivots, scores findings, and generates reports.
Builders who use Claude Code or Codex to run OSINT and cyber threat intelligence cases.
You can move from raw collection to a structured case and finished report without rebuilding the workflow each time.
Provides 120+ commands such as case setup, checking, clustering, pivoting, recall, reporting, and status.
Ships 79 typed MCP tools for collection, enrichment, pivoting, and report generation.
Uses a repeatable case flow that turns raw findings into a case, assessment, and deliverables.
Builds markdown, JSON, CSV, IOC bundles, and presentation reports like PDF, DOCX, and HTML.
Includes lifecycle hooks such as action, leak, and session guards, plus audit checks for keys and tool gates.
Adds connector docs for services such as ChongLuaDao, Intel backend, Maltego export, Notion schema, and Obsidian setup.
npm install -g @anthropic-ai/claude-code
git clone https://github.com/7onez/cti-expert.git ~/.claude/skills/cti-expert bash ~/.claude/skills/cti-expert/scripts/install.sh
git clone https://github.com/7onez/cti-expert.git ~/.claude/skills/cti-expert bash ~/.claude/skills/cti-expert/scripts/install.sh
git clone https://github.com/7onez/cti-expert.git "$env:USERPROFILE\.claude\skills\cti-expert" powershell -ExecutionPolicy Bypass -File "$env:USERPROFILE\.claude\skills\cti-expert\scripts\install.ps1"
bash scripts/install.sh # Core: Python deps + system tools + OSINT tools bash scripts/install.sh --headless # + Scrapling headless browser (~200MB Chromium) bash scripts/install.sh --go # + Go tools (subfinder, amass, gau, gitleaks, httpx) bash scripts/install.sh --all # + Everything above
powershell -ExecutionPolicy Bypass -File scripts\install.ps1 # Core powershell -ExecutionPolicy Bypass -File scripts\install.ps1 -Headless # + Scrapling headless browser powershell -ExecutionPolicy Bypass -File scripts\install.ps1 -Go # + Go tools powershell -ExecutionPolicy Bypass -File scripts\install.ps1 -All # + Everything above
Transform Claude into a trained intelligence analyst — 120+ commands, 57 techniques, zero API keys required for core functionality.
Installation | View Demo | Quick Start | Commands | Contribute
🇬🇧 English · 🇻🇳 Tiếng Việt · 🇨🇳 中文
Built by Hieu Ngo • hieu.ngo@chongluadao.vn • chongluadao.vn
Core contributor • Zeroska • khuong.nguyen@chongluadao.vn
CTI Expert is built in the open. These organisations back the work — with data, tooling, and hard-won investigative tradecraft.
| Supporter | What they bring | In the toolkit |
|---|---|---|
| Rexxfield | Cybercrime investigation and victim-side casework since 2008 — the real-world tradecraft the case workflow and attribution standards are modelled on | Tradecraft & methodology |
| ChongLuaDao ⭐ | First-party — the project's home org. Premium VN threat intel: ~20M-URL denylist verdicts, deep AI URL analysis, IoC + data-leak/breach exposure, brand lookalikes and CVE/KEV feeds — your client talks only to CLD, which fetches the target server-side (never your egress) | /cld · /scam-check · /threat-check · /breach-deep |
| Hudson Rock | Infostealer-infection intelligence — which machines leaked which credentials, and when | /breach-deep · /stealer-log |
| ParanoidLab | Dark-web, Initial-Access-Broker and infostealer-log monitoring across forums, markets and private Telegram | Dark-web collection & review |
| ANY.RUN | Interactive malware sandbox + TI Lookup — sandbox-observed C2 and real endpoints from packed samples | /binary · /hash-id |
| ZETAlytics | Global passive DNS with rare geographic diversity — historical resolution and co-tenancy pivots | /webpivot · /cti-pivot |
| IntelX | Intelligence X — paste sites, leaks, darknet and phonebook selector search | /webpivot · /email-deep |
| Shodan | Internet-connected host & service intelligence — open ports, banners, tags and known CVEs, passive-first via InternetDB | /webpivot · /appliance-scan · /cert-pivot |
| Censys | Internet-wide host & certificate scanning — the server-side view; every host on an exact leaf certificate (works on the free plan) | /censys · /cert-pivot |
| URLScan.io | Passive website scanning — what a page served and who it talked to, captured without touching the target | /webpivot · /impersonate |
| SerpApi | Search-engine + Google Ads Transparency results API — who paid to send traffic, plus multi-engine dork results | /serp · /search-pivot |
| GrayHatWarfare | Open cloud-bucket & exposed-file search (S3/Azure/GCS/Spaces) — graded exposure, not a same-operator pivot | /secrets · /docleak |
| Social Links | OSINT investigation platform — 1000+ methods across social media, blockchain and the dark web (SL Professional / Crimewall, Maltego transforms) | OSINT methodology & data |
| Validin | DNS + certificates + favicon + response-body hashes in one graph — passive DNS, subdomain enumeration, reverse-IP and host-response hash pivots on a free community key | Native in /webpivot (domain lookup, reputation, cert & favicon hosts) · MO-neighbour source · /cti-pivot |
| Netlas | Independent internet-asset index — DNS, scan responses, WHOIS and certificate collections behind one key; domains a:<origin-ip> reverses a non-CDN origin to every apex with dates | /webpivot MO-neighbour source · intel.py netlas · entitlement probe |
[!IMPORTANT] ANY.RUN lookups are read-only; detonation is gated.
anyrun_lookupqueries TI Lookup for hashes that have already been detonated.anyrun_submitcan detonate a file or URL, but only behind a per-submission analyst confirmation (a briefing-then-confirm=truetwo-step), private-by-default privacy withpublicrefused, a fail-closed plan check (the account's own/userprivate quota — zero is denied outright — else a prior private task, else an explicit analyst attestation to a paid plan), a post-submit privacy read-back that withdraws and flags a task that still landed public, and a harness deny unlessHARNESS_ALLOW_SUBMIT=1. A public sandbox task is world-readable and irreversible; the gate is enforced by a regression test (tests/test_no_sample_submission.py), not just by convention.
Listing here reflects support for the project and does not imply affiliation, endorsement, or any verification of this tool by the organisations named. Integrations marked above are optional and key-gated — every core technique still runs with zero API keys. Always respect each provider's terms of service. The full list of open-source projects and free public-interest services this skill depends on is in Acknowledgments & Credits.
A Claude Code skill that transforms Claude into a trained cyber threat intelligence and open-source intelligence analyst. It runs structured intelligence collection using 120+ commands across 57 techniques — no API keys required for core functionality. To take full advantage, add your own free or paid API keys to the skill's .env — each is auto-detected and unlocks higher-tier access (e.g., Wigle, VirusTotal, URLScan.io, Shodan, Censys, SecurityTrails, WhoisXML).
[!TIP] Keyless by default, more powerful with your keys. Every core technique runs with zero API keys. Add any free or paid keys to
.env(or run/apikeys set <service> <KEY>) and the skill auto-detects them, unlocking higher-tier pivots: reverse favicon→host, passive DNS, certificate search, sibling-domain discovery. A missing or bad key never breaks a run — it just degrades to a note. Setup guide: handbook/api-keys.md.
[!TIP] One skill, two layers. cti-expert is the broad collector — the wide net (
/sweep,/webpivot,/subdomain,/username,/email-deep…). Built into the repo is a deep pipeline (intel_engine/) that turns raw collection into a real case: a persistent knowledge base, versioned cases, cross-case correlation, and calibrated assessment. The flow reads like a sentence — collect broadly → "seen this operator before?" → cluster → filter false positives → assess. No external setup: the backend resolves toSELF, and as of v2.9 the bundled installer (scripts/install.{sh,ps1}) provisions the deep layer automatically (or by hand:uv venv && uv pip install -r requirements.txt). Architecture: connectors/intel-backend.md.
|
Core Capability Multi-vector reconnaissance on any target type — person, domain, organization, username, email, IP, WiFi — with automated finding validation, exposure scoring, and structured intelligence delivery. |
AEAD Workflow Acquire raw data → Enrich with pivot expansion → Assess findings → Deliver structured reports — the base bundle (Markdown + JSON + CSV + IOC bundle) always saves, then you pick a presentation report: PDF, DOCX, HTML, or all. |
| INTSUM Report | Network Topology | Risk Assessment |
|---|---|---|
![]() | ![]() | ![]() |
The release where the premium keys start pulling their weight — and the report writes itself. v2.11 shipped detectors. v2.12 turns an eight-finding audit of the paid vendors into behaviour (every metered leg gated, bought once per case instead of once per host), adds Netlas as an independent index, makes the editorial PDF/DOCX a deterministic composition from the case directory, and closes the last honesty gap in the ANY.RUN docs: detonation exists, and it is gated five ways.
| Category | What's New | Details |
|---|---|---|
| MO-neighbour pivot | Reverse a non-CDN origin to its co-tenants — and only ever seed on a registrant join key | wp_mo_neighbours.discover reverses the estate's non-CDN origin IP (also the MX origin) through Netlas · Validin · urlscan, WHOIS-verifies each candidate apex, and classifies it same_registrant (current registrant e-mail/phone join key only — a proxied record contributes no phone) / same_mo (reference-data policy) / unrelated / unverifiable. Only same_registrant seeds the frontier; same-MO personas render as a rung-10 Related personas table in the report (--mask-personas to aggregate). A bulk-hosting guard fires before any spend; per-origin lock + disk cache + a per-run WhoisXML ledger hold across collector subprocesses, so an origin is bought once per case. RULE 5 rails intact: facts-only KB ingest, never an edge, never an operator_lead |
| WHOIS eras · urlscan Pro lifecycle | The timeline now knows who held the name before this operator | WHOIS history is an explicit --whois-history purchase scoped to seeds and cluster members (the render path never buys it); the house report renders a Registrant eras table (same-day flaps folded, registrar placeholders classed) and uses the current era's start as the archive-capture cutoff. urlscan Pro supplies the hostname lifecycle index — A/NS eras, CT and zonefile firsts, left-censored on a truncated walk — feeding the temporal view; verdict rows appear only on signal, and the API key is sent to urlscan.io only |
| Entitlement measured, not assumed | A key measured free skips the calls that would 403 | wp_capabilities.discover_plans probes each vendor's free account endpoint (urlscan quotas, Netlas plan, SecurityTrails/DNSLytics usage, IntelX /authenticate/info, Validin /api/paths) once per case into cases/<id>/capability_plans.json; enrich_live reads the store and gates only on a positive free verdict — unknown keeps the productive call as the probe. Censys search records its own verdict. A failed probe is reported this run and never frozen, so the next process re-measures |
| Netlas + the rest of the vendor wiring | Every registered key now has a pivot behind it | wp_netlas.py — Bearer client over the domains · responses · whois_domains · whois_ip · certs collections (search, count, facet, reverse-IP, plan), keyless query builder + web-UI links, ledgered, Cloudflare-safe UA; intel.py netlas ip|ns|spf|domain|san|title|plan|raw. Live-measured: domains a:<origin> returned 32 apexes on a 32-domain estate (15 members + same-MO siblings under other personas). Alongside: SecurityTrails DNS-history eras + DSL reverse-WHOIS (diffed against WhoisXML), DNSLytics reverse-IP under its own co-tenancy-routed key, GrayHatWarfare exposure lead + report section, Shodan cert/JARM search, once-per-case Censys cert search with a shared-cert fan-out guard, IntelX auto-fire in pipeline open (loop: --full only; role mailboxes excluded), and Validin wired natively (domain lookup, reputation, cert and favicon hosts). Frontier ranks owner-link candidates above lookalikes |
| The house report, composed deterministically | The editorial PDF/DOCX no longer needs a model to write it | intel.py house-report <CASE-ID> composes the IntelReport document from the case dir: sections I–XI, both confidence scales + the ICD-203 × Admiralty scatter, relationship graph + entity-relationship map, attribution inference chain, temporal view + registration heatmap + domain × shared-indicator matrix (which honours the §2.5 false-positive control and carries the WHOIS join keys), a landing-page capture per estate host (proxy-gated egress; a page that will not render falls back to the newest public web-scan, then a web-archive snapshot — captioned, dated by the archive, and labelled a previous owner's page when it predates the current registration), per-domain dossiers, a glossary, Appendices A–E. Rule 12 scrub of tool/vendor/path names; third parties masked through one gate (scripts/cti_third_party_mask.py). One figure source (scripts/cti_report_figures.py) feeds both the dashboard DOCX and the house PDF, so the two deliverables cannot disagree. --no-screenshots is fully offline; --no-archive-fallback forbids the stand-ins |
| ANY.RUN: the gate is real, and the docs now say so | Detonation exists — behind five gates, each of them code | SKILL.md, the README callouts, .env.example and the key registry claimed "no submit path". False since the gated layer landed. anyrun_submit is gated by: per-submission confirmation (a confirm=false briefing first — a data-driven approval_briefing exemption in tool_policy.json now lets that step through the MCP approval gate, fail-closed to fully gated if the file is unreadable); private by default, public refused unless ANYRUN_ALLOW_PUBLIC=1 grants a standing authorization, and then only as an explicit, recorded downgrade; a fail-closed plan check (/user private quota — zero is denied and no attestation overrides it — else a prior private task, else --i-have-a-paid-plan); a polled post-submit privacy read-back that withdraws and flags a task that still landed public (verify-privacy <uuid> finishes the check if the task outlives the wait); and the harness deny unless HARNESS_ALLOW_SUBMIT=1. 103 stubbed checks in test_intelx_anyrun §7b–7c; test_tool_gate §2 pins briefing-allowed / confirm-denied / fail-closed |
| Repo hygiene | The tree checks itself for pasted keys | audit.sh §5b greps every tracked file for vendor key shapes and KEY=value lines — proven to fire on a planted value and clean on the tree, so a key can only live in .env. AGENTS.md rewritten as the cross-agent Repository Guidelines. Key-alias registries reconciled with every tool's _secret() lookup and locked (tests/test_key_alias_registry.py); SecurityTrails / DNSLytics / CertSpotter registered so the capability banner stops going silent on keys it uses. The three workflow diagrams re-rendered from current sources — 79 @tools, 9 commands, Netlas, gated ANY.RUN |
| Every documented command is real | 26 SKILL.md commands that had no code behind them now resolve to a tool — or say what they are | 18 new keyless-first CLIs under scripts/osint/ (hash_id — MD5 vs NTLM before you submit, vuln_check, username_enum, phone_osint, github_osint, reputation_check, msft_recon, cn_recon, traffic_rank, sharelink_resolve, dork_builder, exposure_score, signature_scan, kb_crossref, case_drift, deep_profile, wifi_ssid …) plus 8 existing scripts/webpivot/ shims (cert_pivot, email_hygiene, wayback_fetch/harvest, rank_relations, sensitive_paths, pivot_suggest, crypto_balance) registered as @tools and intel.py ops; every SKILL.md command row now names its T2 CLI and T1 tool, or is labelled [model] / [unimplemented]. 79 @tools, and the SDK allowlists are locked to the decorated set (test_tool_registry.py). Clustering enforces the two-artifact rule: each cluster carries corroboration, and one shared artifact is flagged LEAD ONLY, never an attributed estate. The vendored engine's own tests now run in audit.sh §9–10 and CI — they ran nowhere before |
| ChongLuaDao in the pipeline · subdomains · one timeout ceiling | The first-party feeds grade every host, live subdomains join the case, and no call hangs a run | wp_cld.py runs per collected host inside enrich_live — denylist verdict + IoC analysis land as reputation facts (never a cluster edge) and CLD WHOIS is the primary source for .vn names. subdomain_enum unions subfinder (auto-keyed from .env), amass, assetfinder and findomain, DNS-verifies the names into cases/<id>/subenum/<apex>.json, and the frontier queues the live ones for the next round (hoster plumbing is a fact, not a seed). A single per-call ceiling — CTI_CALL_TIMEOUT, default 1800 s from WebPivot/references/timeouts.json — floors every fetch, vendor call, collector and renderer subprocess; raw DNS/TLS probes keep their fail-fast bounds, and a running MCP server keeps its value until restarted |
| Registrable apexes · landlord IPs · kit binders | The frontier and the KB agree on what an apex is and which IP is a landlord | A vendored Public Suffix List (public_suffix_list.json, wp_psl_update.py) drives one _registrable() reducer, so shop.id.vn and panel.co.uk fold to the right apex everywhere — frontier, ingest, report, Blueprint. shared_hosting_max_cohosts (12) is the one number that marks an IP as shared/bulk hosting: its hosted_on edges become facts, the cluster partition ignores them, and co-tenants are held back as leads. Expansion depth is anchored: a host owner-linked to a previous hop is related_hosts, never a member. Scraped social links resolve to the account — per-network reserved paths, second-segment routers and library/vendor credit accounts are reference data, and a bare platform apex (t.me, facebook.com) is never a handle |
| Blueprint folds to apex level | A hundred-host estate no longer silently drops the HTML report's architecture tab | Archify's architecture type draws ≤ 12 nodes · 18 edges, so cti_archify.py now collapses hosts under their registrable apex (Estate · N hosts), folds the long tail into +N more apexes, ranks finding-bearing apexes first and places the operator hub mid-row with spokes above and below. CTI_ARCHIFY=1 (auto: full graph if it fits, else the fold) · force (the widest 25-node grid) · 0; --plan prints both outcomes offline, and every HTML export now confirms the Blueprint mode first (Step C — --yolo keeps Auto). Locked by tests/test_archify_blueprint.py |
The eCrime-2026 follow-up batch — planned, then cooked. Four deferred phases from the v2.10 research pass ship as keyless, offline, tested modules (planned in
plans/260826-1935-ecrime-2026-followup-analyzers/, implemented via/ak:cook). Same contracts: zero-dep tests inaudit.sh, attribution-safety (RULE 5). Full mapping: docs/ecrime-research-integration.md §6.
| Category | What's New | Details |
|---|---|---|
| APK permission-scope scoring | On-device-fraud capability from the manifest | scripts/apk_permission_scope.py scores dangerous-permission combinations (accessibility+overlay+SMS = banking-trojan profile) — the combination is the signal, not any single grant, so banking/AV apps aren't blindly flagged; result is capability, not guilt. Handles plaintext manifests and binary AXML (UTF-8 and UTF-16 string pools; a zero-permission decode degrades to a note, never a false "clean"). Extends BinaryPivot. Grounded in "The 'Allow' Reflex" (Kandagadla Srinivasamurthy, Dupuis — UW). See techniques/apk-permission-scope.md |
| Kit-template attribution | Same-kit lineage across rotating hosts | [scripts/kit_template_fingerprint.py](scripts/kit_template_finge |
Sign in to join the discussion.
No comments yet. Be the first to say what this is good for.

Turn any codebase, with its docs, SQL schemas, configs, and PDFs, into a queryable knowledge graph. A /graphify skill for Claude Code, Cursor, Codex, and Gemini CLI: local deterministic AST parsing, every edge explained, no vector store.
Topic in, narrated explainer video out. A Claude Code / Codex skill that turns any topic into a black-canvas motion-graphics explainer video with TTS voiceover, subtitles and a chapter progress bar. Chinese or English; every frame drawn in code with Remotion.
Public repository for Agent Skills
Open-source AI job search: scan job portals, evaluate listings into a structured A-H report with a global 1-5 score, tailor your CV, track applications — runs locally in your AI coding CLI (Claude Code, Codex, OpenCode, Antigravity…)
Agent skill for beautiful, verifiable architecture, workflow, sequence, data-flow, and lifecycle diagrams—self-contained HTML with motion and crisp export.
A skill to stop your coding agent from burying the answer. ADHD-friendly output.