Query Details

Multiple Suspicious Inbox Manipulation Rule

Query

let query_frequency = 5m;
let query_period = 2d;
let query_wait = 30m;
let _HomeTenantDomains = toscalar(
    _GetWatchlist("UUID-AADTenantIds")
    | where Notes has "[HomeTenant]"
    | summarize make_list(Domain)
);
let _UntrustedResultTypes = toscalar(
    _GetWatchlist("ResultType-SignInLogsErrorCodes")
    | where Notes has "[MFA]" and Notes has_any ("[Unconfigured]", "[NotCompliant]")
    | summarize make_list(ResultType)
);
let _SuspiciousInboxManipulationRuleAlerts = materialize(
    SecurityAlert
    | where TimeGenerated between (ago(query_wait + query_frequency) .. ago(query_wait))
    | where ProductName has "Microsoft Cloud App Security" and ProviderName != "ASI Scheduled Alerts" and AlertName has "Suspicious inbox manipulation rule"
    //| where CompromisedEntity has_any (_HomeTenantDomains)
    | extend ExtendedProperties = todynamic(ExtendedProperties)
    | project
        Alert_TimeGenerated = TimeGenerated,
        ProductName,
        AlertName,
        Description,
        AlertSeverity,
        Status,
        Tactics,
        Techniques,
        Entities,
        ExtendedProperties,
        AlertLink
    | lookup kind=leftouter
        (AADUserRiskEvents
        | where TimeGenerated > ago(query_period)
        | where OperationName == "User Risk Detection" and Source == "MicrosoftCloudAppSecurity" and RiskEventType == "mcasSuspiciousInboxManipulationRules"
        | summarize arg_max(TimeGenerated, *) by Id
        | mv-apply Auxiliar_AdditionalInfo = AdditionalInfo on (
            where Auxiliar_AdditionalInfo["Key"] == "alertUrl"
            | extend AlertLink = tostring(Auxiliar_AdditionalInfo["Value"])
            )
        | project
            //TimeGenerated,
            UserDisplayName,
            UserPrincipalName,
            UserId,
            AdditionalInfo,
            OriginalRequestId = RequestId,
            CorrelationId,
            RiskDetail,
            RiskLevel,
            RiskState,
            AlertLink
        ) on AlertLink
    | as _Alerts
    | lookup kind=leftouter (
        union
            (SigninLogs
            | where TimeGenerated > ago(query_period)
            | where OriginalRequestId in (toscalar(_Alerts | summarize make_list(OriginalRequestId))) and RiskState == "atRisk"
            | extend
                DeviceDetail = tostring(DeviceDetail),
                TimeReceived = _TimeReceived
            ),
            (AADNonInteractiveUserSignInLogs
            | where TimeGenerated > ago(query_period)
            | where OriginalRequestId in (toscalar(_Alerts | summarize make_list(OriginalRequestId))) and RiskState == "atRisk"
            | extend TimeReceived = _TimeReceived
            )
        | summarize
            arg_max(TimeReceived, *),
            MFASuccess_TimeGenerated = minif(TimeGenerated, ConditionalAccessStatus == "success" and AuthenticationRequirement == "multiFactorAuthentication")
            by OriginalRequestId
        | project
            MFASuccess_TimeGenerated,
            TimeGenerated,
            Type,
            //UserPrincipalName,
            //UserDisplayName,
            IPAddress,
            Location,
            ResultType,
            ResultDescription,
            ClientAppUsed,
            AppDisplayName,
            ResourceDisplayName,
            DeviceDetail,
            UserAgent,
            AuthenticationDetails,
            RiskEventTypes,
            RiskLevelDuringSignIn,
            RiskLevelAggregated,
            //UserId,
            OriginalRequestId//,
            //CorrelationId
        )
        on OriginalRequestId
);
let _UntrustedUserIds = toscalar(
    union
        (_SuspiciousInboxManipulationRuleAlerts
        | join kind=innerunique (
            SigninLogs
            | where TimeGenerated > ago(query_period)
            | where ResultType in (_UntrustedResultTypes)
            | project UserId
            )
            on UserId
        ),
        (AuthenticationMethodChanges(query_period, toscalar(_SuspiciousInboxManipulationRuleAlerts | summarize make_set(UserId)), false)
        )
    | summarize make_set(UserId)
);
_SuspiciousInboxManipulationRuleAlerts
| extend RecentlyConfiguredMFA = UserId in (_UntrustedUserIds)
| extend BenignAlert = case(
        // Remove cases where Defender for Cloud Apps considers the alert solved and the account had MFA configured long ago
        RiskDetail == "aiConfirmedSigninSafe" and RiskState == "dismissed" and not(RecentlyConfiguredMFA), true,
        false
    )
| where not(BenignAlert and AlertSeverity != "High")
| project
    Alert_TimeGenerated,
    TimeGenerated,
    ProductName,
    AlertName,
    Description,
    AlertLink,
    UserDisplayName,
    UserPrincipalName,
    UserId,
    OriginalRequestId,
    CorrelationId,
    AdditionalInfo,
    ExtendedProperties,
    Entities,
    AlertSeverity,
    Tactics,
    Techniques,
    Type,
    IPAddress,
    Location,
    ResultType,
    ResultDescription,
    ClientAppUsed,
    AppDisplayName,
    ResourceDisplayName,
    DeviceDetail,
    UserAgent,
    AuthenticationDetails,
    RiskEventTypes,
    RiskLevelDuringSignIn,
    RiskLevelAggregated

Explanation

The query retrieves suspicious inbox manipulation rule alerts from Microsoft Cloud App Security. It also retrieves additional information about the users associated with these alerts, such as their display name, user principal name, and risk details. The query then filters out alerts that are considered benign or have a severity level other than "High". The final result includes various properties of the alerts and the associated users.

Details

Jose Sebastián Canós profile picture

Jose Sebastián Canós

Released: May 4, 2023

Tables

SecurityAlertAADUserRiskEventsSigninLogsAADNonInteractiveUserSignInLogs

Keywords

Devices,Intune,User,SignInLogs,AADUserRiskEvents,AADNonInteractiveUserSignInLogs,SigninLogs,AuthenticationMethodChanges

Operators

|=|wherehashas_anysummarizemake_listmaterializebetween..and!=extendtodynamicprojectlookupkind=leftouteronunioninarg_maxmv-applyonjoinkind=inneruniquecasenottruefalse

Actions