Forum Discussion
Microsoft Defender - Advanced Hunting API
Hello!
I am looking into utilizing the Advanced Hunting API to search for emails sent by a specific IP / sender / sender domain. Within the Advanced Hunting console, I am able to carry out the following query without any issues:
"message": "'table' operator: Failed to resolve table expression named 'EmailEvents'. Fix semantic errors in your query.
4 Replies
- nt20111290Copper Contributor
After doing some more digging, I was able to get it working. There were a few issues, I was not using the correct endpoint. Additionally, my permissions were not setup correctly as the permissions stated on MS documents were not the ones that I was supposed to use.
Once you create the OAUTH app under "App registrations", make sure to add the "Microsoft Threat Protection -> AdvancedHunting.Read.All" API permission. This is the code that I used:
$tenantId = '[TENANT_ID]' $appId = '[APP_ID]' $appSecret = '[APP_SECRET]' $resourceAppIdUri = 'https://api.security.microsoft.com' $oAuthUri = "https://login.windows.net/$tenantId/oauth2/token" $authBody = [Ordered] @{ resource = $resourceAppIdUri client_id = $appId client_secret = $appSecret grant_type = 'client_credentials' } $authResponse = Invoke-RestMethod -Method Post -Uri $oAuthUri -Body $authBody -ErrorAction Stop $token = $authResponse.access_token $headers = @{ 'Content-Type' = 'application/json' Accept = 'application/json' Authorization = "Bearer $token" } # This assumes the .csv file has a column named 'AllowedSenders' $AntiSpamInboundSenders = (Import-CSv -Path "C:\PATH_TO_CSV_FILE").AllowedSenders # By default, the API can only pull data for the last 30 days foreach ($Sender in $AntiSpamInboundSenders){ Write-Host ("-" * 100) -ForegroundColor Yellow Write-Host "Checking $Sender" # Search by sender domain $query = "EmailEvents | where SenderMailFromDomain contains '$Sender' | where Timestamp > ago(30d) | take 1" # Search by sender # $query = "EmailEvents | where SenderMailFromAddress contains '$Sender' or SenderFromAddress contains '$Sender' | where Timestamp > ago(30d) | take 1" # Search by IP #$query = "EmailEvents | where SenderIPv4 contains '$IP' | where Timestamp > ago(30d) | take 1" $body = ConvertTo-Json -InputObject @{ 'Query' = $query } $queryUrl = "https://api.security.microsoft.com/api/advancedhunting/run" $webResponse = Invoke-WebRequest -Method Post -Uri $queryUrl -Headers $headers -Body $body -ErrorAction Stop $Response = ($webResponse | ConvertFrom-Json).Results if ($Response){ $Sender = $Response.SenderFromAddress $RecipientEmailAddress = $Response.RecipientEmailAddress $Timestamp = $Response.Timestamp $Subject = $Response.Subject Write-Host $Sender Write-Host $RecipientEmailAddress Write-Host $Timestamp Write-Host $Subject }else{ Write-Host "No results" -ForegroundColor Red } Start-Sleep -Seconds 1 # This is to reduce the number of queries sent to not go over the API limit request }
I hope this is useful.
- SpeedRacerBrass ContributorTYVM for the info!
- GrahamP67Copper Contributor
I am having this exact same issues when trying the query 'EmailAttachmentInfo | limit 10' I get a 400 but if i change the query to 'DeviceRegistryEvents | limit 10' the script runs ok.
Odd thing is in Defender I cant see the schema DeviceRegistryEvents.
DId you ever find a fix, is it permissions related?
- SpeedRacerBrass ContributorAny resolution to this issue?