main
py 313 lines 14.8 KB
Raw
1 from fastapi import APIRouter
2 from fastapi import Depends
3 from fastapi import Security
4 from loguru import logger
5 from sqlalchemy.ext.asyncio import AsyncSession
6
7 from app.auth.routes.auth import AuthHandler
8 from app.db.db_session import get_db
9 from app.integrations.modules.schema.sap_siem import CollectSapSiemRequest
10 from app.integrations.modules.schema.sap_siem import CustomerDetails
11 from app.integrations.modules.schema.sap_siem import InvokeSapSiemAnalysis
12 from app.integrations.modules.schema.sap_siem import InvokeSapSiemRequest
13 from app.integrations.modules.schema.sap_siem import InvokeSAPSiemResponse
14 from app.integrations.modules.schema.sap_siem import SapSiemAuthKeys
15 from app.integrations.modules.services.sap_siem.collect import (
16 post_to_copilot_sap_module_brute_force_failed_logins_multiple_ips,
17 )
18 from app.integrations.modules.services.sap_siem.collect import (
19 post_to_copilot_sap_module_brute_force_failed_logins_same_ip,
20 )
21 from app.integrations.modules.services.sap_siem.collect import (
22 post_to_copilot_sap_module_collect,
23 )
24 from app.integrations.modules.services.sap_siem.collect import (
25 post_to_copilot_sap_module_same_user_failed_login_from_different_geo_location,
26 )
27 from app.integrations.modules.services.sap_siem.collect import (
28 post_to_copilot_sap_module_same_user_failed_login_from_different_ip,
29 )
30 from app.integrations.modules.services.sap_siem.collect import (
31 post_to_copilot_sap_module_same_user_successful_login_from_different_geo_location,
32 )
33 from app.integrations.modules.services.sap_siem.collect import (
34 post_to_copilot_sap_module_sap_siem_successful_user_login_with_different_ip,
35 )
36 from app.integrations.modules.services.sap_siem.collect import (
37 post_to_copilot_sap_module_successful_login_after_multiple_failed_logins,
38 )
39 from app.integrations.routes import find_customer_integration
40 from app.integrations.utils.utils import extract_auth_keys
41 from app.integrations.utils.utils import get_customer_integration_response
42 from app.utils import get_customer_meta_attribute
43
44 module_sap_siem_router = APIRouter()
45
46
47 @module_sap_siem_router.post(
48 "",
49 response_model=InvokeSAPSiemResponse,
50 description="Pull down SAP SIEM Events.",
51 dependencies=[Security(AuthHandler().require_any_scope("admin", "analyst"))],
52 )
53 async def collect_sap_siem_route(sap_siem_request: InvokeSapSiemRequest, session: AsyncSession = Depends(get_db)):
54 """Pull down SAP SIEM Events."""
55 customer_integration_response = await get_customer_integration_response(
56 sap_siem_request.customer_code,
57 session,
58 )
59
60 customer_integration = await find_customer_integration(
61 sap_siem_request.customer_code,
62 sap_siem_request.integration_name,
63 customer_integration_response,
64 )
65
66 sap_siem_auth_keys = extract_auth_keys(customer_integration, service_name="SAP SIEM")
67
68 logger.info(f"SAP SIEM Auth Keys: {sap_siem_auth_keys}")
69
70 auth_keys = SapSiemAuthKeys(**sap_siem_auth_keys)
71 # if multiple apiKey values are present, make a loop to iterate through them
72 # and collect the data for each apiKey
73 if "," in auth_keys.API_KEY:
74 api_keys = auth_keys.API_KEY.split(",")
75 for key in api_keys:
76 await post_to_copilot_sap_module_collect(
77 data=CollectSapSiemRequest(
78 auth_keys=SapSiemAuthKeys(
79 API_KEY=key,
80 SECRET_KEY=auth_keys.SECRET_KEY,
81 USER_KEY=auth_keys.USER_KEY,
82 API_DOMAIN=auth_keys.API_DOMAIN,
83 ),
84 customer_code=sap_siem_request.customer_code,
85 integration_name=sap_siem_request.integration_name,
86 threshold=sap_siem_request.threshold,
87 time_range=sap_siem_request.time_range,
88 customer_details=CustomerDetails(
89 customer_code=sap_siem_request.customer_code,
90 iris_customer_id=(
91 await get_customer_meta_attribute(
92 customer_code=sap_siem_request.customer_code,
93 column_name="customer_meta_iris_customer_id",
94 session=session,
95 )
96 ),
97 ),
98 ),
99 )
100 else:
101 await post_to_copilot_sap_module_collect(
102 data=InvokeSapSiemRequest(
103 auth_keys=SapSiemAuthKeys(
104 API_KEY=auth_keys.API_KEY,
105 SECRET_KEY=auth_keys.SECRET_KEY,
106 USER_KEY=auth_keys.USER_KEY,
107 API_DOMAIN=auth_keys.API_DOMAIN,
108 ),
109 customer_code=sap_siem_request.customer_code,
110 integration_name=sap_siem_request.integration_name,
111 threshold=sap_siem_request.threshold,
112 time_range=sap_siem_request.time_range,
113 customer_details=CustomerDetails(
114 customer_code=sap_siem_request.customer_code,
115 iris_customer_id=(await get_customer_meta_attribute(sap_siem_request.customer_code, "customer_meta_iris_customer_id")),
116 ),
117 ),
118 )
119
120 return InvokeSAPSiemResponse(success=True, message="SAP SIEM Events collected successfully.")
121
122
123 @module_sap_siem_router.post(
124 "/successful_user_login_with_different_ip",
125 response_model=InvokeSAPSiemResponse,
126 description="Rule: Successful user login after using different IP addresses\n\n"
127 "Period: within 15 minutes\n\n"
128 "Prerequisite: \n\n"
129 "- Login attempts from different IP addresses, regardless of login status (at least 2 failed IP addresses)\n\n"
130 "- Successful login afterwards (from the third successful IP address)\n\n"
131 "Result: User compressed, IP addresses belong to an attack network",
132 dependencies=[Security(AuthHandler().require_any_scope("admin", "analyst"))],
133 )
134 async def invoke_sap_siem_successful_user_login_with_different_ip_route(
135 invoke_siem_analysis: InvokeSapSiemAnalysis,
136 ):
137 logger.info("Invoking SAP SIEM integration for successful user login with different IP.")
138 await post_to_copilot_sap_module_sap_siem_successful_user_login_with_different_ip(
139 data=InvokeSapSiemAnalysis(
140 threshold=invoke_siem_analysis.threshold,
141 time_range=invoke_siem_analysis.time_range,
142 iris_customer_id=invoke_siem_analysis.iris_customer_id,
143 ),
144 )
145
146 return InvokeSAPSiemResponse(success=True, message="SAP SIEM Events collected successfully.")
147
148
149 @module_sap_siem_router.post(
150 "/same_user_failed_login_from_different_ip",
151 response_model=InvokeSAPSiemResponse,
152 description="Rule: Same user from different IP addresses\n\n"
153 "Period: within 10 minutes\n\n"
154 "Prerequisite: \n\n"
155 "- At least 3 failed login attempts with the same user name from 3 different IP addresses\n\n"
156 "Result: User compressed, IP addresses belong to an attack network",
157 dependencies=[Security(AuthHandler().require_any_scope("admin", "analyst"))],
158 )
159 async def invoke_sap_siem_same_user_failed_login_from_different_ip_route(
160 invoke_siem_analysis: InvokeSapSiemAnalysis,
161 ):
162 logger.info("Invoking SAP SIEM integration for same user failed login from different IP.")
163 await post_to_copilot_sap_module_same_user_failed_login_from_different_ip(
164 data=InvokeSapSiemAnalysis(
165 threshold=invoke_siem_analysis.threshold,
166 time_range=invoke_siem_analysis.time_range,
167 iris_customer_id=invoke_siem_analysis.iris_customer_id,
168 ),
169 )
170
171 return InvokeSAPSiemResponse(success=True, message="SAP SIEM Events collected successfully.")
172
173
174 @module_sap_siem_router.post(
175 "/same_user_failed_login_from_different_geo_location",
176 response_model=InvokeSAPSiemResponse,
177 description="Rule: Same user from different geo locations\n\n"
178 "Period: within 20 minutes\n\n"
179 "Prerequisite: \n\n"
180 "- At least 3 failed login attempts with the same user name from at least two different GEO IP country locations\n\n"
181 "Result: User compressed, IP addresses belong to an attack network",
182 dependencies=[Security(AuthHandler().require_any_scope("admin", "analyst"))],
183 )
184 async def invoke_sap_siem_same_user_failed_login_from_different_geo_location_route(
185 invoke_siem_analysis: InvokeSapSiemAnalysis,
186 ):
187 logger.info("Invoking SAP SIEM integration for same user failed login from different geo location.")
188 await post_to_copilot_sap_module_same_user_failed_login_from_different_geo_location(
189 data=InvokeSapSiemAnalysis(
190 threshold=invoke_siem_analysis.threshold,
191 time_range=invoke_siem_analysis.time_range,
192 iris_customer_id=invoke_siem_analysis.iris_customer_id,
193 ),
194 )
195
196 return InvokeSAPSiemResponse(success=True, message="SAP SIEM Events collected successfully.")
197
198
199 @module_sap_siem_router.post(
200 "/same_user_successful_login_from_different_geo_location",
201 response_model=InvokeSAPSiemResponse,
202 description="Rule: Same user from different geo locations\n\n"
203 "Period: within 20 minutes\n\n"
204 "Prerequisite: \n\n"
205 "- At least 1 failed login attempt with the same username from two different GEO IP country locations\n\n"
206 "- from the 2nd successful login thereafter in another GEO IP country location\n\n"
207 "Result: User compressed, IP addresses belong to an attack network\n\n"
208 "This function would trigger a suspicious login when the following conditions are met:\n\n"
209 "1. There is at least one failed login attempt from the same user (identified by `login_id`) from two different GEO IP country locations within the last 20 minutes.\n"
210 "2. There is at least one successful login attempt from the same user from a different GEO IP country location within the last 20 minutes.\n\n"
211 "Here are some examples:\n\n"
212 "Example 1:\n"
213 "- At 12:00, a failed login attempt is made by user `user1` from IP `1.1.1.1` located in the US.\n"
214 "- At 12:10, another failed login attempt is made by `user1` from IP `2.2.2.2` located in Canada.\n"
215 "- At 12:15, a successful login attempt is made by `user1` from IP `3.3.3.3` located in the UK.\n"
216 "- In this case, the function would trigger a suspicious login for `user1` because there are failed login attempts from two different countries (US and Canada) "
217 "and a successful login from a different country (UK) within 20 minutes.\n\n"
218 "Example 2:\n"
219 "- At 12:00, a failed login attempt is made by user `user2` from IP `4.4.4.4` located in the US.\n"
220 "- At 12:10, another failed login attempt is made by `user2` from IP `5.5.5.5` also located in the US.\n"
221 "- At 12:15, a successful login attempt is made by `user2` from IP `6.6.6.6` located in the US.\n"
222 "- In this case, the function would not trigger a suspicious login for `user2` because all the login attempts are from the same country (US).",
223 dependencies=[Security(AuthHandler().require_any_scope("admin", "analyst"))],
224 )
225 async def invoke_sap_siem_same_user_successful_login_from_different_geo_location_route(
226 invoke_siem_analysis: InvokeSapSiemAnalysis,
227 ):
228 logger.info("Invoking SAP SIEM integration for same user successful login from different geo location.")
229 await post_to_copilot_sap_module_same_user_successful_login_from_different_geo_location(
230 data=InvokeSapSiemAnalysis(
231 threshold=invoke_siem_analysis.threshold,
232 time_range=invoke_siem_analysis.time_range,
233 iris_customer_id=invoke_siem_analysis.iris_customer_id,
234 ),
235 )
236
237 return InvokeSAPSiemResponse(success=True, message="SAP SIEM Events collected successfully.")
238
239
240 @module_sap_siem_router.post(
241 "/brute_force_failed_logins_multiple_ips",
242 response_model=InvokeSAPSiemResponse,
243 description="Rule: Logins from different IP addresses\n\n"
244 "Period: within 3 minutes\n\n"
245 "Prerequisite: \n\n"
246 "- At least 25 failed login attempts from different IP addresses\n\n"
247 "Result: IP addresses belong to an attack network",
248 dependencies=[Security(AuthHandler().require_any_scope("admin", "analyst"))],
249 )
250 async def invoke_sap_siem_brute_force_failed_logins_route(
251 invoke_siem_analysis: InvokeSapSiemAnalysis,
252 ):
253 logger.info("Invoking SAP SIEM integration for brute force failed logins.")
254 await post_to_copilot_sap_module_brute_force_failed_logins_multiple_ips(
255 data=InvokeSapSiemAnalysis(
256 threshold=invoke_siem_analysis.threshold,
257 time_range=invoke_siem_analysis.time_range,
258 iris_customer_id=invoke_siem_analysis.iris_customer_id,
259 ),
260 )
261
262 return InvokeSAPSiemResponse(success=True, message="SAP SIEM Events collected successfully.")
263
264
265 @module_sap_siem_router.post(
266 "/brute_force_failed_logins_same_ip",
267 response_model=InvokeSAPSiemResponse,
268 description="Rule: Logins from the same IP address\n\n"
269 "Period: within 5 minutes\n\n"
270 "Prerequisite: \n\n"
271 "- At least 10 different user name failed login attempts from the same IP address\n\n"
272 "Result: IP addresses belong to an attack network",
273 dependencies=[Security(AuthHandler().require_any_scope("admin", "analyst"))],
274 )
275 async def invoke_sap_siem_brute_force_failed_logins_same_ip_route(
276 invoke_siem_analysis: InvokeSapSiemAnalysis,
277 ):
278 logger.info("Invoking SAP SIEM integration for brute force failed logins from the same IP.")
279 await post_to_copilot_sap_module_brute_force_failed_logins_same_ip(
280 data=InvokeSapSiemAnalysis(
281 threshold=invoke_siem_analysis.threshold,
282 time_range=invoke_siem_analysis.time_range,
283 iris_customer_id=invoke_siem_analysis.iris_customer_id,
284 ),
285 )
286
287 return InvokeSAPSiemResponse(success=True, message="SAP SIEM Events collected successfully.")
288
289
290 @module_sap_siem_router.post(
291 "/successful_login_after_multiple_failed_logins",
292 response_model=InvokeSAPSiemResponse,
293 description="Rule: Successful login after multiple failed logins\n\n"
294 "Period: within 2 minutes\n\n"
295 "Prerequisite: \n\n"
296 "- At least 3 different user names that have failed from the same IP addressn\n"
297 "- At least one successful login from the same IP address after 3 different user names. \n\n"
298 "Result: User compromised, IP address belongs to an attack network",
299 dependencies=[Security(AuthHandler().require_any_scope("admin", "analyst"))],
300 )
301 async def invoke_sap_siem_successful_login_after_multiple_failed_logins_route(
302 invoke_siem_analysis: InvokeSapSiemAnalysis,
303 ):
304 logger.info("Invoking SAP SIEM integration for successful login after multiple failed logins.")
305 await post_to_copilot_sap_module_successful_login_after_multiple_failed_logins(
306 data=InvokeSapSiemAnalysis(
307 threshold=invoke_siem_analysis.threshold,
308 time_range=invoke_siem_analysis.time_range,
309 iris_customer_id=invoke_siem_analysis.iris_customer_id,
310 ),
311 )
312
313 return InvokeSAPSiemResponse(success=True, message="SAP SIEM Events collected successfully.")