with one click
unknown-threat-hunting
// 当用户提供已知威胁实体、报告标题、IOC、攻击模式或漏洞编号,并希望基于关联图谱扩展发现潜在同源团伙、共享基础设施、可疑攻击链或未知威胁候选时触发此技能。
// 当用户提供已知威胁实体、报告标题、IOC、攻击模式或漏洞编号,并希望基于关联图谱扩展发现潜在同源团伙、共享基础设施、可疑攻击链或未知威胁候选时触发此技能。
[HINT] Download the complete skill directory including SKILL.md and all related files
| name | unknown-threat-hunting |
| description | 当用户提供已知威胁实体、报告标题、IOC、攻击模式或漏洞编号,并希望基于关联图谱扩展发现潜在同源团伙、共享基础设施、可疑攻击链或未知威胁候选时触发此技能。 |
当用户有以下任一意图时触发本技能:
本技能只使用 opencti 数据源进行只读分析,不跨入车辆侧组件、TARA 风险或 SES 需求分析。
优先从用户输入提取以下槽位:
entry_type: 允许值为 report_title、actor_name、intrusion_set_name、malware_name、tool_name、indicator_or_infrastructure、attack_pattern_name、cve。entry_value: 与入口类型对应的实际值。time_range: 可选增强条件。若用户提供,则用于缩小查询范围;否则不是硬性前置条件。hunting_goal: 默认值为 expand_unknown_candidates。提取与追问规则:
在执行查询前,先声明以下规则:
ai4x_query。catalog,再读取目标源 schema;若 sourceId="opencti",只将 schema 作为最小目录,并在需要具体字段时追加 detail,之后再 query。Facts 与 Inferences。先调用:
ai4x_query(command="catalog")
检查目录中是否存在 sourceId="opencti"。
如果不存在:
Gaps 中输出缺失数据源。在构造任何 Cypher 前,必须调用:
ai4x_query(command="schema", sourceId="opencti")
ai4x_query(command="detail", sourceId="opencti", detailKind="object|relationship-type|relationship-schema", typeName="...")
重点确认是否可消费以下对象:
reportintrusion-setthreat-actorcampaignmalwaretoolindicatorinfrastructureattack-patternvulnerabilityidentityrelationship如果 Schema 中缺失某条计划中的对象链路,则在 Gaps 中注明并跳过相关扩展分支。
所有入口等价,按 entry_type 选择对应分支。先定位直接命中的对象,再从该对象向外扩展。
ai4x_query(
command="query",
sourceId="opencti",
cypher="MATCH (r {type: 'report'}) WHERE toLower(coalesce(r.name, '')) CONTAINS toLower($entry_value) OPTIONAL MATCH (r)-[rel]-(m) RETURN r, rel, m"
)
ai4x_query(
command="query",
sourceId="opencti",
cypher="MATCH (n) WHERE n.type IN ['intrusion-set','threat-actor'] AND toLower(coalesce(n.name, '')) CONTAINS toLower($entry_value) OPTIONAL MATCH (n)-[rel]-(m) RETURN n, rel, m"
)
ai4x_query(
command="query",
sourceId="opencti",
cypher="MATCH (n) WHERE n.type IN ['malware','tool','attack-pattern','indicator','infrastructure'] AND toLower(coalesce(n.name, '')) CONTAINS toLower($entry_value) OPTIONAL MATCH (n)-[rel]-(m) RETURN n, rel, m"
)
ai4x_query(
command="query",
sourceId="opencti",
cypher="MATCH (v {type: 'vulnerability'}) WHERE toLower(coalesce(v.name, '')) CONTAINS toLower($entry_value) OPTIONAL MATCH (v)-[rel]-(m) RETURN v, rel, m"
)
入口判定规则:
report,优先围绕其邻接对象扩展。report、intrusion-set 或 campaign。本技能的主查询链为:
report -> related objects -> shared infrastructure / attack-pattern先围绕入口对象扩展以下事实对象:
infrastructureindicatorattack-patternmalwaretoolcampaignintrusion-setthreat-actoridentityvulnerability推荐主链查询模板:
ai4x_query(
command="query",
sourceId="opencti",
cypher="MATCH (seed) WHERE toLower(coalesce(seed.name, '')) CONTAINS toLower($entry_value) OPTIONAL MATCH path1=(seed)-[*1..2]-(infra {type: 'infrastructure'}) OPTIONAL MATCH path2=(seed)-[*1..2]-(ap {type: 'attack-pattern'}) OPTIONAL MATCH path3=(seed)-[*1..2]-(mw) WHERE mw.type IN ['malware','tool'] OPTIONAL MATCH path4=(seed)-[*1..2]-(grp) WHERE grp.type IN ['intrusion-set','threat-actor','campaign'] RETURN seed, path1, infra, path2, ap, path3, mw, path4, grp"
)
事实抽取要求:
sourceId=opencti。path 中未显式暴露的关系含义,只能原样引用底层返回结果,不得自行升格为确定归因语言。目标是寻找与已知入口共享关键对象的其他组织类候选。候选对象类型允许为:
intrusion-setthreat-actorcampaign搜索策略:
infrastructure 或共享 indicator 的其他候选。允许作为第二条辅助证据的对象或关系:
attack-patternmalware / toolindicatorreport 邻接关系vulnerabilityidentity / campaign候选搜索查询示例:
ai4x_query(
command="query",
sourceId="opencti",
cypher="MATCH (seed) WHERE toLower(coalesce(seed.name, '')) CONTAINS toLower($entry_value) MATCH (seed)-[*1..2]-(shared) WHERE shared.type IN ['infrastructure','indicator'] MATCH (candidate)-[*1..2]-(shared) WHERE candidate.type IN ['intrusion-set','threat-actor','campaign'] AND candidate.id <> seed.id OPTIONAL MATCH (seed)-[*1..2]-(aux) WHERE aux.type IN ['attack-pattern','malware','tool','indicator','vulnerability','identity','campaign','report'] OPTIONAL MATCH (candidate)-[*1..2]-(aux) RETURN seed, shared, candidate, collect(DISTINCT aux) AS shared_auxiliary_evidence"
)
候选输出门槛:
infrastructure 或 1 个 indicator。Unknown Candidates,而应进入 Exclusions。只保留以下内容:
report、infrastructure、indicator、attack-pattern、malware、tool、campaign、intrusion-set、threat-actor、identity、vulnerability。只允许输出以下类型的推断:
禁止输出:
必须列出搜索过但未达到候选门槛的对象,并说明原因,例如:
建议必须聚焦于进一步验证未知候选,而不是直接给出确定结论。可包含:
当前 opencti 聚合 Schema 可支撑基本的图谱关联猎杀,但若要更稳定地做未知威胁发现,建议增强如下:
attack-pattern 增加更稳定的外部标识和 kill chain phase 字段,以便区别“共享对象”与“共享阶段语义”。indicator 与 infrastructure 增加统一的时效字段和状态字段,避免历史失效对象对当前猎杀造成误导。report 与 campaign 增加更规范的引用来源、时间范围和置信度字段,支持按时间窗和证据新鲜度筛选候选。最终输出必须采用以下 Markdown 结构:
## Facts
- Entry Anchor:
- sourceId: opencti
- object: [入口对象]
- Shared Evidence:
- [对象A(type)] --[relationship]--> [共享对象(type)]
- Candidate Links:
- [共享对象(type)] --[relationship]--> [候选对象(type)]
## Unknown Candidates
- [候选对象名称]
- confidence: high|medium|low
- supporting_facts:
- [共享基础设施或 indicator]
- [第二条辅助证据]
- inference: [只允许写“可能同源”或“值得进一步追查”]
- review_required: yes
## Exclusions
- [对象名称]
- reason: [为什么未达到候选门槛]
## Gaps
- Missing Sources:
- [缺失 sourceId,若无则写 none]
- Unresolved Links:
- [路径不稳定、语义不清或未命中的链路]
## Recommendations
- Next Validation Steps:
- [进一步验证建议]
## Empty Result Contract
- query_status: empty|partial|complete
- retained_facts:
- [若有已命中事实则列出,否则为空数组]
- empty_segments:
- [未命中的入口或扩展链路]
- next_questions:
- [建议用户补充的对象名、报告标题、IOC 或时间范围]
输出约束:
high、medium、low 三档,依据证据覆盖度给出。Unknown Candidates 仅包含满足门槛的候选。Exclusions 必须存在,只要检索过程中出现证据不足的对象就要列出。当用户提出下列意图之一时触发本技能:
intrusion-set 为起点,查询其相关恶意软件、IOC、基础设施和潜在共用关系。本技能当前只依赖 opencti 这一 sourceId 作为最小闭环数据源;其他车辆域数据源不作为本场景的前置依赖。
执行前必须从用户输入中提取或确认以下槽位:
hunt_seed_type:优先支持 intrusion-set;若用户给的是恶意软件、基础设施或 IOC,先归一化为可查询的猎杀种子。hunt_seed_value:例如 APT29、WellMess、某个域名、某个 IP 或某个文件哈希。max_first_hop:第一阶段图谱展开上限,默认建议 25。max_second_hop:第二阶段共享线索回溯上限,默认建议 25。time_window:如用户要求限定 first_seen / last_seen 时间窗时使用;否则不强加时间过滤。report_goal:例如“发现共享基础设施”“找到可落地排查的 IOC”“形成猎杀报告”。如果缺少 hunt_seed_value,必须先向用户请求补充。若 catalog 或 schema 步骤确认 opencti 不存在或缺失关键对象类型,则停止查询并输出结构化空结果。若 hunt_seed_type 未明确,则默认优先按 intrusion-set 解释,并在输出中说明归一化假设。
先验证目标数据源是否可用,严格使用唯一工具 ai4x_query:
{
"command": "catalog"
}
判定规则:
sourceId=opencti。status=empty、missing_source=["opencti"],禁止继续猜测或编造。在任何真实查询前,读取 opencti 的 Schema:
{
"command": "schema",
"sourceId": "opencti"
}
必须从 Schema 中确认以下对象类型或字段可用后再构造 Cypher:
intrusion-setmalwareindicatorinfrastructurerelationship(至少含 source_ref、target_ref、relationship_type)domain-name、ipv4-addr、filesighting、observed-dataSchema 审核要求:
relationship.source_ref / relationship.target_ref 的显式连接方式。relationship 字段为准。如果 Schema 未暴露某类对象或字段,只能降级流程或在输出中标记 data_gap,禁止擅自假设字段存在。
以 intrusion-set 为主路径,先获取第一层和第二层事实实体,形成“组织 -> 恶意软件/基础设施/指标 -> IOC 候选”的证据图。查询前再次确认 Cypher 只使用 Schema 已暴露的对象类型和字段。
建议查询示例:
{
"command": "query",
"sourceId": "opencti",
"cypher": "MATCH (seed:`intrusion-set`) WHERE seed.name = $hunt_seed_value OR $hunt_seed_value IN coalesce(seed.aliases, []) MATCH (rel1:relationship) WHERE rel1.source_ref = seed.id OR rel1.target_ref = seed.id MATCH (neighbor) WHERE ((rel1.source_ref = seed.id AND rel1.target_ref = neighbor.id) OR (rel1.target_ref = seed.id AND rel1.source_ref = neighbor.id)) AND any(label IN labels(neighbor) WHERE label IN ['malware', 'indicator', 'infrastructure', 'campaign', 'tool']) OPTIONAL MATCH (rel2:relationship) WHERE rel2.source_ref = neighbor.id OR rel2.target_ref = neighbor.id OPTIONAL MATCH (pivot) WHERE ((rel2.source_ref = neighbor.id AND rel2.target_ref = pivot.id) OR (rel2.target_ref = neighbor.id AND rel2.source_ref = pivot.id)) AND any(label IN labels(pivot) WHERE label IN ['indicator', 'infrastructure', 'domain-name', 'ipv4-addr', 'file']) RETURN seed.id AS seed_id, seed.name AS seed_name, collect(DISTINCT {relationship_type: rel1.relationship_type, entity_id: neighbor.id, entity_labels: labels(neighbor), entity_name: coalesce(neighbor.name, neighbor.value, neighbor.pattern, 'unknown')})[..$max_first_hop] AS first_hop_facts, collect(DISTINCT {via_entity_id: neighbor.id, relationship_type: rel2.relationship_type, pivot_id: pivot.id, pivot_labels: labels(pivot), pivot_value: coalesce(pivot.name, pivot.value, pivot.pattern, 'unknown')})[..$max_first_hop] AS pivot_candidates"
}
执行要求:
intrusion-set,仅在 Schema 已确认相应对象类型可用时改写 MATCH 起点。indicator.pattern 但没有显式 observable 对象,不要把模式文本解析结果写成事实实体;只能标记为“可进一步解析的 IOC 模式”。first_hop_facts 与 pivot_candidates 全为空,返回结构化空结果并结束流程。对 Phase A 产出的 pivot_candidates 做第二次只读回溯,寻找与这些 IOC/基础设施共享的其他组织、恶意软件或基础设施,形成“未知威胁猎杀”的候选线索。
建议查询示例:
{
"command": "query",
"sourceId": "opencti",
"cypher": "UNWIND $pivot_ids AS pivot_id MATCH (pivot) WHERE pivot.id = pivot_id MATCH (rel:relationship) WHERE rel.source_ref = pivot.id OR rel.target_ref = pivot.id MATCH (other) WHERE ((rel.source_ref = pivot.id AND rel.target_ref = other.id) OR (rel.target_ref = pivot.id AND rel.source_ref = other.id)) AND any(label IN labels(other) WHERE label IN ['intrusion-set', 'malware', 'infrastructure', 'indicator']) WITH pivot, rel, other WHERE NOT ('intrusion-set' IN labels(other) AND other.name = $hunt_seed_value) RETURN collect(DISTINCT {pivot_id: pivot.id, pivot_labels: labels(pivot), pivot_value: coalesce(pivot.name, pivot.value, pivot.pattern, 'unknown'), relationship_type: rel.relationship_type, related_id: other.id, related_labels: labels(other), related_value: coalesce(other.name, other.value, other.pattern, 'unknown')})[..$max_second_hop] AS shared_leads"
}
执行要求:
shared_leads 作为候选线索,不直接宣称“同一组织共用基础设施”已经被证实。Inference 中描述“可能共用基础设施”“可能存在共同投递链”之类的推断。建议证据路径表达:
intrusion-set(APT29) -> relationship -> malware(WellMess) -> relationship -> indicator(...)intrusion-set(APT29) -> relationship -> infrastructure(shared-domain) <- relationship <- intrusion-set(DarkHotel)如果 opencti 最小目录或对应 detail schema 明确显示 sighting 与 observed-data,可对高价值 indicator 或 infrastructure 追加一次验证查询,用于区分“纯情报线索”和“已在环境中被观测的线索”。
建议查询示例:
{
"command": "query",
"sourceId": "opencti",
"cypher": "UNWIND $candidate_indicator_ids AS indicator_id MATCH (indicator:indicator {id: indicator_id}) MATCH (s:sighting {sighting_of_ref: indicator.id}) OPTIONAL MATCH (obs:`observed-data`) WHERE any(ref IN coalesce(s.observed_data_refs, []) WHERE ref = obs.id) RETURN collect(DISTINCT {indicator_id: indicator.id, sighting_id: s.id, first_seen: s.first_seen, last_seen: s.last_seen, observed_data_id: obs.id, observed_first_seen: obs.first_observed, observed_last_seen: obs.last_observed}) AS environment_hits"
}
如果 Schema 未暴露 observed_data_refs 或相关对象,则跳过本步骤,并在结果中明确写入 environment_validation: not_available。
整理输出时必须遵守:
Fact 只包含查询直接返回的对象、字段、关系链和计数。Inference 只包含基于 Fact 的图谱推断,并注明触发该推断的证据路径。统一返回 Markdown + JSON 双层结构,且必须显式分离 Fact 与 Inference。
必需字段清单:request_id、hunt_seed、evidence_paths、derived_leads、confidence_statement、recommended_actions。
Markdown 结构:
## Hunt Summary
- Hunt Seed: <hunt_seed_value>
- Status: success | empty | partial
- Report Goal: <report_goal>
## Fact
- Direct entities: ...
- Direct relationships: ...
- Evidence paths: ...
## Inference
- Derived leads: ...
- Confidence statement: ...
## Gaps
- Missing sources / fields / schema limits: ...
## Recommended Actions
- Next investigation steps: ...
JSON 结构:
{
"request_id": "string",
"hunt_seed": {
"type": "intrusion-set",
"value": "APT29"
},
"report_goal": "identify shared infrastructure",
"status": "success",
"facts": {
"direct_entities": [],
"direct_relationships": [],
"evidence_paths": []
},
"inference": {
"derived_leads": [],
"confidence_statement": "string"
},
"environment_validation": {
"status": "available_or_not_available",
"hits": []
},
"data_gaps": [],
"recommended_actions": []
}
空结果时必须返回:
status: "empty"facts.direct_entities: []facts.direct_relationships: []inference.derived_leads: []recommended_actions 仅包含后续补充数据或调整猎杀假设的建议