main
py 295 lines 9.63 KB
Raw
1 from typing import Any
2 from typing import Dict
3 from typing import List
4 from typing import Optional
5
6 from pydantic import BaseModel
7 from pydantic import ConfigDict
8 from pydantic import Field
9
10
11 class MitreTacticItem(BaseModel):
12 """Represents a single MITRE ATT&CK tactic from Wazuh's API."""
13
14 description: str
15 name: str
16 id: str
17 modified_time: str
18 created_time: str
19 short_name: str
20 techniques: List[str]
21 references: List[str] = []
22 url: str
23 source: str
24 external_id: str
25
26
27 class MitreFailedItem(BaseModel):
28 """Represents a failed item in the Wazuh API response."""
29
30 error: Dict[str, Any]
31 id: str
32
33
34 class MitreResponseData(BaseModel):
35 """Represents the data section of the Wazuh MITRE response."""
36
37 affected_items: List[MitreTacticItem]
38 total_affected_items: int
39 total_failed_items: int
40 failed_items: List[MitreFailedItem] = []
41
42
43 class MitreAPIResponse(BaseModel):
44 """Base response model for Wazuh API responses related to MITRE data."""
45
46 data: MitreResponseData
47 message: str
48 error: int
49
50
51 # Response models for API endpoints
52 class WazuhMitreTacticsResponse(BaseModel):
53 """Response model for the MITRE tactics endpoint."""
54
55 success: bool
56 message: str
57 results: List[MitreTacticItem] = []
58
59
60 # First, add a model for references
61 class MitreReference(BaseModel):
62 """Represents a reference in MITRE ATT&CK data."""
63
64 url: str
65 description: Optional[str] = None
66 source: str
67
68
69 # Then update the MitreTechniqueItem model
70 class MitreTechniqueItem(BaseModel):
71 """Represents a single MITRE ATT&CK technique from Wazuh's API."""
72
73 description: str
74 name: str
75 id: str
76 modified_time: str
77 created_time: str
78 tactics: List[str]
79 url: str
80 source: str
81 external_id: str
82
83 # Fields that might have different structure
84 references: List[MitreReference] = []
85 mitigations: Optional[List[str]] = None
86 subtechnique_of: Optional[str] = None
87
88 # Optional fields from the API response
89 techniques: Optional[List[str]] = None # For sub-techniques
90 groups: Optional[List[str]] = []
91 software: Optional[List[str]] = []
92 mitre_detection: Optional[str] = None
93 mitre_version: Optional[str] = None
94 deprecated: Optional[int] = 0
95 remote_support: Optional[int] = 0
96 network_requirements: Optional[int] = 0
97
98 # Fields that we standardize in our model but might not be in the response
99 platforms: List[str] = []
100 data_sources: List[str] = []
101 is_subtechnique: bool = False
102 model_config = ConfigDict(extra="ignore")
103
104
105 class WazuhMitreTechniquesResponse(BaseModel):
106 """Response model for the MITRE techniques endpoint."""
107
108 success: bool
109 message: str
110 results: List[MitreTechniqueItem] = []
111
112
113 class AtomicRedTeamMarkdownResponse(BaseModel):
114 """Response model for Atomic Red Team markdown content."""
115
116 success: bool
117 message: str
118 technique_id: str
119 markdown_content: Optional[str] = None
120
121
122 class AtomicTestSummary(BaseModel):
123 """Summary information about an Atomic Red Team test."""
124
125 technique_id: str = Field(..., description="MITRE ATT&CK technique ID")
126 technique_name: str = Field(..., description="MITRE ATT&CK technique name")
127 test_count: int = Field(..., description="Number of atomic tests available for this technique")
128 categories: List[str] = Field(default_factory=list, description="Categories/platforms the tests cover")
129 has_prerequisites: bool = Field(False, description="Whether the tests have prerequisites")
130
131
132 class AtomicTestsListResponse(BaseModel):
133 """Response model for listing all available Atomic Red Team tests."""
134
135 success: bool = Field(True, description="Whether the request was successful")
136 message: str = Field(..., description="Response message")
137 total_techniques: int = Field(..., description="Total number of techniques with atomic tests")
138 total_tests: Optional[int] = Field(None, description="Total number of individual atomic tests")
139 tests: List[AtomicTestSummary] = Field(..., description="List of techniques with atomic tests")
140 last_updated: str = Field(..., description="When the test information was last updated")
141 page: int = Field(1, description="Current page number")
142 page_size: int = Field(..., description="Number of items per page")
143 total_pages: int = Field(..., description="Total number of pages available")
144
145
146 class MitreTechniqueInAlert(BaseModel):
147 """Schema for a MITRE technique found in alerts."""
148
149 technique_id: str = Field(..., description="MITRE ATT&CK technique ID")
150 technique_name: str = Field(..., description="MITRE ATT&CK technique name")
151 count: int = Field(..., description="Number of alerts containing this technique")
152 last_seen: Optional[str] = Field(None, description="Last time this technique was seen in an alert")
153 tactics: List[Dict[str, str]] = Field(default_factory=list, description="Associated tactics for this technique")
154
155
156 class MitreTechniquesInAlertsResponse(BaseModel):
157 """Response schema for MITRE techniques found in alerts."""
158
159 success: bool = Field(True, description="Whether the request was successful")
160 message: str = Field(..., description="Description of the response")
161 total_alerts: int = Field(..., description="Total number of alerts matching the query")
162 techniques_count: int = Field(..., description="Number of unique techniques found")
163 techniques: List[MitreTechniqueInAlert] = Field(..., description="List of techniques with counts")
164 time_range: str = Field(..., description="Time range used for the search")
165 field_used: Optional[str] = Field(..., description="Field name used to extract MITRE techniques")
166 page: int = Field(1, description="Current page number")
167 page_size: int = Field(..., description="Number of items per page")
168 total_pages: int = Field(..., description="Total number of pages available")
169
170
171 class MitreTechniqueAlertsResponse(BaseModel):
172 """Response schema for detailed alerts associated with a specific MITRE technique."""
173
174 success: bool = Field(True, description="Whether the request was successful")
175 message: str = Field(..., description="Description of the response")
176 technique_id: str = Field(..., description="The MITRE technique ID that was searched for")
177 technique_name: str = Field(..., description="The name of the MITRE technique")
178 total_alerts: int = Field(..., description="Total number of alerts found")
179 alerts: List[Dict] = Field(..., description="List of alert documents")
180 field_used: Optional[str] = Field(..., description="Field name used to search for MITRE techniques")
181 time_range: str = Field(..., description="Time range used for the search")
182 page: int = Field(1, description="Current page number")
183 page_size: int = Field(..., description="Number of items per page")
184 total_pages: int = Field(..., description="Total number of pages available")
185
186
187 class MitreSoftwareItem(BaseModel):
188 """Represents a single MITRE ATT&CK software from Wazuh's API."""
189
190 mitre_version: Optional[str] = None
191 deprecated: int = 0
192 description: str
193 name: str
194 id: str
195 modified_time: str
196 created_time: str
197 groups: List[str] = []
198 techniques: List[str] = []
199 references: List[MitreReference] = []
200 url: str
201 source: str
202 external_id: str
203
204 # Additional fields that might be present
205 platforms: Optional[List[str]] = None
206 aliases: Optional[List[str]] = None
207 type: Optional[str] = None # For distinguishing between malware, tool, etc.
208 model_config = ConfigDict(extra="ignore")
209
210
211 class WazuhMitreSoftwareResponse(BaseModel):
212 """Response model for the MITRE software endpoint."""
213
214 success: bool
215 message: str
216 results: List[MitreSoftwareItem] = []
217
218
219 class MitreReferenceItem(BaseModel):
220 """Represents a single MITRE ATT&CK reference from Wazuh's API."""
221
222 url: str
223 description: Optional[str] = None
224 source: str
225 id: Optional[str] = None # ID of the related technique, tactic, or software
226 type: Optional[str] = None # Type of the item the reference belongs to (technique, tactic, etc.)
227 model_config = ConfigDict(extra="ignore")
228
229
230 class WazuhMitreReferencesResponse(BaseModel):
231 """Response model for the MITRE references endpoint."""
232
233 success: bool
234 message: str
235 results: List[MitreReferenceItem] = []
236 total: int = 0
237
238
239 class MitreMitigationItem(BaseModel):
240 """Represents a single MITRE ATT&CK mitigation from Wazuh's API."""
241
242 mitre_version: Optional[str] = None
243 deprecated: int = 0
244 description: str
245 name: str
246 id: str
247 modified_time: str
248 created_time: str
249 techniques: List[str] = []
250 references: List[MitreReference] = []
251 url: str
252 source: str
253 external_id: str
254 model_config = ConfigDict(extra="ignore")
255
256
257 class WazuhMitreMitigationsResponse(BaseModel):
258 """Response model for the MITRE mitigations endpoint."""
259
260 success: bool
261 message: str
262 results: List[MitreMitigationItem] = []
263 total: int = 0
264
265
266 class MitreGroupItem(BaseModel):
267 """Represents a single MITRE ATT&CK group from Wazuh's API."""
268
269 mitre_version: Optional[str] = None
270 deprecated: int = 0
271 description: Optional[str] = None
272 name: str
273 id: str
274 modified_time: str
275 created_time: str
276 software: List[str] = []
277 techniques: List[str] = []
278 references: List[MitreReference] = []
279 url: str
280 external_id: str
281 source: str
282
283 # Additional fields that might be present
284 aliases: Optional[List[str]] = None
285 country: Optional[str] = None
286 model_config = ConfigDict(extra="ignore")
287
288
289 class WazuhMitreGroupsResponse(BaseModel):
290 """Response model for the MITRE groups endpoint."""
291
292 success: bool
293 message: str
294 results: List[MitreGroupItem] = []
295 total: int = 0