本文へ移動
cccskills
無料GitHub で公開

lookup-liberty91

Use when you need Liberty91 platform intelligence — what actually happened (deduplicated Threat Events with every source, Admiralty reliability/credibility and verification stage), whether an IOC is already known to your account, the canonical threat library (actors, malware, vulnerabilities, clusters, ATT&CK TTPs), alert matches, or which of your customer organizations an occurrence affects — or when you need to push intelligence back: ingesting your own report, generating an intelligence package, or uploading an organization document. Also supplies event provenance fields, when the platform returns them, and Threat Library alias resolution to /source-provenance and /quality-of-information-check. Two-way, first-party integration. Commonly invoked by /ip-investigation and friends, /ioc-enrichment-workflow, /threat-actor-profiling, /campaign-tracking and /vulnerability-intelligence. Reads $LIBERTY91_API_KEY.

インストール方法を見る

含まれるファイル(1)

  • SKILL.md26.4 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

lookup-liberty91

Two-way bridge to the Liberty91 platform — the pack's only first-party integration. Where VirusTotal or Shodan answer "what is known about this indicator", Liberty91 answers "what happened, who reported it, how well corroborated is it, and which of my organizations does it touch".

Like /lookup-misp and /lookup-opencti, this skill also writes: it ingests your own reports, queues intelligence packages, and manages organization profiles. Writes publish into your Liberty91 account and are metered — confirm with the user before invoking any write command, and never run one inside an autonomous enrichment loop.

The two-layer model — read this first

Everything else follows from it.

  • A Threat Event is a real-world occurrence: one breach, one exploitation campaign, one leak. Deduplicated, with every source you are entitled to attached.
  • An Event is one report about an occurrence. A breach covered by a vendor write-up, three news articles and a leak-site post is five Events and one Threat Event.
You wantCommand
What happened, deduplicated, with all its sourcesthreat-events
The individual documents — who published whatevents

Default to threat-events. Drop to events only when the question is genuinely about documents ("what did vendor X publish this week", "poll my ingested report until enrichment completes"). Every Event carries threat_event_id so you can move between layers.

When to invoke

Read:

  • The user asks what has happened — to a sector, a country, an organization, in a date window (threat-events)
  • An indicator surfaced elsewhere and you want to know whether the platform already holds it (ioc-lookup)
  • An actor / malware family / CVE needs its canonical record, aliases, ATT&CK TTPs, linked occurrences or co-occurring entities (library, entity)
  • A vendor's name for an actor needs resolving to the canonical entry (library threat-actors --alias "…")
  • /source-provenance or /quality-of-information-check needs an occurrence's provenance, or needs two vendors' names matched to one entity (see Provenance fields and Alias resolution below)
  • The user wants their alert rules' matches, or a saved search re-run (alert-matches, run-search)
  • A TIP (MISP, OpenCTI) needs parented STIX for an occurrence (threat-event <id> --section iocs-export)
  • The user asks which of their customer organizations is affected, or about an org's assets/suppliers (threat-event --section detail, orgs, org)

Write — confirm with the user first:

  • A finished investigation or an external report should live in the platform (ingest)
  • The user wants an intelligence package generated (report-generate — 50 credits per report)
  • An organization profile needs a document ingested or extracted entities confirmed (upload-document, confirm-entities, refresh-description)

Do NOT invoke for:

  • Raw internet reconnaissance — Liberty91 is curated intelligence, not a scanner. Use Shodan/Censys.
  • Bulk third-party reputation sweeps — run VT/OTX/RL first, then check the vetted subset here.
  • Community sharing — that is MISP's job (/lookup-misp). Liberty91 is your intelligence source and customer-facing production platform.

How to invoke

Single Python CLI, stdlib only — no install, no venv.

Occurrences

# Connectivity, quota, and which API surface this host serves
python3 tools/clis/liberty91.py quota

# Triage feed: occurrences at least two independent sources agree on, mapped to your account
python3 tools/clis/liberty91.py threat-events --relevant --verification corroborated --min-credibility 2

