Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding Azure EntraID rules #1463

Open
wants to merge 26 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
a97eb8a
feat: new example rules
joongi92 Jan 9, 2025
b207506
Merge pull request #2 from joongi92/feat/my_first_branch
joongi92 Jan 9, 2025
a9dffa1
Removed my local rules
joongi92 Jan 9, 2025
4d4826b
Update upload.yml
joongi92 Jan 22, 2025
89cb8d0
removed API keys
joongi92 Jan 23, 2025
7c11db5
Merge branch 'develop' into main
arielkr256 Jan 27, 2025
550a261
Updated rules, removed panther_azure_helpers and added to panther_msf…
joongi92 Jan 27, 2025
007868b
Merge branch 'develop' into main
arielkr256 Jan 28, 2025
5f66fc1
Update global_helpers/panther_msft_helpers.py
arielkr256 Jan 31, 2025
f7e7cb0
Update global_helpers/panther_msft_helpers.py
arielkr256 Jan 31, 2025
a520480
Update rules/azure_entraid_rules/azure_mfa_disabled.yml
arielkr256 Jan 31, 2025
e948327
Update rules/azure_entraid_rules/azure_mfa_disabled.py
arielkr256 Jan 31, 2025
191c58c
Update rules/azure_entraid_rules/azure_mfa_disabled.py
arielkr256 Jan 31, 2025
ac2c56f
Update rules/azure_entraid_rules/azure_mfa_disabled.yml
arielkr256 Jan 31, 2025
a189443
Update rules/azure_entraid_rules/azure_mfa_disabled.yml
arielkr256 Jan 31, 2025
5379376
Update rules/azure_entraid_rules/azure_mfa_disabled.yml
arielkr256 Jan 31, 2025
2da2ce6
Update rules/azure_entraid_rules/azure_policy_changed.yml
arielkr256 Jan 31, 2025
cac72b4
Update rules/azure_entraid_rules/azure_policy_changed.py
arielkr256 Jan 31, 2025
b34e2df
Update rules/azure_entraid_rules/azure_policy_changed.py
arielkr256 Jan 31, 2025
41f2eea
Update rules/azure_entraid_rules/azure_policy_changed.py
arielkr256 Jan 31, 2025
09ca481
Update rules/azure_entraid_rules/azure_policy_changed.yml
arielkr256 Jan 31, 2025
d7066b6
Update rules/azure_entraid_rules/azure_role_changed_pim.py
arielkr256 Jan 31, 2025
08e1839
Update rules/azure_entraid_rules/azure_policy_changed.yml
arielkr256 Jan 31, 2025
3fc314f
Update rules/azure_entraid_rules/azure_policy_changed.yml
arielkr256 Jan 31, 2025
2c47bf1
Update rules/azure_entraid_rules/azure_policy_changed.yml
arielkr256 Jan 31, 2025
24db394
Update rules/azure_entraid_rules/azure_policy_changed.yml
arielkr256 Jan 31, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/upload.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,4 @@ jobs:

- name: upload
run: |
pipenv run panther_analysis_tool upload --api-host ${{ env.API_HOST }} --api-token ${{ env.API_TOKEN }}
pipenv run panther_analysis_tool upload --api-host ${{ env.API_HOST }} --api-token ${{ env.API_TOKEN }}
37 changes: 37 additions & 0 deletions global_helpers/panther_msft_helpers.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from panther_base_helpers import deep_get, deep_walk

def msft_graph_alert_context(event):
return {
"category": event.get("category", ""),
Expand All @@ -18,3 +20,38 @@ def m365_alert_context(event):
"application": event.get("Application", ""),
"actor": event.get("Actor", []),
}

def azure_rule_context(event: dict):
return {
"operationName": event.get("operationName", default="<MISSING_OPERATION_NAME>"),
"category": deep_get(event, "properties", "category", default="<MISSING_CATEGORY>"),
"actor_id": deep_get(
event, "properties", "initiatedBy", "user", "id", default="<MISSING_ACTOR_ID"
),
"actor_upn": deep_get(
event, "properties", "initiatedBy", "user", "userPrincipalName", default="<MISSING UPN>"
),
"source_ip_address": deep_get(
event, "properties", "initiatedBy", "user", "ipAddress", default="<MISSING_SOURCE_IP>"
),
"target_id": deep_walk(
event, "properties", "targetResources", "id", default="<MISSING_ACCOUNT_ID>"
),
"target_name": deep_walk(
event, "properties", "targetResources", "displayName", default="<MISSING UPN>"
),
}


