feat(threat-detection): Use IAM Identity for Cloudtrail Threat Detection instead of IP (#5166)

This commit is contained in:
Amogh Bantwal
2024-09-25 06:15:47 -07:00
committed by GitHub
parent 90b84b57d3
commit 744e7ff5ac
4 changed files with 49 additions and 27 deletions
@@ -39,14 +39,27 @@ class cloudtrail_threat_detection_enumeration(Check):
minutes=threat_detection_minutes,
):
event_log = json.loads(event_log["CloudTrailEvent"])
if ".amazonaws.com" not in event_log["sourceIPAddress"]:
if event_log["sourceIPAddress"] not in potential_enumeration:
potential_enumeration[event_log["sourceIPAddress"]] = set()
potential_enumeration[event_log["sourceIPAddress"]].add(
event_name
if (
event_log["userIdentity"]["arn"],
event_log["userIdentity"]["type"],
) not in potential_enumeration:
potential_enumeration[
(
event_log["userIdentity"]["arn"],
event_log["userIdentity"]["type"],
)
] = set()
potential_enumeration[
(
event_log["userIdentity"]["arn"],
event_log["userIdentity"]["type"],
)
for source_ip, actions in potential_enumeration.items():
ip_threshold = round(len(actions) / len(enumeration_actions), 2)
].add(event_name)
for aws_identity, actions in potential_enumeration.items():
identity_threshold = round(len(actions) / len(enumeration_actions), 2)
aws_identity_type = aws_identity[1]
aws_identity_arn = aws_identity[0]
if len(actions) / len(enumeration_actions) > threshold:
found_potential_enumeration = True
report = Check_Report_AWS(self.metadata())
@@ -56,7 +69,7 @@ class cloudtrail_threat_detection_enumeration(Check):
cloudtrail_client.region
)
report.status = "FAIL"
report.status_extended = f"Potential enumeration attack detected from source IP {source_ip} with an threshold of {ip_threshold}."
report.status_extended = f"Potential enumeration attack detected from AWS {aws_identity_type} {aws_identity_arn.split('/')[-1]} with an threshold of {identity_threshold}."
findings.append(report)
if not found_potential_enumeration:
report = Check_Report_AWS(self.metadata())
@@ -40,19 +40,28 @@ class cloudtrail_threat_detection_privilege_escalation(Check):
minutes=threat_detection_minutes,
):
event_log = json.loads(event_log["CloudTrailEvent"])
if ".amazonaws.com" not in event_log["sourceIPAddress"]:
if (
event_log["sourceIPAddress"]
not in potential_privilege_escalation
):
potential_privilege_escalation[
event_log["sourceIPAddress"]
] = set()
if (
event_log["userIdentity"]["arn"],
event_log["userIdentity"]["type"],
) not in potential_privilege_escalation:
potential_privilege_escalation[
event_log["sourceIPAddress"]
].add(event_name)
for source_ip, actions in potential_privilege_escalation.items():
ip_threshold = round(len(actions) / len(privilege_escalation_actions), 2)
(
event_log["userIdentity"]["arn"],
event_log["userIdentity"]["type"],
)
] = set()
potential_privilege_escalation[
(
event_log["userIdentity"]["arn"],
event_log["userIdentity"]["type"],
)
].add(event_name)
for aws_identity, actions in potential_privilege_escalation.items():
identity_threshold = round(
len(actions) / len(privilege_escalation_actions), 2
)
aws_identity_type = aws_identity[1]
aws_identity_arn = aws_identity[0]
if len(actions) / len(privilege_escalation_actions) > threshold:
found_potential_privilege_escalation = True
report = Check_Report_AWS(self.metadata())
@@ -62,7 +71,7 @@ class cloudtrail_threat_detection_privilege_escalation(Check):
cloudtrail_client.region
)
report.status = "FAIL"
report.status_extended = f"Potential privilege escalation attack detected from source IP {source_ip} with an threshold of {ip_threshold}."
report.status_extended = f"Potential privilege escalation attack detected from AWS {aws_identity_type} {aws_identity_arn.split('/')[-1]} with an threshold of {identity_threshold}."
findings.append(report)
if not found_potential_privilege_escalation:
report = Check_Report_AWS(self.metadata())
@@ -19,10 +19,10 @@ def mock_get_trail_arn_template(region=None, *_) -> str:
def mock__get_lookup_events__(trail=None, event_name=None, minutes=None, *_) -> list:
return [
{
"CloudTrailEvent": '{"sourceIPAddress": "172.28.7.0/24", "eventName": "DescribeAccessEntry"}'
"CloudTrailEvent": '{"eventName": "DescribeAccessEntry", "userIdentity": {"type": "IAMUser", "principalId": "EXAMPLE6E4XEGITWATV6R", "arn": "arn:aws:iam::123456789012:user/Mateo", "accountId": "123456789012", "accessKeyId": "AKIAIOSFODNN7EXAMPLE", "userName": "Mateo", "sessionContext": {"sessionIssuer": {}, "webIdFederationData": {}, "attributes": {"creationDate": "2023-07-19T21:11:57Z", "mfaAuthenticated": "false"}}}}'
},
{
"CloudTrailEvent": '{"sourceIPAddress": "172.28.7.0/24", "eventName": "DescribeAccountAttributes"}'
"CloudTrailEvent": '{"eventName": "DescribeAccountAttributes", "userIdentity": {"type": "IAMUser", "principalId": "EXAMPLE6E4XEGITWATV6R", "arn": "arn:aws:iam::123456789012:user/Mateo", "accountId": "123456789012", "accessKeyId": "AKIAIOSFODNN7EXAMPLE", "userName": "Mateo", "sessionContext": {"sessionIssuer": {}, "webIdFederationData": {}, "attributes": {"creationDate": "2023-07-19T21:11:57Z", "mfaAuthenticated": "false"}}}}'
},
]
@@ -154,7 +154,7 @@ class Test_cloudtrail_threat_detection_enumeration:
assert result[0].status == "FAIL"
assert (
result[0].status_extended
== "Potential enumeration attack detected from source IP 172.28.7.0/24 with an threshold of 1.0."
== "Potential enumeration attack detected from AWS IAMUser Mateo with an threshold of 1.0."
)
assert result[0].resource_id == AWS_ACCOUNT_NUMBER
assert result[0].region == AWS_REGION_US_EAST_1
@@ -19,10 +19,10 @@ def mock_get_trail_arn_template(region=None, *_) -> str:
def mock__get_lookup_events__(trail=None, event_name=None, minutes=None, *_) -> list:
return [
{
"CloudTrailEvent": '{"sourceIPAddress": "172.28.7.0/24", "eventName": "CreateLoginProfile"}'
"CloudTrailEvent": '{"eventName": "CreateLoginProfile", "userIdentity": {"type": "IAMUser", "principalId": "EXAMPLE6E4XEGITWATV6R", "arn": "arn:aws:iam::123456789012:user/Mateo", "accountId": "123456789012", "accessKeyId": "AKIAIOSFODNN7EXAMPLE", "userName": "Mateo", "sessionContext": {"sessionIssuer": {}, "webIdFederationData": {}, "attributes": {"creationDate": "2023-07-19T21:11:57Z", "mfaAuthenticated": "false"}}}}'
},
{
"CloudTrailEvent": '{"sourceIPAddress": "172.28.7.0/24", "eventName": "UpdateLoginProfile"}'
"CloudTrailEvent": '{"eventName": "UpdateLoginProfile", "userIdentity": {"type": "IAMUser", "principalId": "EXAMPLE6E4XEGITWATV6R", "arn": "arn:aws:iam::123456789012:user/Mateo", "accountId": "123456789012", "accessKeyId": "AKIAIOSFODNN7EXAMPLE", "userName": "Mateo", "sessionContext": {"sessionIssuer": {}, "webIdFederationData": {}, "attributes": {"creationDate": "2023-07-19T21:11:57Z", "mfaAuthenticated": "false"}}}}'
},
]
@@ -153,7 +153,7 @@ class Test_cloudtrail_threat_detection_privilege_escalation:
assert result[0].status == "FAIL"
assert (
result[0].status_extended
== "Potential privilege escalation attack detected from source IP 172.28.7.0/24 with an threshold of 1.0."
== "Potential privilege escalation attack detected from AWS IAMUser Mateo with an threshold of 1.0."
)
assert result[0].resource_id == AWS_ACCOUNT_NUMBER
assert result[0].region == AWS_REGION_US_EAST_1