Spaces:
Running
Running
""" | |
MITRE ATT&CK Navigator JSON Schema | |
""" | |
from pydantic import BaseModel, Field, validator, StringConstraints | |
from typing import Optional, Dict, Any, List, Annotated | |
import re | |
from datetime import datetime | |
# カスタム型の定義 | |
TechniqueID = Annotated[str, StringConstraints(pattern=r'^T\d{4}(\.\d{3})?$')] | |
TacticName = Annotated[str, StringConstraints(pattern=r'^[a-z-]+$')] | |
HexColor = Annotated[str, StringConstraints(pattern=r'^#[0-9A-Fa-f]{6}$')] | |
Domain = Annotated[str, StringConstraints(pattern=r'^(enterprise-attack|mobile-attack|ics-attack)$')] | |
class Technique(BaseModel): | |
"""Technique model for ATT&CK Navigator""" | |
techniqueID: TechniqueID = Field(description="The MITRE ATT&CK technique ID (e.g., T1234 or T1234.001)") | |
tactic: Optional[TacticName] = Field(description="The tactic this technique belongs to (lowercase with hyphens)") | |
score: Optional[int] = Field(description="Score between 0 and 100", ge=0, le=100) | |
color: Optional[HexColor] = Field(description="Hex color code (e.g., #FF0000)") | |
comment: Optional[str] = Field(description="Comment about the technique", max_length=1000) | |
enabled: Optional[bool] = Field(description="Whether the technique is enabled", default=True) | |
metadata: Optional[List[Dict[str, str]]] = Field(description="Additional metadata") | |
links: Optional[List[Dict[str, str]]] = Field(description="Related links") | |
showSubtechniques: Optional[bool] = Field(description="Whether to show subtechniques", default=True) | |
def validate_links(cls, v): | |
if v is not None: | |
for link in v: | |
if not all(k in link for k in ['label', 'url']): | |
raise ValueError("Each link must have 'label' and 'url' fields") | |
return v | |
class VersionInfo(BaseModel): | |
"""バージョン情報のサブスキーマ""" | |
attack: str = Field( | |
..., | |
description="""ATT&CKのバージョン。ユーザーが指定したバージョンを使用すること。 | |
例: ユーザーが「ATT&CKバージョンは16で」と指定した場合、"16"と設定する。 | |
指定がない場合は、DEFAULT_LAYER_SETTINGSの値を使用する。""" | |
) | |
navigator: str = Field( | |
..., | |
description="""Navigatorのバージョン。ユーザーが指定したバージョンを使用すること。 | |
指定がない場合は、DEFAULT_LAYER_SETTINGSの値を使用する。""" | |
) | |
layer: str = Field( | |
..., | |
description="""レイヤーのバージョン。ユーザーが指定したバージョンを使用すること。 | |
指定がない場合は、DEFAULT_LAYER_SETTINGSの値を使用する。""" | |
) | |
class AttackLayer(BaseModel): | |
"""MITRE ATT&CK Navigator Layer""" | |
name: str = Field(..., description="レイヤーの名前") | |
description: str = Field(..., description="レイヤーの説明") | |
domain: Domain = Field(..., description="ATT&CKドメイン") | |
versions: VersionInfo = Field(..., description="バージョン情報") | |
filters: Dict[str, Any] = Field( | |
default_factory=lambda: { | |
"platforms": [ | |
"Windows", | |
"Linux", | |
"macOS", | |
"Containers", | |
"IaaS", | |
"Network" | |
] | |
}, | |
description="フィルター設定" | |
) | |
sorting: int = Field(default=0, description="ソート順") | |
layout: Dict[str, Any] = Field( | |
default_factory=lambda: { | |
"layout": "side", | |
"showName": True, | |
"showID": False, | |
"showAggregateScores": True, | |
"countUnscored": True, | |
"aggregateFunction": "average" | |
}, | |
description="レイアウト設定" | |
) | |
hideDisabled: bool = Field(default=False, description="無効なテクニックを非表示") | |
techniques: List[Technique] = Field(..., description="テクニックのリスト") | |
gradient: Dict[str, Any] = Field( | |
default_factory=lambda: { | |
"colors": ["#ff6666", "#ffe766", "#8ec843"], | |
"minValue": 0, | |
"maxValue": 100 | |
}, | |
description="スコアのグラデーション設定" | |
) | |
legendItems: List[Dict[str, Any]] = Field( | |
default_factory=list, | |
description="凡例アイテム" | |
) | |
showTacticRowBackground: bool = Field(default=False, description="タクティック行の背景を表示") | |
tacticRowBackground: str = Field(default="#dddddd", description="タクティック行の背景色") | |
selectTechniquesAcrossTactics: bool = Field(default=True, description="タクティック間でテクニックを選択") | |
selectSubtechniquesWithParent: bool = Field(default=False, description="サブテクニックを親と共に選択") | |
selectVisibleTechniques: bool = Field(default=False, description="表示されているテクニックのみを選択") | |
metadata: List[Dict[str, str]] = Field( | |
default_factory=lambda: [ | |
{"name": "作成者", "value": "AIアシスタント"}, | |
{"name": "作成日", "value": datetime.now().strftime("%Y-%m-%d")} | |
], | |
description="メタデータ" | |
) | |
# デフォルトのレイヤー設定 | |
DEFAULT_LAYER_SETTINGS = { | |
"versions": { | |
"attack": "16.1", | |
"navigator": "5.1.0", | |
"layer": "4.5" | |
}, | |
"layout": { | |
"layout": "side", | |
"showName": True, | |
"showID": False, | |
"showAggregateScores": True, | |
"countUnscored": True, | |
"aggregateFunction": "average" | |
}, | |
"gradient": { | |
"colors": ["#ff6666", "#ffe766", "#8ec843"], | |
"minValue": 0, | |
"maxValue": 100 | |
} | |
} | |
# プロンプトテンプレート | |
ATTACK_PROMPT = """ | |
あなたはMITRE ATT&CKフレームワークの専門家です。 | |
以下のシナリオに基づいて、MITRE ATT&CK NavigatorのレイヤーJSONを生成してください。 | |
回答形式: | |
{format_instructions} | |
注意: | |
- 有効なMITRE ATT&CKテクニックIDを使用すること | |
- 適切なタクティクスを含めること | |
- スコアは0-100の範囲で設定すること | |
- 有効な16進数カラーコードを使用すること | |
- 意味のあるコメントを含めること | |
- 適切なメタデータを設定すること | |
""" |