def get_target_name(event, target_type="User"):
target_resources = deep_walk(event, "properties", "targetResources", default="")
for resource in target_resources:
if resource.get("type") == target_type:
return resource.get("displayName", "NO DISPLAY NAME FOUND")

return "NO DISPLAY NAME FOUND"


def azure_success(event):
result = event.deep_get("properties", "result", default="")
return result == "success"
35 changes: 35 additions & 0 deletions rules/azure_entraid_rules/azure_invite_external_users.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
from panther_msft_helpers import azure_rule_context, azure_success


def rule(event):
if not azure_success(event) or event.get("operationName") != "Invite external user":
return False

user_who_sent_invite = event.deep_get(
"properties", "initiatedBy", "user", "userPrincipalName", default=""
)
user_who_received_invite = event.deep_walk(
"properties", "additionalDetails", "value", return_val="last", default=""
)
domain = user_who_sent_invite.split("@")[-1]

different_domain = not user_who_received_invite.endswith(domain)

return different_domain


def title(event):
user_who_sent_invite = event.deep_get(
"properties", "initiatedBy", "user", "userPrincipalName", default=""
)
user_who_received_invite = event.deep_walk(
"properties", "additionalDetails", "value", return_val="last", default=""
)

return (
f"{user_who_sent_invite} invited {user_who_received_invite} to join as an EntraID member."
)


def alert_context(event):
return azure_rule_context(event)
294 changes: 294 additions & 0 deletions rules/azure_entraid_rules/azure_invite_external_users.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,294 @@
AnalysisType: rule
Filename: azure_invite_external_users.py
RuleID: "Azure.Audit.InviteExternalUsers"
DisplayName: "Azure Invite External Users"
Enabled: true
LogTypes:
- Azure.Audit
Severity: Low
Description: >
This detection looks for a Azure users inviting external users
Reports:
MITRE ATT&CK:
- TA0001:T1078
Runbook: >
Verify the user permissions and investigate the external user details. If unauthorized, revoke access and block further invites. Update security policies.

Reference: https://learn.microsoft.com/en-us/entra/identity/authentication/overview-authentication
SummaryAttributes:
- properties:ServicePrincipalName
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would remove this entirely; the field isn't present in any of your sample logs, so it will always be null and not useful

- properties:UserPrincipalName
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't need this, since we already have the userPrincipalName in the alert title

- properties:ipAddress
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- properties:ipAddress
- properties:initiatedBy:user:ipAddress

