| Attribute | Details |
|---|---|
| Technique ID | COLLECT-AUDIT-001 |
| MITRE ATT&CK v18.1 | T1552.001 - Credentials in Files |
| Tactic | Collection |
| Platforms | Multi-Env (Windows AD, Azure, M365, Entra ID, Hybrid) |
| Severity | Critical |
| CVE | N/A |
| Technique Status | ACTIVE |
| Last Verified | 2026-01-10 |
| Affected Versions | Windows Server 2016-2025, Azure all versions, M365 all tenants |
| Patched In | N/A (Operational Feature) |
| Author | SERVTEP – Artur Pchelnikau |
Concept: Audit logs are comprehensive records of security-relevant activities across Microsoft environments: Windows Event Log (on-premises), Azure Activity Log (cloud infrastructure), M365 Unified Audit Log (collaboration and mail), and Entra ID/Azure AD Sign-in Logs (authentication events). These logs contain timestamped records of user actions, administrative changes, system events, and security anomalies. Comprehensive collection and analysis of audit logs reveals: (1) user access patterns and privilege escalation chains, (2) administrative configuration changes (often indicators of persistence mechanisms), (3) failed authentication attempts (brute force indicators), (4) sensitive data access and exfiltration events, (5) policy violations and compliance failures. An attacker with comprehensive audit log access can understand exactly what the organization has observed, what went undetected, and how to refine their attack techniques. Organizations with audit logging disabled or with short retention periods are unable to investigate historical breaches, making audit log collection critical for post-compromise threat hunting.
Attack Surface: Windows Event Viewer, Azure Activity Log API, Microsoft Purview Compliance Portal (M365 Unified Audit Log), Entra ID Sign-in Logs, Azure Monitor Log Analytics workspace, third-party SIEM ingestion points.
Business Impact: Complete visibility into security events, administrative actions, user behavior patterns, and forensic evidence for all breaches. Audit logs contain: (1) evidence of initial compromise (failed login attempts before successful breach), (2) administrative account misuse (privilege escalation), (3) data exfiltration indicators (bulk downloads, email forwards), (4) account creation/deletion events (backdoor accounts), (5) policy modifications (disabling MFA, Conditional Access rules). Loss of audit logs due to short retention or deletion during incident response prevents forensic investigation, blocks threat intelligence gathering, and eliminates legal evidence for breach notification and litigation.
Technical Context: Audit logs are available in all Microsoft environments by default (some require explicit enablement). Retention varies: Windows Event Log (default 7-30 days), Azure Activity (90 days default, up to 12 years with policy), M365 Unified Audit (90 days default, up to 10 years with Advanced Audit). Querying audit logs requires minimal permissions (Security Reader, Audit log viewer). Exfiltration requires simple export via portal or API. No special tools required.
| Framework | Control / ID | Description |
|---|---|---|
| CIS Benchmark | 6.2 | Configure log retention to preserve logs for adequate period |
| DISA STIG | AU-2 | Audit Events – Determine auditable events (all security-relevant events) |
| CISA SCuBA | Log.1.1 | Ensure audit logging is enabled and retention is set appropriately |
| NIST 800-53 | AU-2, AU-3, AU-12 | Audit and Accountability – Log events, retention, and protection |
| GDPR | Art. 5(1)(f), Art. 32 | Data Protection – Integrity and confidentiality of logs |
| DORA | Art. 19 | Incident handling and response – Evidence preservation |
| NIS2 | Art. 21 | Cybersecurity Risk Management – Logging and monitoring |
| ISO 27001 | A.12.4.1 | Recording user activities and system events (audit logs) |
| ISO 27005 | 8.3 | Risk Assessment – Audit logs as forensic evidence |
Supported Versions:
Tools:
eventvwr.msc) – on-premises# Check if audit logging is enabled on local Windows system
Get-EventLog -LogName Security -Newest 1 -ErrorAction SilentlyContinue | Select-Object TimeGenerated, EventID
# Check if Windows audit policy is configured
auditpol /get /category:*
# Check Azure audit log availability
Connect-AzAccount
Get-AzActivityLog -MaxRecord 1
# Check M365 audit log availability
Connect-ExchangeOnline
Search-UnifiedAuditLog -ResultSize 1
What to Look For:
Version Note: Commands work identically across all Windows versions and Azure regions.
Supported Versions: Server 2016-2025 (all versions)
Command:
Win + R, type eventvwr.msc, press EnterExpected Output:
OpSec & Evasion:
Command:
C:\temp\Security_Logs.evtxExpected Output:
C:\temp\Security_Logs.evtx (typically 100MB - 1GB for large environments)What This Means:
OpSec & Evasion:
Command:
# Load the exported .evtx file
$events = Get-WinEvent -Path "C:\temp\Security_Logs.evtx" -MaxEvents 10000
# Filter for logon events (EventID 4624)
$logonEvents = $events | Where-Object {$_.Id -eq 4624}
# Filter for process creation (EventID 4688)
$processEvents = $events | Where-Object {$_.Id -eq 4688}
# Filter for account lockouts (EventID 4740)
$lockoutEvents = $events | Where-Object {$_.Id -eq 4740}
# Export filtered events to CSV
$logonEvents | Select-Object TimeCreated, @{n='EventID';e={$_.Id}}, @{n='Message';e={$_.Message}} | Export-Csv -Path "C:\temp\logon_events.csv"
Write-Host "Extracted $($logonEvents.Count) logon events"
Write-Host "Extracted $($processEvents.Count) process creation events"
Write-Host "Extracted $($lockoutEvents.Count) account lockout events"
Expected Output:
Extracted 15234 logon events
Extracted 8976 process creation events
Extracted 342 account lockout events
What This Means:
OpSec & Evasion:
References & Proofs:
Supported Versions: All Azure subscriptions and regions
Command:
Expected Output:
What This Means:
OpSec & Evasion:
Command:
Expected Output:
What This Means:
OpSec & Evasion:
Command:
activity-log-export.csv to Downloads folderExpected Output:
Time,Subscription,Operation,Status,Resource,Resource Group,Caller,Request Size,Caller IP Address
2026-01-09T14:32:15Z,mysubscription,Microsoft.Authorization/roleAssignments/write,Succeeded,myresourcegroup,myresourcegroup,user@company.com,1234,203.0.113.45
2026-01-09T13:22:08Z,mysubscription,Microsoft.Storage/storageAccounts/delete,Failed,mystorageaccount,myresourcegroup,admin@company.com,567,203.0.113.46
What This Means:
OpSec & Evasion:
References & Proofs:
Supported Versions: All M365 tenants with audit enabled (90 days default, 10 years with Advanced Audit)
Command:
Expected Output:
OpSec & Evasion:
Command:
Expected Output:
Activity: Add-MailForwardingAddress
User: admin@company.com
Date: 2026-01-09
Time: 14:32:15
Details: Forward emails from user@company.com to attacker@external-domain.com
Result IP: 203.0.113.45
What This Means:
OpSec & Evasion:
Command:
AuditLog_yyyy-mm-dd.csvExpected Output:
CreationDate,UserIds,Operations,AuditData
2026-01-09T14:32:15Z,admin@company.com,Add-MailForwardingAddress,"{'Id':'xxxxxxxx','Item':{'Subject':'','Identity':'user@company.com'},'ModifiedProperties':{'Name':'ForwardingAddress','NewValue':'attacker@external.com'}}"
What This Means:
OpSec & Evasion:
References & Proofs:
Supported Versions: All environments (Windows, Azure, M365)
Command (M365 Unified Audit Log - no API available, PowerShell only):
# Connect to Exchange Online PowerShell (M365 Audit)
Connect-ExchangeOnline -UserPrincipalName "user@company.com"
# Search Unified Audit Log for last 90 days
$startDate = (Get-Date).AddDays(-90)
$endDate = Get-Date
$auditEvents = Search-UnifiedAuditLog -StartDate $startDate -EndDate $endDate -ResultSize 50000
# Filter for suspicious activities
$suspiciousEvents = $auditEvents | Where-Object {
$_.Operations -in @(
"Delete",
"Update-InboxRules",
"Add-MailForwardingAddress",
"Set-Mailbox",
"New-ExternalUser",
"New-ApplicationAccessPolicy"
)
}
# Export to CSV
$suspiciousEvents | Select-Object CreationDate, UserId, Operations, @{n='Details';e={$_.AuditData | ConvertFrom-Json}} | Export-Csv -Path "C:\temp\m365_audit_suspicious.csv" -NoTypeInformation
Write-Host "Extracted $($suspiciousEvents.Count) suspicious events from M365 Audit Log"
Expected Output:
Extracted 342 suspicious events from M365 Audit Log
What This Means:
OpSec & Evasion:
Command (Azure Activity Logs - programmatic access):
#!/bin/bash
# Connect to Azure
az login
# Query Activity Log for last 30 days
RESOURCE_GROUP="your-resource-group"
START_DATE=$(date -d '30 days ago' -u +%Y-%m-%dT%H:%M:%SZ)
END_DATE=$(date -u +%Y-%m-%dT%H:%M:%SZ)
# Export all activity logs
az monitor activity-log list \
--resource-group $RESOURCE_GROUP \
--start-time $START_DATE \
--end-time $END_DATE \
--query "[*].{Time:eventTimestamp, Operation:operationName, Caller:caller, Status:status}" \
--output csv > /tmp/azure_activity.csv
echo "Activity logs exported to /tmp/azure_activity.csv"
Expected Output:
Time,Operation,Caller,Status
2026-01-09T14:32:15Z,Microsoft.Authorization/roleAssignments/write,user@company.com,Succeeded
2026-01-09T13:22:08Z,Microsoft.Compute/virtualMachines/delete,admin@company.com,Succeeded
OpSec & Evasion:
Command (Windows Event Logs - remote collection):
# Connect to remote server
$server = "SERVER-PROD-01"
Invoke-Command -ComputerName $server -ScriptBlock {
# Export Security event log
wevtutil epl Security "C:\temp\Security.evtx"
# Get count of events
Get-WinEvent -LogName Security -MaxEvents 1 | Select-Object RecordCount
}
# Copy exported file back to local machine
Copy-Item -Path "\\$server\C$\temp\Security.evtx" -Destination "C:\incident\Security.evtx"
Write-Host "Security event log exported from $server"
Expected Output:
C:\incident\Security.evtx (containing all security events from remote server)What This Means:
OpSec & Evasion:
References & Proofs:
eventvwr.msc)Version: Built-in (all Windows versions) Platforms: Windows Server 2016-2025, Windows 10-11
Usage:
# Open Event Viewer GUI
eventvwr.msc
# Or: Export logs via command line
wevtutil epl Security "C:\temp\Security.evtx"
# Query logs with PowerShell
Get-WinEvent -LogName Security -FilterXPath "*[System[(EventID=4624)]]" -MaxEvents 100
Version: Part of Exchange Online PowerShell module v2.x Platforms: Windows, macOS, Linux (PowerShell 7+)
Installation:
Install-Module ExchangeOnlineManagement -Force
Connect-ExchangeOnline
Usage:
$results = Search-UnifiedAuditLog -StartDate (Get-Date).AddDays(-90) -EndDate (Get-Date) -ResultSize 5000
$results | Select-Object CreationDate, UserId, Operations | Export-Csv "audit.csv"
az monitor activity-log)Version: 2.50+ (current) Platforms: Windows, macOS, Linux
Installation:
# macOS
brew install azure-cli
# Linux (Ubuntu/Debian)
curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash
# Windows (PowerShell)
Invoke-WebRequest -Uri https://aka.ms/installazurecliwindows -OutFile AzureCLI.msi
Start-Process msiexec.exe -Wait -ArgumentList '/I AzureCLI.msi /quiet'
Usage:
az login
az monitor activity-log list --start-time 2026-01-01 --end-time 2026-01-10 --output json > activity_log.json
Rule Configuration:
KQL Query:
AuditLogs
| where OperationName == "Search-UnifiedAuditLog" or OperationName == "Export audit log"
| where Result == "Success"
| summarize ExportCount = count(), TotalRecords = sum(ResultCount) by UserPrincipalName, IpAddress
| where ExportCount > 3 // Multiple exports by same user = suspicious
| project UserPrincipalName, IpAddress, ExportCount, TotalRecords
What This Detects:
Manual Configuration (Azure Portal):
Audit_Log_Bulk_Export_DetectionEvent IDs to Monitor:
Manual Configuration (Group Policy):
gpupdate /force and restartRestrict Audit Log Access: Limit who can access, export, and search audit logs. Only Security and Audit teams should have access.
Manual Steps (Windows):
Manual Steps (M365):
Manual Steps (Azure):
Enable Audit Log Retention: Set audit log retention to maximum allowed (10 years M365, 7-12 years Azure with archive).
Manual Steps (M365):
Manual Steps (Azure):
Manual Steps (Windows):
Enable Audit Log Alerts: Configure alerts for access to sensitive audit logs.
Manual Steps:
Implement Immutable Audit Logs: Use Azure Storage immutable backup for critical audit logs (cannot be deleted even by Global Admin).
Manual Steps:
Monitor Audit Log Deletion: Alert on any attempt to delete, clear, or disable audit logs.
Manual Steps:
# Verify audit log retention is set to maximum
Get-UnifiedAuditLogRetentionPolicy | Select-Object Name, RetentionDays
# Expected: > 2000 days (5+ years minimum)
# Verify only Security group can access Event Viewer logs
Get-Acl "C:\Windows\System32\Winevt\Logs\Security.evtx" | Select-Object Owner, Access
# Expected: SYSTEM and Security group only
.evtx export files: Security.evtx, audit.evtx in unexpected locationsAuditLog_*.csv, activity-log-export.csvSearchQueryInitiatedAdmin event in Unified Audit Log (user searching audit logs)ExportUnifiedAuditLog event in Unified Audit Logeventvwr.exe, powershell.exe show recent executionC:\temp\, C:\users\[user]\downloads\ contain exported audit logsSearchQueryInitiatedAdmin events in Unified Audit Log show who searched audit logs, when, and what queriesExportUnifiedAuditLog event shows export timestamp and result count# Disable compromised user account
Disable-AzADUser -ObjectId "compromised@company.com"
# Export all audit log searches by compromised user (last 30 days)
Search-UnifiedAuditLog -StartDate (Get-Date).AddDays(-30) -UserIds "compromised@company.com" | Export-Csv "incident_queries.csv"
# Check for exported files
Get-ChildItem -Path "C:\temp\", "C:\users\*\downloads\" -Filter "*audit*.csv", "*.evtx" -Recurse
| Step | Phase | Technique | Description |
|---|---|---|---|
| 1 | Initial Access | T1078 - Valid Accounts | Compromise admin account or insider threat |
| 2 | Privilege Escalation | T1548 - Abuse Elevation Control Mechanism | Obtain audit log access via admin account |
| 3 | Collection | [COLLECT-AUDIT-001] | Extract 90+ days of comprehensive audit logs |
| 4 | Exfiltration | T1020 - Automated Exfiltration | Exfiltrate audit CSV files via email or cloud storage |
| 5 | Impact | T1562.008 - Disable/Modify Cloud Logs | Delete audit logs to cover tracks |
Primary References: