Query Details

Office Activity Teams Phishing Campaign

Query

let query_frequency = 15m;
let query_period = 30m;
let threshold = 5;
let _ExpectedDomains = toscalar(
    _GetWatchlist("UUID-AADTenantIds")
    | where Notes has "[ChatCreated]"
    | summarize make_list(TenantId)
);
OfficeActivity
| where TimeGenerated > ago(query_period)
| where Operation == "ChatCreated" and CommunicationType == "OneOnOne"
| extend
    SenderOrganizationId = tostring(Members[0]["OrganizationId"]),
    SenderDisplayName = tostring(Members[0]["DisplayName"]),
    SenderUPN = tostring(Members[0]["UPN"]),
    RecipientOrganizationId = tostring(Members[1]["OrganizationId"]),
    RecipientDisplayName = tostring(Members[1]["DisplayName"]),
    RecipientUPN = tostring(Members[1]["UPN"])
| where not(SenderOrganizationId in (_ExpectedDomains))
| extend SenderOrganizationDomain = tostring(split(SenderUPN, "@")[-1])
| as _Events
| join kind=leftsemi (
    _Events
    // query_period should be 2 * query_frequency
    | evaluate activity_counts_metrics(Type, TimeGenerated, ago(query_period), now(), query_frequency, SenderOrganizationId)
    | summarize
        arg_min(PreviousTimeGenerated = TimeGenerated, PreviousCount = ["count"]),
        arg_max(CurrentTimeGenerated = TimeGenerated, CurrentCount = ["count"])
        by SenderOrganizationId
    | where CurrentTimeGenerated > ago(query_period)
    | extend PreviousCount = iff(PreviousTimeGenerated == CurrentTimeGenerated, 0, PreviousCount)
    | where (not(PreviousCount > threshold) and CurrentCount > threshold)
        or ((CurrentCount - PreviousCount) > threshold)
    ) on SenderOrganizationId
| join kind=leftouter (
    OfficeActivity
    | where TimeGenerated > ago(query_period)
    | where Operation == "MessageSent"
    | where UserId in (toscalar(_Events | summarize make_set(UserId)))
    | summarize SenderIPAddress = make_set(ClientIP) by UserId
    ) on UserId
| join kind=leftouter (
    OfficeActivity
    | where TimeGenerated > ago(query_period)
    | where Operation in ("MemberAdded", "MemberRemoved")
    | summarize
        MemberAdded = tobool(binary_all_or(tolong(Operation == "MemberAdded"))),
        MemberRemoved = tobool(binary_all_or(tolong(Operation == "MemberRemoved")))
        by ChatThreadId, UserId
    ) on ChatThreadId, $left.RecipientUPN == $right.UserId
| summarize
    StartTime = min(TimeGenerated),
    EndTime = max(TimeGenerated),
    SenderOrganizationDomain = array_sort_asc(make_set(SenderOrganizationDomain)),
    SenderDisplayNames = array_sort_asc(make_set(SenderDisplayName)),
    SenderUPNs = array_sort_asc(make_set(SenderUPN)),
    UserIds = array_sort_asc(make_set(UserId)),
    SenderIPAddresses = make_set_if(SenderIPAddress, isnotempty(SenderIPAddress)),
    RecipientOrganizationIds = array_sort_asc(make_set(RecipientOrganizationId)),
    RecipientUPNs = array_sort_asc(make_set(RecipientUPN)),
    RecipientCount = count_distinct(RecipientUPN),
    RecipientAcceptedChat = array_sort_asc(make_set_if(RecipientUPN, MemberAdded)),
    RecipientRemovedChat = array_sort_asc(make_set_if(RecipientUPN, MemberRemoved)),
    ChatNames = array_sort_asc(make_set(ChatName)),
    take_any(OfficeWorkload, RecordType, Operation)
    by SenderOrganizationId
| where RecipientCount > threshold
| project
    StartTime,
    EndTime,
    OfficeWorkload,
    RecordType,
    Operation,
    ChatNames,
    SenderOrganizationDomain,
    SenderUPNs,
    UserIds,
    SenderIPAddresses,
    SenderDisplayNames,
    SenderOrganizationId,
    RecipientCount,
    RecipientUPNs,
    RecipientAcceptedChat,
    RecipientRemovedChat,
    RecipientOrganizationIds

Explanation

This query is looking for Office 365 chat activities where one-on-one chats are created. It checks for unusual patterns in chat activity based on a specified threshold and time period. The query identifies the organizations involved in the chats, the users participating, and any changes in chat membership. It then summarizes the data and filters out chats with a high number of recipients. Finally, it projects specific fields for analysis.

Details

Jose Sebastián Canós profile picture

Jose Sebastián Canós

Released: February 21, 2024

Tables

OfficeActivity

Keywords

Devices,Intune,User

Operators

| where| summarize| extend| as| join| evaluate| arg_min| arg_max| iff| toscalar| split| ago| now| make_list| make_set| make_set_if| count_distinct| array_sort_asc| binary_all_or| tobool| tolong| in| take_any| project| by| not| and| or| has| ==| !=| >| <| >=| <=| -

Actions