| name | analyzing-office365-audit-logs-for-compromise |
| description | Parse Office 365 Unified Audit Logs via Microsoft Graph API to detect email forwarding rule creation, inbox delegation, suspicious OAuth app grants, and other indicators of account compromise. Use when working with analyzing office365 audit logs for compromise. |
| domain | cybersecurity |
| subdomain | cloud-security |
| tags | ["Office365","Microsoft-Graph","audit-logs","email-compromise","inbox-rules","OAuth","BEC"] |
| version | 1.0 |
| author | oyi77 |
| license | Apache-2.0 |
| nist_csf | ["PR.IR-01","ID.AM-08","GV.SC-06","DE.CM-01"] |
Analyzing Office 365 Audit Logs for Compromise
Overview
Business Email Compromise (BEC) attacks often leave traces in Office 365 audit logs: suspicious inbox rule creation, email forwarding to external addresses, mailbox delegation changes, and unauthorized OAuth application consent grants. This skill uses the Microsoft Graph API to query the Unified Audit Log, enumerate inbox rules across mailboxes, detect forwarding configurations, and identify compromised account indicators.
When to Use
Trigger phrases:
-
"analyzing office365 audit logs for compromise"
-
"Parse Office 365 Unified Audit Logs via Microsoft Graph API to detect email forw"
-
When investigating security incidents that require analyzing office365 audit logs for compromise
-
When building detection rules or threat hunting queries for this domain
-
When SOC analysts need structured procedures for this analysis type
-
When validating security monitoring coverage for related attack techniques
Prerequisites
- Azure AD app registration with
AuditLog.Read.All, MailboxSettings.Read, Mail.Read (application permissions)
- Python 3.9+ with
msal, requests
- Client secret or certificate for authentication
- Global Reader or Security Reader role
Steps
import re
IOC_PATTERNS = {
"ip": r"\b(?:\d{1,3}\.){3}\d{1,3}\b",
"domain": r"\b[a-z0-9-]+\.[a-z]{2,}\b",
"hash_md5": r"\b[a-f0-9]{32}\b",
"hash_sha256": r"\b[a-f0-9]{64}\b",
}
def extract_iocs(text: str) -> dict:
return {k: re.findall(v, text) for k, v in IOC_PATTERNS.items()}
- Authenticate to Microsoft Graph using MSAL client credentials flow