Query Details

Azure Hound Reconnaissance Detected

Query

let AzureHoundGraphQueries = dynamic([
    "https:/graph.microsoft.com/version/servicePrincipals/<UUID>/owners",
    "https:/graph.microsoft.com/version/groups/<UUID>/members",
    "https:/graph.microsoft.com/version/groups/<UUID>/owners",
    "https:/graph.microsoft.com/version/servicePrincipals/<UUID>/appRoleAssignedTo",
    "https:/graph.microsoft.com/version/roleManagement/directory/roleAssignments",
    "https:/graph.microsoft.com/version/applications/<UUID>/owners",
    "https:/graph.microsoft.com/version/devices/<UUID>/registeredOwners",
    "https:/graph.microsoft.com/version/organization",
    "https:/graph.microsoft.com/version/groups",
    "https:/graph.microsoft.com/version/servicePrincipals",
    "https:/graph.microsoft.com/version/applications",
    "https:/graph.microsoft.com/version/roleManagement/directory/roleDefinitions",
    "https:/graph.microsoft.com/version/devices",
    "https:/graph.microsoft.com/version/users"
    ]);
let PotentialMaliciousGraphCalls = materialize (
    MicrosoftGraphActivityLogs
    | where ingestion_time() > ago(35m)
    | extend ObjectId = iff(isempty(UserId), ServicePrincipalId, UserId)
    | extend ObjectType = iff(isempty(UserId), "ServicePrincipalId", "UserId")
    | where RequestUri !has "microsoft.graph.delta"
    | extend NormalizedRequestUri = replace_regex(RequestUri, @'[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12}', @'<UUID>')
    | extend NormalizedRequestUri = replace_regex(NormalizedRequestUri, @'\d+$', @'<UUID>')
    | extend NormalizedRequestUri = replace_regex(NormalizedRequestUri, @'\/+', @'/')
    | extend NormalizedRequestUri = replace_regex(NormalizedRequestUri, @'\/(v1\.0|beta)\/', @'/version/')
    | extend NormalizedRequestUri = replace_regex(NormalizedRequestUri, @'%23EXT%23', @'')
    | extend NormalizedRequestUri = replace_regex(NormalizedRequestUri, @'\/[a-zA-Z0-9+_.\-]+@[a-zA-Z0-9.]+\/', @'/<UUID>/')
    | extend NormalizedRequestUri = replace_regex(NormalizedRequestUri, @'^\/<UUID>', @'')
    | extend NormalizedRequestUri = replace_regex(NormalizedRequestUri, @'\?.*$', @'')
    | summarize
        GraphEndpointsCalled = make_set(NormalizedRequestUri, 1000),
        IPAddresses = make_set(IpAddress)
        by ObjectId, ObjectType
    | project
        ObjectId,
        ObjectType,
        IPAddresses,
        MatchingQueries=set_intersect(AzureHoundGraphQueries, GraphEndpointsCalled)
    | extend ConfidenceScore = round(todouble(array_length(MatchingQueries)) / todouble(array_length(AzureHoundGraphQueries)), 1)
    | where ConfidenceScore > 0.7);
let IPEntities = PotentialMaliciousGraphCalls
    | mv-expand IPAddresses
    | sort by ObjectId
    | extend CurrentRowNumber=row_number(2, prev(ObjectId) != ObjectId)
    | extend IPInformation = bag_pack(@"$id", CurrentRowNumber, "Address", IPAddresses, "Type", "ip")
    | project ObjectId, IPInformation
    | summarize IPInformation = make_set(IPInformation, 150) by ObjectId;
PotentialMaliciousGraphCalls
| join kind=leftouter IPEntities on ObjectId
| project-away IPAddresses, *1, *2

Explanation

The query is designed to detect potential malicious activity in your environment related to Microsoft Graph queries similar to AzureHound. It looks for specific URLs in the Microsoft Graph API and matches them with activity logs. It calculates a confidence score based on the number of matching queries and compares it to a threshold. If the score is above the threshold, it identifies the potential malicious calls and extracts IP addresses associated with them. The query also includes incident configuration settings and entity mappings for further analysis.

Details

Fabian Bader profile picture

Fabian Bader

Released: October 14, 2023

Tables

MicrosoftGraphActivityLogs

Keywords

DevicesIntuneUserMicrosoft GraphServicePrincipalsGroupsOwnersAppRoleAssignedToRoleAssignmentsApplicationsRoleDefinitionsOrganizationUsers

Operators

|=:.()<>!hasextendiffreplace_regexmake_setsummarizeprojectset_intersectroundtodoublearray_lengthwherejoinproject-awaysortbag_packmv-expand

Severity

Medium

Tactics

ReconnaissanceInitialAccess

MITRE Techniques

Frequency: 30m

Period: 40m

Actions

GitHub