# Scope by sector / country / technique / time
python3 tools/clis/liberty91.py threat-events --target-sector energy --target-country AE --last-reported-after 2026-07-01
python3 tools/clis/liberty91.py threat-events --technique T1566.001 --event-class security-incident
python3 tools/clis/liberty91.py threat-events --organization <org-uuid> --all --max-pages 5

# One occurrence: the evidence — sources with stance + reliability, entities, ATT&CK, org relevance
python3 tools/clis/liberty91.py threat-event <id>
python3 tools/clis/liberty91.py threat-event <id> --section iocs
python3 tools/clis/liberty91.py threat-event <id> --section sources     # every report behind it, paginated
python3 tools/clis/liberty91.py threat-event <id> --section iocs-export --out bundle.json   # parented STIX for a TIP

The list row now carries the entities. From API v2.1, threat-events rows include actors, malware, vulnerabilities, techniques, victims and source_countries alongside the sectors and regions they always had. Actor/malware/vulnerability entries are {id, name, from_private_source} where id is the canonical catalog id, so you can go straight from a list row to entity <type> <id> without paying for a detail call first, which matters more now that pages are a quarter the size. Three caveats that change what you may conclude:

  • List rows show publicly-linked entities only. An entity named only in a report private to your account appears on the detail response but not on the list row. Absence from a row is not absence from the occurrence.
  • source_countries counts only publicly-sourced, non-disputing reports. Private and user-uploaded reports never contribute one, by design.
  • Only threat-events rows gained these. search and alert-matches still return the base Threat Event shape without them, so do not write a pipeline that expects actors on every occurrence row regardless of where it came from.

--section sources vs the sources in detail. The detail response embeds a sources[] block that is capped: for a heavily corroborated occurrence it is a sample, not the record. --section sources paginates the full set, newest first, and is the one to use when you are counting or citing reporting. Both are masked to what your account is entitled to, so neither reveals reporting you do not hold. It costs an extra scope: threat-events.read plus events.read.

Threat library (canonical catalog)

# Resolve a name — or a vendor's alias — to a canonical id, then track the id, not the string
python3 tools/clis/liberty91.py library threat-actors --name "APT28"
python3 tools/clis/liberty91.py library threat-actors --alias "Fancy Bear"
python3 tools/clis/liberty91.py library vulnerabilities --q "CVE-2026-2" --tracked

# The record and its sub-resources (entity types: threat-actors | malware | vulnerabilities | clusters)
python3 tools/clis/liberty91.py entity threat-actors <id>
python3 tools/clis/liberty91.py entity threat-actors <id> --section techniques      # dated ATT&CK observations
python3 tools/clis/liberty91.py entity threat-actors <id> --section threat-events   # occurrences it was named in
python3 tools/clis/liberty91.py entity threat-actors <id> --section related         # co-occurring entities
python3 tools/clis/liberty91.py entity malware <id> --section iocs

Search, events, IOCs, alerts, organizations

# Search returns Threat Events, not reports (POST, but a read — a default-scoped key can use it)
python3 tools/clis/liberty91.py search --free-text "wiper" --target-sector energy --date-from 2026-06-01T00:00:00Z
python3 tools/clis/liberty91.py search --query-tree-file tree.json    # the full grammar
python3 tools/clis/liberty91.py saved-searches
python3 tools/clis/liberty91.py run-search <id>

# Individual reports
python3 tools/clis/liberty91.py events --since 2026-07-01 --threat-event <uuid>
python3 tools/clis/liberty91.py event <id>

# IOCs
python3 tools/clis/liberty91.py ioc-lookup 185.220.101.45
python3 tools/clis/liberty91.py iocs --kind domain --verdict MALICIOUS --since 2026-07-01
python3 tools/clis/liberty91.py ioc-export --format csv --out iocs.csv     # blocklist, not TIP context

# Alerts, packages, organizations
python3 tools/clis/liberty91.py alerts
python3 tools/clis/liberty91.py alert-matches <id>                # Threat Events; --results reports for documents
python3 tools/clis/liberty91.py reports --status DRAFT
python3 tools/clis/liberty91.py report-download <id> --type md --out report.md
python3 tools/clis/liberty91.py orgs
python3 tools/clis/liberty91.py org <org-id> --section suppliers

