Query Details

Big Yellow Taxi Sign In

Query

# Big Yellow Taxi - SignIn Based

## Query Information

#### MITRE ATT&CK Technique(s)

| Technique ID | Title    | Link    |
| ---  | --- | --- |
| T1114 | Email Collection | https://attack.mitre.org/techniques/T1114/ |

#### Description
The Big Yellow Taxi detections are based on the compromise of the state department in 2023. The following information was shared: State Department was the first victim to discover the intrusion when, on June 15, 2023, State’s security operations center (SOC) detected anomalies in access to its mail systems. The next day, State observed multiple security alerts from a custom rule it had created, known internally as “Big Yellow Taxi,” that analyzes data from a log known as MailItemsAccessed, which tracks access to Microsoft Exchange Online mailboxes.

This KQL query detects when an IP with a low successful interactive signin rate synchronizes a mailbox.

Be aware: The query for XDR and Sentinel are build with different tables. Defender XDR uses both CloudAppEvents and AADSignInEventsBeta, while Sentinel is build based on the OfficeActivity and SigninLogs tables.

#### Risk
An actor might have compromised the credentials of an useraccount and synchronizes the mailbox.

#### References
- https://www.cisa.gov/sites/default/files/2024-04/CSRB_Review_of_the_Summer_2023_MEO_Intrusion_Final_508c.pdf

## Defender XDR
```KQL
let DefaultInboxFolders = pack_array("Inbox", "Drafts", "Sent Items", "Archive", "rss", "Inbox", "Deleted Items", "Junk Email");
let BinSize = 30m;
let TimeFrame = 14d;
let MaxSuccess = 10;
let MailBoxSyncOperations = CloudAppEvents
// List all MailItemsAccessed that are created because of a sync audit activity.
// The audit volume for sync operations is huge. So, instead of generating an audit record for each mail item that's synched, we generate an audit event for the mail folder containing items that were synched and assume that all mail items in the synched folder have been compromised.
// Info: https://learn.microsoft.com/en-us/purview/audit-log-investigate-accounts?view=o365-worldwide#auditing-sync-access
| where ActionType == "MailItemsAccessed"
| extend MailAccessType = toint(RawEventData.RecordType), IsThrottled = tostring(parse_json(RawEventData.OperationCount))
| where MailAccessType == 2
// Parse synchronised folders. All FolderNames should be considered compromised.
| extend ParentFolder = parse_json(RawEventData.Item).ParentFolder
| extend SyncedFolder = tostring(ParentFolder.Name), Path = tostring(ParentFolder.Path), MailboxGuid = tostring(parse_json(RawEventData.MailboxGuid)), UserId = tolower(parse_json(RawEventData.UserId))
| summarize TotalFolers = dcount(SyncedFolder), Folders = make_set(SyncedFolder) by bin(TimeGenerated, BinSize), UserId, IPAddress, MailboxGuid;
let LargeSyncOperations = MailBoxSyncOperations
// Filter & enrich results
| where TotalFolers >= array_length(DefaultInboxFolders)
| extend GeoIPInfo = geo_info_from_ip_address(IPAddress)
| extend country = tostring(parse_json(GeoIPInfo).country);
LargeSyncOperations
| join kind=inner (AADSignInEventsBeta | where TimeGenerated > startofday(ago(TimeFrame)) and LogonType == '["interactiveUser"]' | project ErrorCode, AccountUpn = tolower(AccountUpn), IPAddress | summarize TotalSuccess = countif(ErrorCode == 0), TotalFailed = countif(ErrorCode != 0) by AccountUpn, IPAddress) on $left.IPAddress == $right.IPAddress, $left.UserId == $right.AccountUpn
// Filter only on IPs with low successrate 
| where TotalSuccess <= MaxSuccess
```
## Sentinel
```KQL
let DefaultInboxFolders = pack_array("Inbox", "Drafts", "Sent Items", "Archive", "rss", "Inbox", "Deleted Items", "Junk Email");
let BinSize = 30m;
let TimeFrame = 14d;
let MaxSuccess = 10;
let MailBoxSyncOperations =  OfficeActivity
// List all MailItemsAccessed that are created because of a sync audit activity.
// The audit volume for sync operations is huge. So, instead of generating an audit record for each mail item that's synched, we generate an audit event for the mail folder containing items that were synched and assume that all mail items in the synched folder have been compromised.
// Info: https://learn.microsoft.com/en-us/purview/audit-log-investigate-accounts?view=o365-worldwide#auditing-sync-access
| where Operation == "MailItemsAccessed"
| extend MailAccessType = tostring(parse_json(OperationProperties[0]).Value), IsThrottled = tostring(parse_json(OperationProperties[1]).Value)
| where MailAccessType == "Sync"
// Parse synchronised folders. All FolderNames should be considered compromised.
| extend ParentFolder = parse_json(Item).ParentFolder
| extend SyncedFolder = tostring(ParentFolder.Name), Path = tostring(ParentFolder.Path)
| summarize TotalFolers = dcount(SyncedFolder), Folders = make_set(SyncedFolder) by bin(TimeGenerated, BinSize), UserId, Client_IPAddress, MailboxGuid;
let LargeSyncOperations = MailBoxSyncOperations
// Filter & enrich results
| where TotalFolers >= array_length(DefaultInboxFolders)
| extend GeoIPInfo = geo_info_from_ip_address(Client_IPAddress)
| extend country = tostring(parse_json(GeoIPInfo).country);
LargeSyncOperations
| join kind=inner (SigninLogs | where TimeGenerated > startofday(ago(TimeFrame)) | project ResultType, UserPrincipalName, IPAddress | summarize TotalSuccess = countif(ResultType == 0), TotalFailed = countif(ResultType != 0) by UserPrincipalName, IPAddress) on $left.Client_IPAddress == $right.IPAddress, $left.UserId == $right.UserPrincipalName
// Filter only on IPs with low successrate 
| where TotalSuccess <= MaxSuccess
```

