mirror of
https://github.com/FunnyWolf/agentic-soc-platform.git
synced 2026-08-22 13:12:56 +02:00
update attack stage
This commit is contained in:
@@ -9,7 +9,7 @@ from Lib.baseplaybook import LanggraphPlaybook
|
||||
from Lib.llmapi import BaseAgentState
|
||||
from PLUGINS.LLM.llmapi import LLMAPI
|
||||
from PLUGINS.SIRP.sirpapi import Case
|
||||
from PLUGINS.SIRP.sirpmodel import PlaybookJobStatus, PlaybookModel, CaseModel
|
||||
from PLUGINS.SIRP.sirpmodel import PlaybookJobStatus, PlaybookModel, CaseModel, AttackStage
|
||||
from PLUGINS.SIRP.sirpmodel import Severity, Confidence
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ class AnalyzeResult(BaseModel):
|
||||
new_severity: Severity = Field(description="Recommended new severity level")
|
||||
confidence: Confidence = Field(description="Confidence score, only one of 'Low', 'Medium', or 'High'")
|
||||
analysis_rationale: str | None = Field(description="Analysis process and reasons", default=None)
|
||||
attack_stage: str | dict[str, Any] | None = Field(description="e.g., 'T1059 - Command and Control', 'Lateral Movement'", default=None)
|
||||
attack_stage: AttackStage = Field(description="e.g. 'Lateral Movement'", default=None)
|
||||
recommended_actions: str | dict[str, Any] | None = Field(description="e.g., 'Isolate host 10.1.1.5'", default=None)
|
||||
|
||||
|
||||
@@ -81,9 +81,9 @@ class Playbook(LanggraphPlaybook):
|
||||
case_new = CaseModel(rowid=self.param_source_rowid,
|
||||
severity_ai=analyze_result.new_severity,
|
||||
confidence_ai=analyze_result.confidence,
|
||||
analysis_rationale_ai=analyze_result.analysis_rationale,
|
||||
comment_ai=analyze_result.analysis_rationale,
|
||||
attack_stage_ai=analyze_result.attack_stage,
|
||||
recommended_actions_ai=analyze_result.recommended_actions,
|
||||
summary_ai=analyze_result.recommended_actions,
|
||||
)
|
||||
Case.update(case_new)
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ from Lib.baseplaybook import LanggraphPlaybook
|
||||
from Lib.llmapi import BaseAgentState
|
||||
from PLUGINS.LLM.llmapi import LLMAPI
|
||||
from PLUGINS.SIRP.sirpapi import Case
|
||||
from PLUGINS.SIRP.sirpmodel import PlaybookJobStatus, CaseModel, PlaybookModel
|
||||
from PLUGINS.SIRP.sirpmodel import PlaybookJobStatus, CaseModel, PlaybookModel, AttackStage
|
||||
from PLUGINS.SIRP.sirpmodel import Severity, Confidence
|
||||
|
||||
|
||||
@@ -51,9 +51,9 @@ class AnalyzeResult(BaseModel):
|
||||
default=None,
|
||||
description="详细推理过程.需包含识别到的新证据、新旧告警关联逻辑以及搜索工具返回的情报如何辅助了判断."
|
||||
)
|
||||
attack_stage: str | None = Field(
|
||||
attack_stage: AttackStage | None = Field(
|
||||
default=None,
|
||||
description="参考 MITRE ATT&CK 战术名称,必须是字符串(如:'T1059 - Command and Control', 'Lateral Movement')."
|
||||
description="MITRE ATT&CK 战术名称(如:'Lateral Movement')."
|
||||
)
|
||||
recommended_actions: str | None = Field(
|
||||
default=None,
|
||||
@@ -151,9 +151,9 @@ class Playbook(LanggraphPlaybook):
|
||||
case_new = CaseModel(rowid=self.param_source_rowid,
|
||||
severity_ai=analyze_result.new_severity,
|
||||
confidence_ai=analyze_result.confidence,
|
||||
analysis_rationale_ai=analyze_result.analysis_rationale,
|
||||
comment_ai=analyze_result.analysis_rationale,
|
||||
attack_stage_ai=analyze_result.attack_stage,
|
||||
recommended_actions_ai=analyze_result.recommended_actions,
|
||||
summary_ai=analyze_result.recommended_actions,
|
||||
)
|
||||
Case.update(case_new)
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@ Ask the user which operation they want to perform:
|
||||
- Total count
|
||||
- For each key alert: title, severity, status, source UID, correlation UID, first seen time, last seen time
|
||||
|
||||
**Associated Artifacts**
|
||||
**Associated Artifacts for each alert**
|
||||
|
||||
- Total count
|
||||
- For each key artifact: name, value, type, role, reputation score
|
||||
@@ -108,6 +108,7 @@ Total: [count] cases
|
||||
Risk, Managed Externally, Duplicate, Other
|
||||
- `severity_ai` - AI-assessed severity
|
||||
- `confidence_ai` - Unknown, Low, Medium, High, Other
|
||||
- `attack_stage_ai` - MITRE ATT&CK tactics
|
||||
- `comment_ai` - Markdown content (use #### as top-level heading)
|
||||
- `summary_ai` - Markdown content (use #### as top-level heading)
|
||||
|
||||
|
||||
@@ -30,7 +30,8 @@ This skill currently focuses on `siem_keyword_search`. More SIEM operations can
|
||||
|
||||
**Required parameters:**
|
||||
|
||||
- `keyword` - Search keyword or keyword list. Can be an IP address, hostname, username, email, hash, process name, domain, or any string. If a list is provided, all keywords are matched with AND semantics
|
||||
- `keyword` - Search keyword or keyword list. Can be an IP address, hostname, username, email, hash, process name,
|
||||
domain, or any string. If a list is provided, all keywords are matched with AND semantics
|
||||
- `time_range_start` - Start time in UTC ISO8601 format, for example `2026-02-04T06:00:00Z`
|
||||
- `time_range_end` - End time in UTC ISO8601 format, for example `2026-02-04T07:00:00Z`
|
||||
|
||||
@@ -48,11 +49,13 @@ This skill currently focuses on `siem_keyword_search`. More SIEM operations can
|
||||
3. If the target source uses a non-default time field, collect `time_field`; otherwise use `@timestamp`
|
||||
4. Use MCP tool `siem_keyword_search` with the collected parameters
|
||||
5. Check the returned `status` for each result group
|
||||
6. If the result is too large, reduce the time range or add more precise keywords so the query moves from `summary` or `sample` toward `full`
|
||||
6. If the result is too large, reduce the time range or add more precise keywords so the query moves from `summary` or
|
||||
`sample` toward `full`
|
||||
7. If the result is empty or too narrow, expand the time range or remove restrictive keywords
|
||||
8. Continue iterating until `full` is reached when the goal is to retrieve the complete original raw logs
|
||||
9. Parse each returned JSON string
|
||||
10. If the result list is empty after reasonable refinement, state that no matching logs were found in the specified time range
|
||||
10. If the result list is empty after reasonable refinement, state that no matching logs were found in the specified
|
||||
time range
|
||||
11. Present results grouped by backend and index when multiple results are returned
|
||||
|
||||
**Behavior notes:**
|
||||
@@ -64,7 +67,8 @@ This skill currently focuses on `siem_keyword_search`. More SIEM operations can
|
||||
- `sample` - statistics plus representative sample records for medium result sets
|
||||
- `summary` - statistics only for large result sets
|
||||
- Use time range changes together with keyword changes to control result volume and converge on `full`
|
||||
- The preferred end state for evidence collection is `full`, because it contains the complete original raw logs returned by the backend
|
||||
- The preferred end state for evidence collection is `full`, because it contains the complete original raw logs returned
|
||||
by the backend
|
||||
- Time values must be UTC and end with `Z`
|
||||
|
||||
**Refinement guidance:**
|
||||
@@ -118,4 +122,5 @@ Then provide statistics and sample records under each result group.
|
||||
2. Collect required parameters for the chosen operation
|
||||
3. Execute the appropriate MCP tool
|
||||
4. Format and present the results according to the operation's output specification
|
||||
5. Handle errors gracefully, such as invalid UTC time format, unsupported index, backend connection issues, or no matching logs
|
||||
5. Handle errors gracefully, such as invalid UTC time format, unsupported index, backend connection issues, or no
|
||||
matching logs
|
||||
|
||||
+17
-13
@@ -5,7 +5,7 @@ from PLUGINS.SIEM.models import KeywordSearchInput
|
||||
from PLUGINS.SIEM.tools import SIEMToolKit
|
||||
from PLUGINS.SIRP.nocolymodel import Group, Condition, Operator
|
||||
from PLUGINS.SIRP.sirpapi import Case
|
||||
from PLUGINS.SIRP.sirpmodel import CaseModel, Severity, CaseStatus, CaseVerdict, Confidence
|
||||
from PLUGINS.SIRP.sirpmodel import CaseModel, Severity, CaseStatus, CaseVerdict, Confidence, AttackStage
|
||||
|
||||
|
||||
def get_case(
|
||||
@@ -22,6 +22,7 @@ def get_case(
|
||||
def list_cases(
|
||||
status: Annotated[Optional[list[CaseStatus]], "Filter by case status or a list of case statuses"] = None,
|
||||
severity: Annotated[Optional[list[Severity]], "Filter by severity level or a list of severity levels"] = None,
|
||||
confidence: Annotated[Optional[list[Confidence]], "Filter by severity level or a list of severity levels"] = None,
|
||||
limit: Annotated[int, "Maximum number of results to return"] = 10
|
||||
) -> Annotated[list[str], "Security cases matching the filters"]:
|
||||
"""List security cases with optional filters."""
|
||||
@@ -29,9 +30,10 @@ def list_cases(
|
||||
|
||||
if status:
|
||||
conditions.append(Condition(field="status", operator=Operator.IN, value=status))
|
||||
|
||||
if severity:
|
||||
conditions.append(Condition(field="severity", operator=Operator.IN, value=severity))
|
||||
if confidence:
|
||||
conditions.append(Condition(field="confidence", operator=Operator.IN, value=confidence))
|
||||
|
||||
filter_model = Group(logic="AND", children=conditions) if conditions else Group(logic="AND", children=[])
|
||||
|
||||
@@ -44,11 +46,12 @@ def list_cases(
|
||||
|
||||
def update_case(
|
||||
case_id: Annotated[str, "Case ID to update"],
|
||||
severity: Annotated[Optional[str], "New severity"] = None,
|
||||
status: Annotated[Optional[str], "New status"] = None,
|
||||
verdict: Annotated[Optional[str], "New verdict"] = None,
|
||||
severity_ai: Annotated[Optional[str], "New AI-assessed severity"] = None,
|
||||
confidence_ai: Annotated[Optional[str], "New AI-assessed confidence"] = None,
|
||||
severity: Annotated[Optional[Severity], "New severity"] = None,
|
||||
status: Annotated[Optional[CaseStatus], "New status"] = None,
|
||||
verdict: Annotated[Optional[CaseVerdict], "New verdict"] = None,
|
||||
severity_ai: Annotated[Optional[Severity], "New AI-assessed severity"] = None,
|
||||
confidence_ai: Annotated[Optional[Confidence], "New AI-assessed confidence"] = None,
|
||||
attack_stage_ai: Annotated[Optional[AttackStage], "New AI-attack stage"] = None,
|
||||
comment_ai: Annotated[Optional[
|
||||
str], "New AI-comment. Supports Markdown format."] = None,
|
||||
summary_ai: Annotated[Optional[
|
||||
@@ -62,16 +65,17 @@ def update_case(
|
||||
case_new = CaseModel()
|
||||
case_new.rowid = case_old.rowid
|
||||
if severity:
|
||||
case_new.severity = Severity(severity)
|
||||
case_new.severity = severity
|
||||
if status:
|
||||
case_new.status = CaseStatus(status)
|
||||
case_new.status = status
|
||||
if verdict:
|
||||
case_new.verdict = CaseVerdict(verdict)
|
||||
case_new.verdict = verdict
|
||||
if severity_ai:
|
||||
case_new.severity_ai = Severity(severity_ai)
|
||||
case_new.severity_ai = severity_ai
|
||||
if confidence_ai:
|
||||
case_new.confidence_ai = Confidence(confidence_ai)
|
||||
|
||||
case_new.confidence_ai = confidence_ai
|
||||
if attack_stage_ai:
|
||||
case_new.attack_stage_ai = attack_stage_ai
|
||||
if comment_ai:
|
||||
case_new.comment_ai = comment_ai
|
||||
if summary_ai:
|
||||
|
||||
@@ -138,6 +138,23 @@ class Severity(StrEnum):
|
||||
OTHER = "Other"
|
||||
|
||||
|
||||
class AttackStage(StrEnum):
|
||||
RECONNAISSANCE = "Reconnaissance"
|
||||
RESOURCE_DEVELOPMENT = "Resource Development"
|
||||
INITIAL_ACCESS = "Initial Access"
|
||||
EXECUTION = "Execution"
|
||||
PERSISTENCE = "Persistence"
|
||||
PRIVILEGE_ESCALATION = "Privilege Escalation"
|
||||
DEFENSE_EVASION = "Defense Evasion"
|
||||
CREDENTIAL_ACCESS = "Credential Access"
|
||||
DISCOVERY = "Discovery"
|
||||
LATERAL_MOVEMENT = "Lateral Movement"
|
||||
COLLECTION = "Collection"
|
||||
COMMAND_AND_CONTROL = "Command and Control"
|
||||
EXFILTRATION = "Exfiltration"
|
||||
IMPACT = "Impact"
|
||||
|
||||
|
||||
class ImpactLevel(StrEnum):
|
||||
UNKNOWN = "Unknown"
|
||||
LOW = "Low"
|
||||
@@ -697,7 +714,7 @@ class CaseModel(BaseSystemModel):
|
||||
workbook: Optional[str] = Field(default="", description="事件调查使用的工作簿或调查手册内容")
|
||||
|
||||
# ai 字段
|
||||
attack_stage_ai: Optional[str] = Field(default="", description="AI评估的攻击阶段")
|
||||
attack_stage_ai: Optional[AttackStage] = Field(default="", description="AI评估的攻击阶段")
|
||||
severity_ai: Optional[Severity] = Field(default=None,
|
||||
description="AI评估的事件严重性")
|
||||
confidence_ai: Optional[Confidence] = Field(default=None, description="AI评估的事件置信度")
|
||||
|
||||
Reference in New Issue
Block a user