Canonical entity filters (v2.1). Six new query_tree leaf fields, usable in search and in saved searches:

LeafValuesMatches
canonical_actorUUID[]threat actor from the deduplicated cross-tenant catalog
canonical_malwareUUID[]malware, same catalog
canonical_vulnerabilityUUID[]vulnerability, same catalog
incident_techniqueT1566, T1566.001ATT&CK techniques derived for the occurrence
affected_organizationUUID[]one of your own customer organizations
relevant_to_meone of true/false/1/0/yes/nooccurrence intersects any of your organizations' profiles

Prefer the canonical leaves. The legacy leaves (threat_actor, malware, vulnerability, threat_cluster) still work and are not being removed, but they match your account-local entities while the canonical ones match the deduplicated catalog. Resolve a name with library threat-actors --name/--alias, then filter on the canonical id.

technique and incident_technique answer different questions, and both are kept: technique matches what a single report named, incident_technique matches the set derived for the occurrence, which merges every source and can therefore carry an assertion no individual report made. Tree grammar and caps are unchanged: depth 3, 50 nodes, 50 values per leaf, 3 free-text leaves.

The caveat that will look like missing data. An entity filter returns strictly fewer results than a free-text search for the same name. A report not yet matched into an occurrence has no canonical links, so no entity filter can reach it, even when its text plainly names the actor. This is correct behaviour, not a gap. When someone asks why filtering APT28 by id returns less than searching the string, that is the answer. For a completeness sweep run the free-text search as well, and say which one the finding came from.

Write operations — confirm with the user first

# Push a report in. Private to your account; extracted IOCs are TLP:RED. 10 credits.
python3 tools/clis/liberty91.py ingest --title "Phishing wave against UAE energy" \
  --text-file findings.md --source "Internal CTI" --actor APT34 --vulnerability CVE-2026-1234

# Then poll until enrichment completes, and read threat_event_id for the occurrence it matched
python3 tools/clis/liberty91.py event <event_id>

# Intelligence package — 50 credits PER REPORT generated
python3 tools/clis/liberty91.py report-generate --organization-id <org-id> --intelligence-requirement <ir-id>

# Organization profile (orgs.write)
python3 tools/clis/liberty91.py upload-document <org-id> supplier-list.xlsx --description "2026 vendor register"
python3 tools/clis/liberty91.py confirm-entities <org-id> <doc-id> --id <entity-id> --id <entity-id>
python3 tools/clis/liberty91.py refresh-description supplier <entity-id>

Every command accepts --dry-run (preview the request, send nothing) and --insecure (skip TLS verification — non-production hosts only). Lists accept --page-size, --all, --max-pages and --cursor; next is an opaque complete URL, never build cursor params. The CLI exits 2 if LIBERTY91_API_KEY is unset. Report a missing key; never fabricate results.

Page size shrank in v2.1, and it costs you. The server default drops 100 → 25 and the maximum 500 → 100, on every paginated endpoint. Credits are charged per request and the rate limit is a fixed window per key, so the same walk now costs up to 4x the credits and 4x the rate-limit budget. The CLI omits page_size unless you pass --page-size, so it follows whichever contract the host serves and needs no change. What does need your attention is --max-pages (default 10): the same --all --max-pages 10 that returned up to 5,000 rows returns 250 against a v2.1 host. Check truncated before reporting a count as complete, and raise --max-pages deliberately rather than assuming the default still covers the set.

Reading the trust signals

Three separate judgements travel with every occurrence. Do not collapse them into one number — and do not re-derive them, they are already Admiralty.

  • Source reliability (A–F, per source) — who said it. Government sources start at A, vendors at B, news at C, and move on evidence.
  • Credibility (1–6, per occurrence, lower is better) — how well-supported the claim is. 1 Confirmed · 2 Probably True · 3 Possibly True · 4 Doubtful · 5 Improbable · 6 Cannot be judged. Syndicated re-publications collapse to one source, so they cannot inflate it. null means unscored, not average.
  • Verification — where the occurrence stands: auto, corroborated, verified, disputed, rejected, merged (see merged_into). Analyst judgements are never overwritten by the pipeline.
  • Stance — a property of each report: claims, corroborates, updates, mentions, disputes. When sources disagree, say so — report the dispute, don't average it away.

