A few weeks ago I thought that 0x00sec didn’t have enough Blue Team focused posts. Yet, detection of potential threats is incredibly important in any organization. Because Azure and Office 365 are widely used, I decided to start with this. I hope you will find it useful because unfortunately, there is a lack of good resources other than Microsoft when it comes to monitoring Azure with a SIEM and I had to spend many hours to study the logs and figure out what was relevant.
This is not a complete guide for all the products and services within Azure. I just don’t have enough spare time to do it all. But I think it’s a great starting point to monitor the commonly used services.
Most of the queries here are built for Splunk because of its increasing popularity as a SIEM. If you or your organization doesn’t use Splunk, you can convert them manually or try using Sigma. The queries are meant to be base searches that you can built on top of and customize to your needs.
Requirements for log ingestion
This depends on your SIEM. Most SIEM or log management platforms provide apps or connectors to easily ingest logs from Azure. For Splunk specifically, you will likely need the following apps:
Splunk Add-on for Microsoft Office 365
Splunk Add-on for Microsoft Cloud Services
Microsoft Office 365 Reporting Add-on for Splunk
If you’re using ArcSight, you’ll find the connectors on the ArcSight Marketplace.
If such app is not available for the solution you are using, you can script the pulling with the Azure API. The logs provided are in JSON format so the parsing should be easy.
The details on the integration for Azure activity logs can be found here in the integration column for each type of log. For Office 365 specifically, details can be found here.
Building a list of known attackers
Chances are that you are the target of password spray and bruteforce attacks. This is something that your organization can use to its advantage by building a list of “known attackers”. You can then use this list for:
- Identifying other services targeted by the attackers
- Succesful authentication from these sources to identify compromised account
- Conduct intelligence gathering to determine if your organization is specifically targeted
A reliable way I found to build such list using Azure is to look for an unknown IP generating an account lockout on N distinct accounts. In the search below, I first start by looking for sources generating locked accounts and exclude the IP addresses that already exist in the list to avoid duplicates. Then, I run the iplocation
command in Splunk to get the country and city of each one of them. Finally, I do a distinct count on the UserId field by ClientIP and the source IPs that locked 5 or more accounts are appended to the list.
sourcetype=o365:management:activity
Operation=UserLoginFailed
LogonError=IdsLocked
`comment("Don`t include duplicates")`
NOT [|inputlookup azure_ipv4_blacklist | fields ClientIP]
| iplocation ClientIP
| stats dc(UserId) as DistinctUsersLocked by ClientIP, Country, City
| where DistinctUsersLocked >= 5
| fields ClientIP, Country, City
| outputlookup append=t azure_ipv4_blacklist
Exchange Online
Users sending large amount of emails to external recipients
Attempts to detect potentially compromised hosts spamming external recipients. In large organization, this might generate multiple false-positive due to internal communications, mass mailing, etc so I recommend filtering by excluding some legitimate senders. The threshold can be modified in the where RecipientCount >= 100
part.
sourcetype=ms:o365:reporting:messagetrace
RecipientAddress!="*@<yourdomain.tld>"
| stats dc(RecipientAddress) by SenderAddress, Subject
| rename dc(RecipientAddress) as RecipientCount
| where RecipientCount >= 100
| sort - RecipientCount
Mail forwarding to external recipients
Email forwarding can be set up by both administrators and users. It’s very important to monitor these kind of events to detect insider threats. The difference is that administrators can set up new mail transport rules that affect one or multiple users within Exchange Online while users can only do it on their own mailbox from the Outlook client.
Forwarding to an external recipient by an administrator
Administrator using New-TransportRule
cmdlet
sourcetype=o365:management:activity
Workload=Exchange
Operation="New-TransportRule"
| eval kv=mvzip('Parameters{}.Name', 'Parameters{}.Value', "=")
| mvexpand kv
| rex field=kv "^(?<kv_key>[^=]+)=(?<kv_value>[^=]+)$"
| eval {kv_key}=kv_value
| search kv_key=RedirectMessageTo
| rename kv_value as dest
| search dest!="*@<yourdomain.tld>"
| table _time, user, src, dest
Forwarding to an external recipient by a user
User using the Outlook client
sourcetype=o365:management:activity
Workload=Exchange
Operation="UpdateInboxRules"
"Forward"
| eval kv=mvzip('OperationProperties{}.Name', 'OperationProperties{}.Value', "=")
| mvexpand kv
| rex field=kv "^(?<kv_key>[^=]+)=(?<kv_value>[^=]+)$"
| eval {kv_key}=kv_value
| search kv_key=RuleActions
| rename kv_value as RuleActions
| rex field=RuleActions "(?<dest>(([^<>()\[\]\.,;:\s@\"]+(\.[^<>()\[\]\.,;:\s@\"]+)*)|(\".+\"))@(([^<>()[\]\.,;:\s@\"]+\.)+[^<>()[\]\.,;:\s@\"]{2,}))"
| search dest!="*@<yourdomain.ltd>"
| table _time, user, dest, Operation, RuleActions
Mailbox item deleted by a user other than a mailbox owner
Useful to monitor users with permissions on another user’s mailbox deleting items that could be sensitive or that shouldn’t be deleted in the first place.
index=azure sourcetype=o365:management:activity
Workload=Exchange
AND (Operation=HardDelete OR Operation=SoftDelete)
| where MailboxOwnerUPN!=user
| table _time, MailboxOwnerUPN, Operation, AffectedItems{}.ParentFolder.Path, AffectedItems{}.Subject, user
OneDrive
Users sharing OneDrive items with individuals outside of the organizations
This is self-explanatory and can be useful to detect individuals voluntarily sharing confidential information with external party or typo mistakes. Here too, a list of trusted third-party (partners, subsidiaries, etc) emails could be useful to filter out the noise.
index=azure sourcetype=o365:management:activity
Workload=OneDrive
Operation=AddedToSecureLink
TargetUserOrGroupName!="*@<organization.tld>"
| stats count by _time, UserId, ObjectId, Operation, TargetUserOrGroupName
Azure Active Directory
A note on MFA and legacy authentication
Azure allows legacy authentication using ActiveSync. That means that even if you have MFA enforced in Azure across your organization, as long as legacy authentication is enabled, MFA is useless against successful bruteforcing, password spraying or authentication to a mailbox with a compromised account.
Locked accounts
Identifies locked accounts from existing users. I say existing, because oddly, Azure detects and locks non-existing accounts (I’m not kidding) which explain the exclusion of unknown actor IDs in the "Actor{}.ID"!="Unknown"
part. Removing this would return many false-positive as it would include any locks for accounts that don’t exist in your organization.
sourcetype=o365:management:activity
Workload=AzureActiveDirectory
Operation=UserLoginFailed
LogonError=IdsLocked "Actor{}.ID"!="Unknown"
| iplocation ClientIP
| stats count by UserId, ClientIP, Country, City, ResourceName
| sort - count
Succesful authentication without the use of MFA from a blacklisted IP
This is where the blacklist from earlier can be useful. You can detect compromised accounts using a blacklist of known attackers of your own or using threat intelligence feeds.
sourcetype=o365:management:activity
NOT "OAuth2"
AND Operation=UserLoggedIn
LogonError!=UserAccountNotFound
[| inputlookup <blacklist_lookup>
| fields <ip_field>
| rename <ip_field> as ClientIP]
| table _time, UserId, ClientIP
If using Splunk Enterprise Security, you can replace the |inputlookup
command part and use the ip_intel
macro instead to match on the threat intel aggregated in Splunk.
sourcetype=o365:management:activity
Workload=AzureActiveDirectory
Operation=UserLoggedIn
LogonError!=UserAccountNotFound
[| `ip_intel`
| search threat_collection=ip_intel ip!=""
| fields ip
| rename ip as ClientIP] NOT "OAuth2"
Users with a high count of failed MFA challenges
That one can be noisy because the integration with some products can be very buggy. Otherwise, it’s very useful to detect accounts for which the password was compromised but the authentication failed because MFA was enabled. It’s really up to you and your knowledge of your environment to define the threshold and what is a high count. If you happen to have multiple offices or remote users, I strongly suggest excluding a list of known legitimate public IPs to reduce the noise.
sourcetype=o365:management:activity
LogonError=UserStrongAuthClientAuthNRequiredInterrupt
| stats count by user, ClientIP
| where count >= 10
eDiscovery
eDiscovery is a very sensitive feature, part of the Security & Compliance Center. It can be used to search anything in an indiviual account or all user accounts in your organization. While that seems creepy (and it is, which is why its use should be monitored), it is extremely useful for acquiring evidence in legal cases.
Compliance search started or exported
Anytime actions such as an eDiscovery compliance search is ran, it should be reported and validated by whoever is responsible for overseeing legal cases or HR in your company, due to the sensitivity of the information.
sourcetype=o365:management:activity
Workload=SecurityComplianceCenter
Operation=AlertTriggered
Category=ThreatManagement
Name="eDiscovery search started or exported"
`comment("Use regex to re-write the user field with the user name that triggered the alert.
Otherwise, the user appearing by default is 'SecurityComplianceAlerts'")`
| rex "(?<user>[\w\-\.]+@[\w\-]+\.+[\w\-]{2,4})"
| `map_notable_fields`
Compliance search requesting the deletion of items
Legitimate most of the time (i.e. removing phishing emails from users mailboxes), it can also be used to remove incriminating evidence. Pay a particular attention to the -PurgeType
argument shown in the logs as a HardDelete
indicates permanent removal.
sourcetype=o365:management:activity
Workload=SecurityComplianceCenter
"New-ComplianceSearchAction"
"-Purge"
As important as eDiscovery searches is monitoring users added as administrator in Security & Compliance Center.
sourcetype=o365:management:activity
Workload=SecurityComplianceCenter
"Add-eDiscoveryCaseAdmin"
Conclusion
I hope this will help you getting start. Feel free to message me privately here or on Twitter if you need any help or have any questions. You can also email me at [email protected]
Edit: Added a section on log ingestion and change the format of the queries so they are easier to read.