Explanation

This KQL query is designed to detect potential unauthorized access to Microsoft Exchange Online mailboxes by identifying suspicious mailbox synchronization activities. It is based on an incident involving the State Department in 2023, where anomalies in email access were detected. Here's a simplified explanation of the query:

  1. Purpose: The query aims to identify when an IP address with a low rate of successful interactive sign-ins is used to synchronize a mailbox. This could indicate that an attacker has compromised a user's credentials and is accessing their email.

  2. Data Sources: The query uses different data sources depending on the platform:

    • Defender XDR: Uses CloudAppEvents and AADSignInEventsBeta tables.
    • Sentinel: Uses OfficeActivity and SigninLogs tables.
  3. Process:

    • Mailbox Synchronization Detection: The query looks for "MailItemsAccessed" events, which are generated when mail folders are synchronized. It assumes that all items in a synchronized folder might be compromised.
    • Folder Analysis: It checks if the number of synchronized folders is equal to or greater than a predefined set of default inbox folders, indicating a large synchronization operation.
    • IP Address Analysis: It enriches the data with geographical information based on the IP address used for synchronization.
    • Sign-In Success Rate: It joins the synchronization data with sign-in logs to calculate the success rate of sign-ins from the same IP address. It filters for IPs with a low success rate (10 or fewer successful sign-ins).
  4. Risk: The query helps identify potential credential compromise, where an attacker might be synchronizing a mailbox using stolen credentials.

  5. Output: The result is a list of suspicious synchronization activities, highlighting potential unauthorized access to mailboxes.

This query is part of a broader detection strategy to monitor and respond to potential security incidents involving email access.

Details

Bert-Jan Pals profile picture

Bert-Jan Pals

Released: November 13, 2024

Tables

CloudAppEventsAADSignInEventsBetaOfficeActivitySigninLogs

Keywords

CloudAppEventsAADSignInEventsBetaOfficeActivitySigninLogsMailItemsAccessedMailboxGuidUserIdIPAddressGeoIPInfoCountryTimeGeneratedOperationPropertiesParentFolderSyncedFolderPathUserPrincipalNameClientIPAddress

Operators

letpack_arraywhereextendtointtostringparse_jsonsummarizedcountmake_setbingeo_info_from_ip_addressjoinkindprojectcountifarray_lengthagostartofday

Actions