--verification corroborated --min-credibility 2 is the triage filter for "actionable now".

Provenance fields

/source-provenance and /quality-of-information-check read the following per occurrence when the platform returns them. They are planned platform work. As of 27 September 2026 they are not in the documented API contract and the CLI has no code that depends on them, so expect them to be absent.

FieldContent
primaries[]The originating sources, each with org, type, access, date, url, stated_confidence, interest. Values follow the evidence item schema
independent_primariesCount of primaries with separate access. Reports that cite one another count once
secondary_reportsCount of reports that relay a primary without adding evidence
chains[]Per report, the ordered hops from that outlet to its primary
most_recent_observationDate the activity was last observed, which is not the publication date
superseded_byLater report by the same primary that replaces this one, or null

The CLI passes the API response through, so once a host serves these fields they appear in threat-event <id> output with no CLI change. Check the response, or /api/v1/schema/, rather than assuming.

Which label the result gets:

  • Fields present → provenance_basis: platform-resolved. Use the values verbatim.
  • Fields absent, or no LIBERTY91_API_KEY configured → fall back to /source-provenance, which resolves the chain by script for the URLs in hand. The result is labelled script-resolved, never platform-resolved.
  • Some present, some absent → each evidence item takes the label of where its own provenance came from, and the run reports the worst of them.

What today's API does return is not a substitute. --section sources gives source_name, url, published_at, stance and reliability per report. That says who reported, not who originated. Do not build primaries[] or chains[] from it, and do not read verification: corroborated or the number of corroborates stances as independent_primaries. Pass the report URLs to /source-provenance instead. Never fill a missing provenance field with a guess. The per-source reliability letter and the occurrence credibility number are the platform's ratings of the outlet and the event. They are passed to /source-assessment as Admiralty-style ratings where that skill is used. They are never copied into an evidence grade: /quality-of-information-check grades each claim itself, in words (access level and claim support).

Alias resolution

/quality-of-information-check has to know that two vendors mean the same actor or malware before it can count them as corroborating each other. With a key, the Threat Library does the matching, and the evidence item records alias_source: liberty91.

python3 tools/clis/liberty91.py library threat-actors --alias "Sednit"
python3 tools/clis/liberty91.py library threat-actors --name "APT28"
python3 tools/clis/liberty91.py library malware --alias "X-Agent"

Two names match when both resolve to the same canonical id. Compare ids, not strings.

