Forum Discussion
Use Powershell to get data from Defender Advanced Hunting Queries
- Dec 17, 2022403 is usually permissions - check the token as it's either expired or doesn't contain all relevant scopes.
I'm having some issues on my tries to use the Microsoft Graph API query directly, which was my first attempt. So usually I call the request like this:
$vulnResponse = Invoke-WebRequest -Method Get -Uri $vulnUrl -Headers $headers -ErrorAction StopSo, according to the documentation I have to build out a query like this:
https://graph.microsoft.com/beta/security/runHuntingQuery { "query": "DeviceTvmSoftwareVulnerabilities | summarize count() by VulnerabilitySeverityLevel" }"But when I run the web request I get a 401 (Unauthorized), which is strange, because on the permissions side I got the Ti.Read.All allowed, and also, if I run a query to the Microsoft Defender API (https://api-eu.securitycenter.windows.com/api/vulnerabilities/machinesVulnerabilities?) I can run it without any permission issues.
This is what I have configured on the API permissions:
What am I missing here?
Thanks
- dmarquesgnDec 15, 2022Iron Contributor
You're totally right. I misconfused Ti.Read.All with ThreatHuning.Read.All
Now I've overcome the 401, but I get a 400 error. This is my actual code:
$tenantId = 'redacted' ### Tenant ID $appId = 'redacted' ### Paste your Application ID here $appSecret = 'redacted' ### Paste your Application secret here #$resourceAppIdUri = 'https://api.securitycenter.windows.com' $resourceAppIdUri = 'https://graph.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 #NOTE: This returns your access token, and below we pull out the token that will be used as the authorization token going forward. $token = $authResponse.access_token $headers = @{ 'Content-Type' = 'application/json' Accept = 'application/json' Authorization = "Bearer $token" } $vulnUrl = 'https://graph.microsoft.com/beta/security/runHuntingQuery { "query": "DeviceTvmSoftwareVulnerabilities | summarize count() by VulnerabilitySeverityLevel" }' $vulnResponse = Invoke-WebRequest -Method Post -Uri $vulnUrl -Headers $headers -ErrorAction StopThe error shown is this:
Invoke-WebRequest : The remote server returned an error: (400) Bad Request.Any idea of what might be doing wrong here?
Thanks
- VasilMichevDec 15, 2022MVPPass the actual query in the body of the request. Refer to the examples in the documentation article above.
- dmarquesgnDec 16, 2022Iron Contributor
Hi, I changed the request for this format:
$vulnUrl = ' { "query": "DeviceTvmSoftwareVulnerabilities | summarize count() by VulnerabilitySeverityLevel" } ' $vulnUrlUri = 'https://graph.microsoft.com/beta/security/runHuntingQuery' $vulnResponse = Invoke-WebRequest -Method POST -Uri $vulnUrlUri -Body $vulnUrl -Headers $headers -ErrorAction StopBut I've got an error:
Invoke-WebRequest : The remote server returned an error: (403) Forbidden.
So I'm still missing something here. The permissions are supposed to be ok now. What am I still missing?
Thanks