From eb8d116e27e1aeb527f2f066691c214f0ee1a67d Mon Sep 17 00:00:00 2001 From: rookit Date: Thu, 14 May 2026 17:25:49 +0800 Subject: [PATCH] update SKILL --- .../skills/asp-module-creator-en/SKILL.md | 56 ++++++++++-------- .../skills/asp-module-creator-zh/SKILL.md | 57 +++++++++++-------- 2 files changed, 65 insertions(+), 48 deletions(-) diff --git a/PLUGINS/ClaudeCode/skills/asp-module-creator-en/SKILL.md b/PLUGINS/ClaudeCode/skills/asp-module-creator-en/SKILL.md index 930a8d6..8731965 100644 --- a/PLUGINS/ClaudeCode/skills/asp-module-creator-en/SKILL.md +++ b/PLUGINS/ClaudeCode/skills/asp-module-creator-en/SKILL.md @@ -29,7 +29,7 @@ Use this skill to guide the user through the full workflow — from requirement - Before writing code, read `PLUGINS/SIRP/sirpcoremodel.py`; enum values must come only from the actual definitions in that file, never from memory or inference. - All modules must inherit `BaseModule` and implement the `run()` method. - SIRP data hierarchy: `Case → Alert → Artifact` (three-tier). Artifact is the smallest atomic investigation entity (an IP, a username); Alerts are attached to Cases; related alerts are aggregated into the same Case via `correlation_uid`. Enrichment is a cross-cutting attachment layer independent of the three-tier hierarchy — it can be attached to any level (Case / Alert / Artifact). -- Reference implementation: `MODULES/Cloud-01-AWS-IAM-Privilege-Escalation-via-AttachUserPolicy.py`. +- Reference implementation: `MODULES/Cloud-01-AWS-IAM-Privilege-Escalation-via-AttachUserPolicy.py`, which demonstrates the current recommended pattern for consuming raw_alerts, extracting Artifacts, assembling Alert/Case records, deduplicating appended alerts, and requesting case analysis scheduling. - Data model reference: `PLUGINS/SIRP/sirpcoremodel.py`. ## Decision Flow @@ -101,7 +101,7 @@ Before determining `correlation_uid`, first identify what kind of SOC scenario t - User-reported phishing mail: prefer sender/sender domain. If the email title does not contain random values such as recipient names, timestamps, or order numbers, include a normalized title. Usually do not include recipient. Recommended window: `12h`, which keeps one phishing wave together without delaying notifications and response too much. - Same malicious URL/domain delivery: use URL domain or normalized URL + sender domain. If the URL contains one-time tokens, use only the domain or stable path. - Malicious process/command on endpoint: use host + stable process/command signature. If it looks like lateral movement or a hash-wide outbreak, aggregate by file hash/command signature and do not necessarily include host. -- Cloud IAM abnormal operation: usually use cloud account/tenant + principal identity + API/target resource. If investigating one broad attack wave, aggregate by principal identity or source IP and keep target resources as supporting context. +- Cloud IAM abnormal operation: usually use cloud account/tenant + principal identity + API/target resource. If investigating one broad attack wave, aggregate by principal identity or source IP and keep target resources as supporting context. For high-risk permission changes such as `AttachUserPolicy`, if a Case represents "the same principal granting high-risk permissions to the same target user", use `account_id + principal_user/principal_id + target_user`; do not include fields such as `policyArn`, `requestID`, or `eventID` when they would fragment one activity or add little aggregation value. - C2 communication: use C2 IP/domain + internal host. If one C2 affects many hosts, aggregate by C2 first and keep affected hosts in the Case. **Time-window guidance:** @@ -180,28 +180,31 @@ class Module(BaseModule): self.logger.info(f"Alert created: {saved_alert_row_id}") # 7. Case management - try: - existing_case = Case.get_by_correlation_uid(correlation_uid, lazy_load=True) - if existing_case: - update_case = CaseModel( - alerts=[*existing_case.alerts, saved_alert_row_id], - row_id=existing_case.row_id - ) - Case.update(update_case) - else: - new_case = CaseModel( - title=..., - severity=..., - impact=..., - priority=..., - confidence=Confidence.HIGH, - description=..., - correlation_uid=correlation_uid, - alerts=[saved_alert_row_id] - ) - Case.create(new_case) - except Exception as e: - self.logger.error(f"Case operation failed: {str(e)}") + existing_case = Case.get_by_correlation_uid(correlation_uid, lazy_load=True) + if existing_case: + existing_case_row_id = existing_case.row_id + assert existing_case_row_id is not None + existing_alerts = existing_case.alerts or [] + updated_alerts = existing_alerts if saved_alert_row_id in existing_alerts else [*existing_alerts, saved_alert_row_id] + update_case = CaseModel( + alerts=updated_alerts, + row_id=existing_case_row_id + ) + Case.update(update_case) + Case.mark_analysis_requested(row_id=existing_case_row_id, cooldown_minutes=3) + else: + new_case = CaseModel( + title=..., + severity=..., + impact=..., + priority=..., + confidence=Confidence.HIGH, + description=..., + correlation_uid=correlation_uid, + alerts=[saved_alert_row_id] + ) + created_case_row_id = Case.create(new_case) + Case.mark_analysis_requested(row_id=created_case_row_id, cooldown_minutes=3) return True ``` @@ -215,7 +218,12 @@ Field mapping principles: - AlertModel field population priority: ① map directly from the raw alert; ② derive via calculation or transformation from raw alert fields; ③ use a sensible default only when both previous steps fail. - MITRE ATT&CK fields (`tactic`, `technique`, `sub_technique`) should be hardcoded based on the alert type. - `Alert.create(alert_model)` automatically cascade-creates artifact records, writes the resulting row_id list back to `AlertModel.artifacts`, and then creates the alert record — attach artifacts to `alert_model`, do not call `Artifact.create` separately. +- Artifact selection principles: prefer stable, reusable, investigable entities; when deciding whether a field should become an Artifact, focus on whether it helps cross-alert correlation, investigation, evidence collection, or automated response. +- Avoid single-event random identifiers as Artifacts, such as request_id, event_id, trace_id, session_id, and uuid, unless the rule specifically investigates those IDs. +- Prefer preserving original, complete, stable entity values instead of only storing over-trimmed or overly generic derived values; derived values often fit better in Alert labels, descriptions, or unmapped data. +- ArtifactRole should describe the entity's relationship to the event: initiators are usually `ACTOR`, operated objects are usually `TARGET`, affected assets/environments are usually `AFFECTED`, and contextual entities are usually `RELATED` or `OTHER`. - If fields in `unmapped` (or other high-value fields) need structured storage, create an `EnrichmentModel` record and attach it to the `enrichments` field of ArtifactModel / AlertModel / CaseModel. +- Use Enrichment only for supplementary information that is useful for investigation but does not fit core Alert/Case/Artifact fields. Do not convert every unmapped field into an Enrichment; keep it in `unmapped` by default and create Enrichment only when structured display or automation consumption is needed. - For threat intelligence or Owner attribution on an entity, prefer storing directly in the corresponding `ArtifactModel` fields (`owner`, `reputation_score`, `reputation_provider`); create an EnrichmentModel and attach it to ArtifactModel only when richer structured content is needed. ### Step 6 — Add the Debug Entry Point diff --git a/PLUGINS/ClaudeCode/skills/asp-module-creator-zh/SKILL.md b/PLUGINS/ClaudeCode/skills/asp-module-creator-zh/SKILL.md index cc9f3b9..67407f1 100644 --- a/PLUGINS/ClaudeCode/skills/asp-module-creator-zh/SKILL.md +++ b/PLUGINS/ClaudeCode/skills/asp-module-creator-zh/SKILL.md @@ -31,7 +31,7 @@ metadata: - SIRP 数据层级:`Case → Alert → Artifact`(三级体系)。Artifact 是调查的最小原子实体(一个 IP、一个用户名),应尽量从 raw_alert 中提取;Alert 挂在 Case 下;同类告警通过 `correlation_uid` 聚合到同一个 Case。Enrichment 是独立于三级体系之外的横切附加层,可按需挂载到 Case / Alert / Artifact 任意一级。 -- 参考实现:`MODULES/Cloud-01-AWS-IAM-Privilege-Escalation-via-AttachUserPolicy.py`。 +- 参考实现:`MODULES/Cloud-01-AWS-IAM-Privilege-Escalation-via-AttachUserPolicy.py`,体现当前推荐的 raw_alert 消费、Artifact 提取、Alert/Case 组装、Case 去重追加和分析调度调用方式。 - 数据模型参考:`PLUGINS/SIRP/sirpcoremodel.py`。 ## 决策流程 @@ -113,7 +113,8 @@ metadata: - 同一恶意 URL/域名投递:用 URL 域名或归一化 URL + 发件域;如果 URL 中包含一次性 token,应只取域名或稳定路径。 - 主机恶意进程/命令:用主机 + 进程名/命令行稳定特征;如果判断为横向传播或同一 hash 大范围爆发,可用文件 hash/命令特征,不一定加入主机。 - 云 IAM 异常操作:通常用云账号/租户 + 主体身份 + API/目标资源;如果关注一次大范围攻击,可按主体身份或源 IP - 聚合,再用目标资源作为辅助信息。 + 聚合,再用目标资源作为辅助信息。例如 `AttachUserPolicy` 这类高危权限变更,如果 Case 表示"同一主体对同一目标用户的高危授权活动",可使用 + `account_id + principal_user/principal_id + target_user`;不要加入 `policyArn`、`requestID`、`eventID` 这类会拆散同一活动或缺乏聚合价值的字段。 - C2 通信:用目标 C2 IP/域名 + 内部主机;如果同一 C2 影响多台主机,允许按 C2 先聚合,再在 Case 中保留受影响主机列表。 **时间窗口参考:** @@ -194,28 +195,31 @@ class Module(BaseModule): self.logger.info(f"Alert created: {saved_alert_row_id}") # 7. Case 处理 - try: - existing_case = Case.get_by_correlation_uid(correlation_uid, lazy_load=True) - if existing_case: - update_case = CaseModel( - alerts=[*existing_case.alerts, saved_alert_row_id], - row_id=existing_case.row_id - ) - Case.update(update_case) - else: - new_case = CaseModel( - title=..., - severity=..., - impact=..., - priority=..., - confidence=Confidence.HIGH, - description=..., - correlation_uid=correlation_uid, - alerts=[saved_alert_row_id] - ) - Case.create(new_case) - except Exception as e: - self.logger.error(f"Case operation failed: {str(e)}") + existing_case = Case.get_by_correlation_uid(correlation_uid, lazy_load=True) + if existing_case: + existing_case_row_id = existing_case.row_id + assert existing_case_row_id is not None + existing_alerts = existing_case.alerts or [] + updated_alerts = existing_alerts if saved_alert_row_id in existing_alerts else [*existing_alerts, saved_alert_row_id] + update_case = CaseModel( + alerts=updated_alerts, + row_id=existing_case_row_id + ) + Case.update(update_case) + Case.mark_analysis_requested(row_id=existing_case_row_id, cooldown_minutes=3) + else: + new_case = CaseModel( + title=..., + severity=..., + impact=..., + priority=..., + confidence=Confidence.HIGH, + description=..., + correlation_uid=correlation_uid, + alerts=[saved_alert_row_id] + ) + created_case_row_id = Case.create(new_case) + Case.mark_analysis_requested(row_id=created_case_row_id, cooldown_minutes=3) return True ``` @@ -232,8 +236,13 @@ class Module(BaseModule): - MITRE ATT&CK 字段(`tactic`、`technique`、`sub_technique`)根据告警类型硬编码。 - `Alert.create(alert_model)` 会自动级联创建 artifacts 记录,并将生成的 row_id 列表回写到 AlertModel.artifacts,再创建 alert 记录——因此 artifacts 应挂载到 alert_model 上,不要单独调用 Artifact.create。 +- Artifact 选择原则:优先选择稳定、可复用、可调查的实体;判断一个字段是否适合作为 Artifact 时,重点看它能否帮助跨告警关联、调查取证或自动化处置。 +- 避免把单事件随机标识作为 Artifact,例如 request_id、event_id、trace_id、session_id、uuid 等;除非该 rule 的调查目标就是这些 ID。 +- 优先保留原始、完整、稳定的实体值,避免只保存过度裁剪或泛化后的派生值;派生值更适合放在 Alert label、描述或 unmapped 中。 +- ArtifactRole 应表达实体在事件中的关系:行为发起方通常为 `ACTOR`,被操作对象通常为 `TARGET`,受影响资产/环境通常为 `AFFECTED`,仅提供上下文的信息通常为 `RELATED` 或 `OTHER`。 - 如果 unmapped 中有特殊价值的字段需要结构化存储,可创建 `EnrichmentModel` 记录并挂载到 ArtifactModel / AlertModel / CaseModel 的 enrichments 字段。 +- Enrichment 只用于补充对调查有帮助但不适合作为核心 Alert/Case/Artifact 字段的信息。不要把所有 unmapped 字段都转成 Enrichment;默认先放入 `unmapped`,只有需要结构化展示或后续自动化消费时再创建 Enrichment。 - 针对实体的威胁情报信息或 Owner 归属,优先直接存储到 `ArtifactModel` 的对应字段(如 `owner`、`reputation_score`、 `reputation_provider`);若需要更丰富的结构化内容,再创建 EnrichmentModel 挂载到 ArtifactModel。