What the CLI can do today:

  • --alias is a case-insensitive exact match and --name matches the canonical name. Neither is fuzzy. Try the name as written, then --q for a substring, and treat a --q hit as a candidate to confirm on the record, not as a match.
  • Vendor-cluster merge records (a vendor's unnamed cluster, such as a UNC or Storm designation, later merged into a named group) are used when the library record returns them. The CLI has no dedicated command or flag for them today. If the older designation is listed as an alias on the canonical record, --alias finds it. If it is not, the names do not match.
  • clusters entries are account-local and have no canonical record, so they cannot match names across vendors.
  • No result means not matched. It does not mean the two are different actors. Corroboration for that claim stays at 1, unchecked.
  • The library endpoints need API v2.0 or later. When quota reports occurrence_layer_available: false, alias resolution is unavailable on that host.

Without a key, or when resolution is unavailable, QoI uses the user's own references/aliases.yml (alias_source: user) or matches no names (alias_source: none). Hash, CVE and infrastructure matching do not depend on aliases.

Response format

All commands return JSON on stdout:

source: liberty91
operation: threat-events | threat-event | library | entity | search | ioc-lookup | ingest | ...
query_time: <ISO8601>
# lists:
count: <n>
pages_walked: <n>
next: <complete URL or null>
truncated: true            # only when --max-pages stopped the walk
results: [...]
unlinked_report_count: <n> # search and alert-matches only
# ioc-lookup:
found: true|false
results: [...]
# _meta on every successful call:
_meta:
  rate_limit_remaining: <n>
  credits_remaining: <n>

Watch _meta.credits_remaining and surface it when it gets low. Reads cost 1 credit (2 for detail/search, 5 for STIX and downloads, 10 for IOC export and ingest, 25 for document upload, 50 per generated report). Failed requests are never charged.

Source reliability (Admiralty default)

Liberty91 emits Admiralty ratings natively — use the platform's own numbers rather than a default:

  • Occurrence carries per-source reliability and an occurrence credibility → pass both to /source-assessment verbatim
  • Occurrence unscored (credibility: null) → B6 — reliability from the source class, credibility cannot be judged
  • Nothing else available → B2 (the frontmatter default)
  • A report your own analysts ingested → A1; a report you ingested from a third party → rate the original author

When an occurrence rests on a single D/E-graded publisher, downgrade to that worst contributing source no matter how confident the summary reads.

These ratings apply to the occurrence and its outlets as lookup results. They are not evidence grades. Claims from the reports behind an occurrence are graded by /quality-of-information-check with access level and claim support, and neither is converted into the other.

Operational notes

  • A bad filter value is a 400, not an empty page. If a sector or country filter errors, it is a typo in your query — not absence of data. Read detail; it names the field.
  • 404 is also "not in your account". Tenancy is enforced by returning 404 rather than 403, so never report a 404 as "deleted" or "does not exist" — say "not visible to this account".
  • Visibility is per-report. You see an occurrence when you hold at least one of its reports, and report_count / source_count count only those. Never present them as the total volume of reporting in the world.
  • Your ingested reports are private and their IOCs are TLP:RED — check /tlp-guide before including them in anything shared.
  • Flat vs parented STIX. ioc-export --format stix is a context-free indicator list (blocklist). For a TIP, use --section iocs-export on an occurrence or entity — it carries the occurrence plus relationships to each indicator.
  • Clusters are account-local: the techniques, threat-events and related sections return 400 for them. The CLI refuses those combinations locally.
  • Enrichment and generation are asynchronous. ingest returns 202 — poll event <id> until enrichment_status is complete. report-generate queues — poll report <id> until status leaves GENERATING.
  • An empty alert-matches has historically meant nothing. Alert rules carrying a sector condition have never fired: the rule stored two-letter sector codes while events store display names, and the matcher compared them directly, so the condition was always false. The auto-created rule every new account receives is country AND sector, so that rule has never produced a single alert. v2.1 fixes the matcher. Until a host is on v2.1, never read "no alert matches" as "no matching activity", and after the upgrade expect a first-activation surge that reflects the backlog rather than a spike in threat activity. No customer needs to reconfigure anything: the rules were always right, the matcher was not.
  • Three scopes now gate the flagship detail call. threat-event <id> needs threat-events.read + orgs.read + events.read from v2.1, because the detail is a join across three resources: the occurrence, your organizations' relevance, and the reporting behind it. events.read is the new one, added because the embedded sources[] is the report layer, so withholding it previously bought nothing and only changed which URL the caller used. If you need the occurrence alone, use threat-events (the list), which still needs threat-events.read by itself.
  • alerts needs four scopes from v2.1: alerts.read + orgs.read + search.read + threats.read. The rule's criteria block returns suppliers and asset technologies (org resources), the effective query_tree (a search resource) and threat clusters (a threat-library resource), so the endpoint now requires the scope of everything it actually returns. A narrowly scoped key that worked before will get a 403 naming what is missing. Also from v2.1, criteria.query_tree always reflects what the rule really evaluates: for a rule configured only through the flat criteria fields it returns the tree those compile to, where it previously returned null. Treat query_tree as the authoritative statement of what a rule fires on.
  • The occurrence layer may not be deployed yet. API v2.0 introduced /threat-events/, /search/ and /threat-library/ (renaming the pre-2.0 /threats/); as of 31 July 2026 the production host still serves the pre-2.0 surface and those return 404. quota reports occurrence_layer_available: false when that is the case — fall back to events + iocs and say plainly that deduplication is unavailable rather than presenting report counts as occurrence counts.
  • v2.1 is documented here but is not live anywhere yet. Everything marked v2.1 above (25/100 page sizes, entity-bearing list rows, --section sources, the canonical search leaves, the widened scopes, the alert-matcher fix) sits on an unmerged branch, not yet on staging, and the production host is still behind even v2.0. Check /api/v1/schema/ for what a host actually serves before promising any of it to a user. The v1 contract only grows: no field has been renamed or removed, so ignore fields you do not recognise rather than treating them as errors.

Related skills

  • /ip-investigation, /domain-investigation, /hash-investigation, /url-investigation — chain ioc-lookup for first-party correlation
  • /ioc-enrichment-workflow — first-party check before third-party enrichment, and the write-back path afterwards
  • /threat-actor-profiling, /campaign-tracking — library + entity --section techniques|threat-events|related before rebuilding a profile from scratch
  • /vulnerability-intelligence — library vulnerabilities for CVE records with exploitation context
  • /lookup-misp, /lookup-opencti — the other two-way integrations; Liberty91 is the source, MISP the exchange layer, OpenCTI the internal graph
  • /stix-bundle — the bundle structure --section stix produces
  • /source-provenance — the fallback when provenance fields are absent or no key is configured; output is script-resolved
  • /quality-of-information-check — consumes provenance fields and alias resolution; grades per claim with the evidence grade (access level and claim support), never from the platform's reliability or credibility
  • /source-assessment, /confidence-levels, /tlp-guide — consume the platform's native ratings rather than inventing new ones
  • /intelligence-writing, /writing-assessments — turn occurrences into finished products

See also

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

同じリポジトリのスキル

概要と使いどころ

AbuseIPDB API reference. IP reputation and abuse report lookups.

日本語の概要は準備中です。原文の説明を表示しています。

Liberty91LTD/cti-skills272026年9月30日 更新

ach

無料

Analysis of Competing Hypotheses — structured technique for evaluating multiple explanations against evidence. Use when facing ambiguous attribution or multiple plausible scenarios. Prefers graded evidence items from /quality-of-information-check and runs that skill first when handed raw URLs or text. Runs on ungraded evidence when asked, labelled as such, unweighted, and capped at Moderate confidence.

日本語の概要は準備中です。原文の説明を表示しています。

Liberty91LTD/cti-skills272026年9月30日 更新

Use when documenting a named campaign across time and victims, the user asks to start or update a campaign record, or another skill identified a multi-incident cluster that warrants formal tracking. Provides the template (timeline, attribution, victimology, attack chain, Diamond Model mapping, IOC clusters) and the lifecycle from active to historical.

日本語の概要は準備中です。原文の説明を表示しています。

Liberty91LTD/cti-skills272026年9月30日 更新

Use when the user asks about carding, BIN attacks, payment-card breach markets, fullz/CVV2 trade, autoshops (BidenCash, Brian's Club, Russianmarket, B1ack's Stash), or financial-fraud TTPs. Self-updating knowledge cell.

日本語の概要は準備中です。原文の説明を表示しています。

Liberty91LTD/cti-skills272026年9月30日 更新

Censys API v2 reference. Host reconnaissance and certificate data.

日本語の概要は準備中です。原文の説明を表示しています。

Liberty91LTD/cti-skills272026年9月30日 更新

Use when the user asks about Chinese state-sponsored cyber operations or specific PRC-aligned actors (APT41, Volt Typhoon, Mustang Panda, APT10, APT31, Salt Typhoon, etc.), MSS/PLA-attributed campaigns, or PRC sector targeting. Self-updating knowledge cell.

日本語の概要は準備中です。原文の説明を表示しています。

Liberty91LTD/cti-skills272026年9月30日 更新

Liberty91LTD のスキルをすべて見る

このスキルの問題を報告する