Tests:
- Name: Successful Invite external user
ExpectedResult: true
Log:
{
"callerIpAddress": "1.1.1.1",
"category": "AuditLogs",
"correlationId": "123456789",
"durationMs": 0,
"Level": 4,
"operationName": "Invite external user",
"operationVersion": "1.0",
"properties": {
"activityDateTime": "2024-09-23 14:33:09.049661100",
"activityDisplayName": "Invite external user",
"additionalDetails": [
{
"key": "oid",
"value": "123456789"
},
{
"key": "tid",
"value": "0123456789"
},
{
"key": "ipaddr",
"value": "1.2.3.4"
},
{
"key": "wids",
"value": "123456789"
},
{
"key": "InvitationId",
"value": "123456789"
},
{
"key": "invitedUserEmailAddress",
"value": "[email protected]"
}
],
"category": "UserManagement",
"correlationId": "123456789",
"id": "Invited Users_123456789",
"initiatedBy": {
"user": {
"id": "123456789",
"ipAddress": "1.2.3.4.5",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"ipAddress": "1.2.3.4.5",
"ipAddress": "1.2.3.4",

"roles": [],
"userPrincipalName": "[email protected]"
}
},
"loggedByService": "Invited Users",
"operationType": "Add",
"result": "success",
"targetResources": [
{
"administrativeUnits": [],
"displayName": "Zeus.Theboss",
"id": "123456789",
"type": "User"
}
]
},
"resourceId": "/tenants/123456789/providers/Microsoft.aadiam",
"resultSignature": "None",
"tenantId": "123456789",
"time": "2024-12-10 14:33:09.049661100"
}
- Name: Same org successful invite
ExpectedResult: false
Log:
{
"callerIpAddress": "1.1.1.1",
"category": "AuditLogs",
"correlationId": "123456789",
"durationMs": 0,
"Level": 4,
"operationName": "Invite external user",
"operationVersion": "1.0",
"properties": {
"activityDateTime": "2024-09-23 14:33:09.049661100",
"activityDisplayName": "Invite external user",
"additionalDetails": [
{
"key": "oid",
"value": "123456789"
},
{
"key": "tid",
"value": "0123456789"
},
{
"key": "ipaddr",
"value": "1.2.3.4"
},
{
"key": "wids",
"value": "123456789"
},
{
"key": "InvitationId",
"value": "123456789"
},
{
"key": "invitedUserEmailAddress",
"value": "[email protected]"
}
],
"category": "UserManagement",
"correlationId": "123456789",
"id": "Invited Users_123456789",
"initiatedBy": {
"user": {
"id": "123456789",
"ipAddress": "1.2.3.4.5",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"ipAddress": "1.2.3.4.5",
"ipAddress": "1.2.3.4",

"roles": [],
"userPrincipalName": "[email protected]"
}
},
"loggedByService": "Invited Users",
"operationType": "Add",
"result": "success",
"targetResources": [
{
"administrativeUnits": [],
"displayName": "Zeus.Theboss",
"id": "123456789",
"type": "User"
}
]
},
"resourceId": "/tenants/123456789/providers/Microsoft.aadiam",
"resultSignature": "None",
"tenantId": "123456789",
"time": "2024-12-10 14:33:09.049661100"
}
- Name: Unsuccessful invite
ExpectedResult: false
Log:
{
"callerIpAddress": "1.1.1.1",
"category": "AuditLogs",
"correlationId": "123456789",
"durationMs": 0,
"Level": 4,
"operationName": "Invite external user",
"operationVersion": "1.0",
"properties": {
"activityDateTime": "2024-09-23 14:33:09.049661100",
"activityDisplayName": "Invite external user",
"additionalDetails": [
{
"key": "oid",
"value": "123456789"
},
{
"key": "tid",
"value": "0123456789"
},
{
"key": "ipaddr",
"value": "1.2.3.4"
},
{
"key": "wids",
"value": "123456789"
},
{
"key": "InvitationId",
"value": "123456789"
},
{
"key": "invitedUserEmailAddress",
"value": "[email protected]"
}
],
"category": "UserManagement",
"correlationId": "123456789",
"id": "Invited Users_123456789",
"initiatedBy": {
"user": {
"id": "123456789",
"ipAddress": "1.2.3.4.5",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"ipAddress": "1.2.3.4.5",
"ipAddress": "1.2.3.4",

"roles": [],
"userPrincipalName": "[email protected]"
}
},
"loggedByService": "Invited Users",
"operationType": "Add",
"result": "failed",
"targetResources": [
{
"administrativeUnits": [],
"displayName": "Zeus.Theboss",
"id": "123456789",
"type": "User"
}
]
},
"resourceId": "/tenants/123456789/providers/Microsoft.aadiam",
"resultSignature": "None",
"tenantId": "123456789",
"time": "2024-12-10 14:33:09.049661100"
}
- Name: Not external invite
ExpectedResult: false
Log:
{
"callerIpAddress": "1.1.1.1",
"category": "AuditLogs",
"correlationId": "123456789",
"durationMs": 0,
"Level": 4,
"operationName": "Invite Internal User",
"operationVersion": "1.0",
"properties": {
"activityDateTime": "2024-09-23 14:33:09.049661100",
"activityDisplayName": "Invite external user",
"additionalDetails": [
{
"key": "oid",
"value": "123456789"
},
{
"key": "tid",
"value": "0123456789"
},
{
"key": "ipaddr",
"value": "1.2.3.4"
},
{
"key": "wids",
"value": "123456789"
},
{
"key": "InvitationId",
"value": "123456789"
},
{
"key": "invitedUserEmailAddress",
"value": "[email protected]"
}
],
"category": "UserManagement",
"correlationId": "123456789",
"id": "Invited Users_123456789",
"initiatedBy": {
"user": {
"id": "123456789",
"ipAddress": "1.2.3.4.5",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"ipAddress": "1.2.3.4.5",
"ipAddress": "1.2.3.4",

"roles": [],
"userPrincipalName": "[email protected]"
}
},
"loggedByService": "Invited Users",
"operationType": "Add",
"result": "success",
"targetResources": [
{
"administrativeUnits": [],
"displayName": "Zeus.Theboss",
"id": "123456789",
"type": "User"
}
]
},
"resourceId": "/tenants/123456789/providers/Microsoft.aadiam",
"resultSignature": "None",
"tenantId": "123456789",
"time": "2024-12-10 14:33:09.049661100"
}
Loading