main
py 324 lines 8.69 KB
Raw
1 import base64
2 import hashlib
3 import hmac
4 import uuid
5 from datetime import datetime
6 from datetime import timedelta
7 from enum import Enum
8 from typing import Dict
9 from typing import List
10 from typing import Optional
11
12 from pydantic import BaseModel
13 from pydantic import ConfigDict
14 from pydantic import Field
15 from pydantic import HttpUrl
16 from pydantic import model_validator
17
18
19 class PipelineRuleTitles(Enum):
20 WAZUH_INFO = "WAZUH CREATE FIELD SYSLOG LEVEL - INFO"
21 WAZUH_WARNING = "WAZUH CREATE FIELD SYSLOG LEVEL - WARNING"
22 WAZUH_NOTICE = "WAZUH CREATE FIELD SYSLOG LEVEL - NOTICE"
23 WAZUH_ALERT = "WAZUH CREATE FIELD SYSLOG LEVEL - ALERT"
24 OFFICE365_TIMESTAMP = "Office365 Timestamp - UTC"
25
26
27 class PipelineTitles(Enum):
28 OFFICE365 = "OFFICE365 PROCESSING PIPELINE"
29
30
31 class MimecastRequest(BaseModel):
32 customer_code: str = Field(
33 ...,
34 description="The customer code.",
35 examples=["00002"],
36 )
37 integration_name: str = Field(
38 "Mimecast",
39 description="The integration name.",
40 examples=["Mimecast"],
41 )
42 time_range: Optional[str] = Field(
43 "15m",
44 pattern="^[1-9][0-9]*[mhdw]$",
45 description="Time range for the query (1m, 1h, 1d, 1w)",
46 )
47
48
49 class MimecastResponse(BaseModel):
50 success: bool
51 message: str
52
53
54 class MimecastAuthKeys(BaseModel):
55 APP_ID: str = Field(
56 ...,
57 description="YOUR DEVELOPER APPLICATION ID",
58 examples=["00002"],
59 )
60 APP_KEY: str = Field(
61 ...,
62 description="YOUR DEVELOPER APPLICATION KEY",
63 examples=["00002"],
64 )
65 EMAIL_ADDRESS: Optional[str] = Field(
66 None,
67 description="EMAIL ADDRESS OF YOUR ADMINISTRATOR",
68 examples=["00002"],
69 )
70 ACCESS_KEY: str = Field(
71 ...,
72 description="ACCESS KEY FOR YOUR ADMINISTRATOR",
73 examples=["00002"],
74 )
75 SECRET_KEY: str = Field(
76 ...,
77 description="SECRET KEY FOR YOUR ADMINISTRATOR",
78 examples=["00002"],
79 )
80 URI: str = Field(
81 "/api/audit/get-siem-logs",
82 description="URI FOR YOUR API Endpoint",
83 examples=["/api/audit/get-siem-logs"],
84 )
85
86
87 class APIEndpointRegion(BaseModel):
88 code: str
89 api: HttpUrl
90 mpp: HttpUrl
91 adminConsole: HttpUrl
92 name: str
93
94
95 class APIEndpointDataItem(BaseModel):
96 emailAddress: str
97 emailToken: str
98 authenticate: List
99 region: APIEndpointRegion
100
101
102 class APIEndpointMeta(BaseModel):
103 status: int
104
105
106 class APIEndpointData(BaseModel):
107 meta: APIEndpointMeta
108 data: List[APIEndpointDataItem]
109 fail: List
110
111
112 class MimecastAPIEndpointResponse(BaseModel):
113 data: APIEndpointData
114 success: bool
115 message: str
116
117
118 class MimecastScheduledResponse(BaseModel):
119 success: bool
120 message: str
121
122
123 # ! MIMECAST TTP URLS ! #
124 class MimecastHeaders(BaseModel):
125 Authorization: str = Field(
126 ...,
127 description="The Authorization header typically containing the access token.",
128 )
129 x_mc_app_id: str = Field(
130 ...,
131 alias="x-mc-app-id",
132 description="The Application ID for Mimecast.",
133 )
134 x_mc_date: str = Field(
135 ...,
136 alias="x-mc-date",
137 description="The date when the request was made.",
138 )
139 x_mc_req_id: str = Field(
140 ...,
141 alias="x-mc-req-id",
142 description="The unique request ID.",
143 )
144 Content_Type: str = Field(
145 ...,
146 alias="Content-Type",
147 description="The type of content, usually application/json.",
148 )
149 model_config = ConfigDict(populate_by_name=True)
150
151
152 class MimecastTTPURLSRequest(BaseModel):
153 ApplicationID: str = Field(..., description="The ID of the Mimecast application.")
154 ApplicationKey: str = Field(
155 ...,
156 description="The key associated with the Mimecast application.",
157 )
158 AccessKey: str = Field(..., description="The access key for API authentication.")
159 SecretKey: str = Field(..., description="The secret key for API authentication.")
160 EmailAddress: str = Field(
161 ...,
162 description="The email address of the Mimecast administrator.",
163 )
164 BaseURL: Optional[str] = Field(
165 None,
166 description="The base URL for the Mimecast API.",
167 )
168 time_range: Optional[str] = Field(
169 "15m",
170 pattern="^[1-9][0-9]*[mhdw]$",
171 description="Time range for the query (1m, 1h, 1d, 1w)",
172 )
173 # headers: Dict[str, str] = Field(default_factory=dict) # default empty dictionary
174 headers: Optional[MimecastHeaders] = Field(
175 None,
176 description="The headers generated for the request.",
177 )
178 pagination_token: str = Field(None, description="Pagination token for API calls")
179
180 lower_bound: str = None
181 upper_bound: str = None
182
183 def __init__(self, *args, **kwargs):
184 super().__init__(*args, **kwargs)
185 self.generate_headers("/api/ttp/url/get-logs") # default URI
186
187 @model_validator(mode="before")
188 @classmethod
189 def set_time_bounds(cls, values):
190 time_range = values.get("time_range")
191 if time_range:
192 unit = time_range[-1]
193 amount = int(time_range[:-1])
194
195 now = datetime.utcnow()
196
197 if unit == "m":
198 lower_bound = now - timedelta(minutes=amount)
199 elif unit == "h":
200 lower_bound = now - timedelta(hours=amount)
201 elif unit == "d":
202 lower_bound = now - timedelta(days=amount)
203 elif unit == "w":
204 lower_bound = now - timedelta(weeks=amount)
205
206 values["lower_bound"] = lower_bound.strftime("%Y-%m-%dT%H:%M:%S.%f")[:-3] + "Z"
207 values["upper_bound"] = now.strftime("%Y-%m-%dT%H:%M:%S.%f")[:-3] + "Z"
208 return values
209
210 def generate_headers(self, uri: str) -> dict:
211 """Generate Mimecast request headers."""
212
213 request_id = str(uuid.uuid4())
214 hdr_date = datetime.utcnow().strftime("%a, %d %b %Y %H:%M:%S") + " UTC"
215
216 dataToSign = ":".join([hdr_date, request_id, uri, self.ApplicationKey])
217
218 hmac_sha1 = hmac.new(
219 base64.b64decode(self.SecretKey),
220 dataToSign.encode(),
221 digestmod=hashlib.sha1,
222 ).digest()
223 sig = base64.b64encode(hmac_sha1).rstrip()
224
225 headers_dict = {
226 "Authorization": "MC " + self.AccessKey + ":" + sig.decode(),
227 "x-mc-app-id": self.ApplicationID,
228 "x-mc-date": hdr_date,
229 "x-mc-req-id": request_id,
230 "Content-Type": "application/json",
231 }
232
233 self.headers = MimecastHeaders(
234 **headers_dict,
235 ) # Create a new instance of MimecastHeaders and assign
236
237 return headers_dict
238
239
240 ##### ! SENDING REQUEST TO MIMECAST ! #####
241 class DataItem(BaseModel):
242 oldestFirst: bool = Field(..., description="Ordering flag, oldest first if true.")
243 from_: datetime = Field(
244 ...,
245 alias="from",
246 description="Start date-time in ISO 8601 format.",
247 )
248 to: datetime = Field(..., description="End date-time in ISO 8601 format.")
249 route: str = Field(..., description="Routing information.")
250 scanResult: str = Field(..., description="Scan result.")
251 model_config = ConfigDict(populate_by_name=True)
252
253
254 class RequestBody(BaseModel):
255 meta: Dict = Field({}, description="Meta information.")
256 data: List[DataItem] = Field(..., description="List of data items.")
257
258
259 class TTPResponseClickLogs(BaseModel):
260 userEmailAddress: str
261 fromUserEmailAddress: str
262 url: str
263 ttpDefinition: str
264 subject: str
265 action: str
266 adminOverride: str
267 userOverride: str
268 scanResult: str
269 category: str
270 sendingIp: str
271 userAwarenessAction: str
272 date: str
273 actions: str
274 route: str
275 creationMethod: str
276 emailPartsDescription: List[str]
277 messageId: str
278
279
280 class TTPResponseDataItem(BaseModel):
281 clickLogs: List[TTPResponseClickLogs]
282
283
284 class TTPResponsePagination(BaseModel):
285 pageSize: int
286 totalCount: int
287 next: Optional[str] = None
288
289
290 class ResponseMeta(BaseModel):
291 pagination: TTPResponsePagination
292 status: int
293
294
295 class TtpURLResponseBody(BaseModel):
296 meta: ResponseMeta
297 data: List[TTPResponseDataItem]
298 fail: List[Dict] # Adjust this based on the actual structure of the "fail" field
299
300
301 class ResponseAttachmentLogs(BaseModel):
302 senderAddress: str
303 recipientAddress: str
304 fileName: str
305 fileType: str
306 result: str
307 actionTriggered: str
308 date: str
309 details: str
310 route: str
311 messageId: str
312 subject: str
313 fileHash: str
314 definition: str
315
316
317 class ResponseDataItemAttachment(BaseModel):
318 attachmentLogs: List[ResponseAttachmentLogs]
319
320
321 class TtpURLAttachmentResponseBody(BaseModel):
322 meta: ResponseMeta
323 data: List[ResponseDataItemAttachment]
324 fail: List[Dict] # Adjust this based on the actual structure of the "fail" field