Threat hunting with PowerShell and Microsoft Defender Advanced Threat Protection

Microsoft Defender’s Advanced Threat Protection API allows for operators to use PowerShell to create applications that can help automate securing, detecting and investigating threats. Its a phenomenal feature of a remarkable platform that every blue team should be using.

In this post I’ll go over how to create an application that uses the API and some ATP queries that can be automated.

The first step is to create a web API app in Azure AD. From the dashboard select App Registrations and click New App Registration. Give your app a name and make sure to select Web App / API for application type. In the last box provide a URL where users can sign in to use the app.

Once the app is created you have to grant API access for the WindowsDefenderATP API. It is best practice to use the principle of least privilege when select permissions for your app. Make sure to click Grant Permissions after you create them.

The last step for setting up your app is generating a key and getting the application token. Save the application password, ID, and tenant ID.

Application Skeleton

To receive the API token we will need this snippet first:

$tenantId = '00000000-0000-0000-0000-000000000000' # Paste your own tenant ID here
$appId = '11111111-1111-1111-1111-111111111111' # Paste your own app ID here
$appSecret = '22222222-2222-2222-2222-222222222222' # Paste your own app secret here

$resourceAppIdUri = 'https://api.securitycenter.windows.com'
$oAuthUri = "https://login.windows.net/$TenantId/oauth2/token"
$body = [Ordered] @{
    resource = "$resourceAppIdUri"
    client_id = "$appId"
    client_secret = "$appSecret"
    grant_type = 'client_credentials'
}
$response = Invoke-RestMethod -Method Post -Uri $oAuthUri -Body $body -ErrorAction Stop
$aadToken = $response.access_token

Now that the token has been received you can use the API to run Microsoft Defender ATP queries like this:

$query = 'QueryExample | limit 10' # Paste your own query here

$url = "https://api.securitycenter.windows.com/api/advancedqueries/run"
$headers = @{ 
    'Content-Type' = 'application/json'
    Accept = 'application/json'
    Authorization = "Bearer $aadToken" 
}
$body = ConvertTo-Json -InputObject @{ 'Query' = $query }
$webResponse = Invoke-WebRequest -Method Post -Uri $url -Headers $headers -Body $body -ErrorAction Stop
$response =  $webResponse | ConvertFrom-Json
$results = $response.Results
$schema = $response.Schema

*The $results variable contains the content of your query and can be manipulated with PowerShell in typical fashion (ConvertTo-Csv, Select-String, etc.)

Advanced Queries

With a basic understanding of setting up and using Microsoft Defender Advanced Threat Protection API lets look at some more advanced queries that we can automate.

To run more advanced queries with multiple lines we need to save them in a separate text file. We can then point to the text file with this line:

$query = [IO.File]::ReadAllText("C:\QueryExample.txt");

And here are some examples of advanced ATP queries that we can automate with PowerShell:

// Detect RDP tunneling
ProcessCreationEvents 
| where EventTime > ago(10d)
| where (ProcessCommandLine contains ":3389" or ProcessCommandLine contains ":6511")
| project EventTime, ComputerName, AccountName, InitiatingProcessFileName, ActionType, 
FileName, ProcessCommandLine, InitiatingProcessCommandLine
// Account Creation
ProcessCreationEvents  
| where EventTime > ago(7d)
| where ProcessCommandLine contains "net user" and ProcessCommandLine contains "/add"
| summarize makeset(ComputerName), makeset(AccountName), makeset(ProcessCommandLine)  by InitiatingProcessFileName
| project EventTime, ComputerName, ProcessCommandLine, InitiatingProcessFileName, AccountName
// Local Accounts Activation
ProcessCreationEvents  
| where EventTime > ago(7d)
| where ProcessCommandLine contains "Administrator /active:yes" or ProcessCommandLine contains "guest /active:yes" 
| summarize makeset(ComputerName), makeset(AccountName), makeset(ProcessCommandLine)  by InitiatingProcessFileName
| project EventTime, ComputerName, ProcessCommandLine, InitiatingProcessFileName, AccountName
// User Addition to Local Groups
ProcessCreationEvents  
| where EventTime > ago(7d)
| where ProcessCommandLine contains "localgroup" and ProcessCommandLine contains "/add" 
and ( ProcessCommandLine contains "Remote Desktop Users" or ProcessCommandLine contains "administrators")
| summarize makeset(ComputerName), makeset(AccountName), makeset(ProcessCommandLine)  by InitiatingProcessFileName
| project EventTime, ComputerName, ProcessCommandLine, InitiatingProcessFileName, AccountName
// Service Creation
ProcessCreationEvents  
| where EventTime > ago(7d)
| where FileName contains "SECEDIT" 
| where ProcessCommandLine == @"secedit.exe /export /cfg ** .inf"
| summarize makeset(ComputerName), makeset(AccountName), makeset(ProcessCommandLine)  by InitiatingProcessFileName
// All Alert Events
AlertEvents 
| where EventTime > ago(7d)
| summarize makeset(FileName), dcount(FileName), makeset(ComputerName), makeset(Category), 
dcount(ComputerName) by Title 
| sort by dcount_ComputerName desc
// Alert Events from Windows Defender
MiscEvents    
| where EventTime > ago(17d)
| where ActionType == "WDAVDetection"
| summarize  makeset(FileName), makeset(InitiatingProcessParentFileName), 
makeset(InitiatingProcessFileName), makeset(InitiatingProcessCommandLine), 
makeset(FolderPath), makeset(InitiatingProcessFolderPath) , makeset(AccountName )  by ComputerName 
// Clearing of Event Log
ProcessCreationEvents  
| where EventTime > ago(10d)
| where ProcessCommandLine contains "call ClearEventlog" or InitiatingProcessCommandLine contains "call ClearEventlog" 
| summarize makeset(ComputerName), makeset(AccountName), dcount(ComputerName)   by InitiatingProcessFileName, ProcessCommandLine
| sort by dcount_ComputerName desc 
// Output Redirection
ProcessCreationEvents  
| where EventTime > ago(10d)
| where ProcessCommandLine contains "2>&1"
| summarize makeset(ComputerName), makeset(AccountName), dcount(ComputerName)   by InitiatingProcessFileName, ProcessCommandLine
| sort by dcount_ComputerName desc 
// Process Dump
ProcessCreationEvents  
| where EventTime > ago(10d)
| where (ProcessCommandLine contains "-accepteula" and ProcessCommandLine contains "1>") 
or (ProcessCommandLine contains "-accepteula" and ProcessCommandLine contains "-ma")
| summarize makeset(ComputerName), makeset(AccountName), dcount(ComputerName)   by InitiatingProcessFileName, ProcessCommandLine
| sort by dcount_ComputerName desc 
// Windows Script Host Network Activity
NetworkCommunicationEvents 
| where EventTime > ago(7d)
| where InitiatingProcessFileName in ("cscript.exe", "wscript.exe")
| summarize makeset(InitiatingProcessParentName), makeset(RemoteUrl), makeset(RemotePort), makeset(InitiatingProcessAccountName)  ,dcount(RemoteUrl) by InitiatingProcessCommandLine
| sort by dcount_RemoteUrl desc 
// PowerShell Network Activity
NetworkCommunicationEvents 
| where EventTime > ago(1d)
| where InitiatingProcessFileName =~ "powershell.exe"
| summarize makeset(RemoteUrl), makeset(RemotePort), makeset(InitiatingProcessAccountName)  ,dcount(RemoteUrl) by InitiatingProcessCommandLine
| sort by dcount_RemoteUrl desc 
// Bitsadmin Executions
ProcessCreationEvents  
| where EventTime > ago(7d)
| where FileName contains "bitsadmin.exe"
| where ProcessCommandLine contains "/TRANSFER" or ProcessCommandLine contains "/CREATE" or ProcessCommandLine contains "/ADDFILE"
or ProcessCommandLine contains "/SETPROXY" or ProcessCommandLine contains "/SETNOTIFYCMDLINE" or ProcessCommandLine contains "/SETCUSTOMHEADERS"
or ProcessCommandLine contains "/SETSECURITYFLAGS" or ProcessCommandLine contains "/SETREPLYFILENAME"
| project EventTime, ComputerName, ProcessCommandLine, InitiatingProcessFileName, AccountName  
| top 1000 by EventTime
// Bitsadmin Transfers
ProcessCreationEvents  
| where EventTime > ago(7d)
| where FileName =~ "bitsadmin.exe"
| where ProcessCommandLine contains "/transfer"
| project EventTime, ComputerName, ProcessCommandLine, InitiatingProcessFileName, AccountName  
| top 1000 by EventTime
// Microsoft Office Abuse 
ProcessCreationEvents  
| where EventTime > ago(1d)
| where InitiatingProcessParentName contains "winword.exe" or InitiatingProcessParentName contains "excel.exe" or InitiatingProcessParentName contains  "powerpnt.exe"
| where FileName contains "cscript" or FileName contains "wscript" or FileName contains "powershell"
| project EventTime, ComputerName, ProcessCommandLine, InitiatingProcessFileName, InitiatingProcessParentName,  AccountName  
| top 1000 by EventTime
// LOLbin RunDLL32 Activity
ProcessCreationEvents  
| where EventTime > ago(7d)
| where FileName =~ "rundll32.exe"
| where ProcessCommandLine contains ",Control_RunDLL"
| summarize makeset(ComputerName), makeset(AccountName), dcount(ComputerName)   by InitiatingProcessFileName, ProcessCommandLine
| sort by dcount_ComputerName desc
// LOLbin RunDLL32 Register Server Activity
ProcessCreationEvents  
| where EventTime > ago(7d)
| where FileName =~ "rundll32.exe"
| where ProcessCommandLine contains "DllRegisterServer"
| summarize makeset(ComputerName), makeset(AccountName)  by InitiatingProcessFileName, ProcessCommandLine
| sort by InitiatingProcessFileName asc 
// LOLbin RunDLL32 Suspicious Executions
ProcessCreationEvents  
| where EventTime > ago(7d)
| where FileName =~ "rundll32.exe"
| where InitiatingProcessFileName in ("winword.exe" , "excel.exe" , "cscript.exe" , "wscript.exe" , "mshta.exe" )
| summarize makeset(ComputerName), makeset(AccountName)  by InitiatingProcessFileName, ProcessCommandLine
| sort by InitiatingProcessFileName asc 
// Curl Executions
ProcessCreationEvents  
| where EventTime > ago(7d)
| where FileName =~ "curl.exe"
| project EventTime, ComputerName, ProcessCommandLine, InitiatingProcessFileName, AccountName  
| top 1000 by EventTime
// At Executions
ProcessCreationEvents  
| where EventTime > ago(7d)
| where FileName =~ "at.exe"
| project EventTime, ComputerName, ProcessCommandLine, InitiatingProcessFileName, AccountName  
| top 1000 by EventTime
// WMIC Process Call
ProcessCreationEvents  
| where EventTime > ago(7d)
| where FileName =~ "WMIC.exe"
| where ProcessCommandLine contains "process call create"
| project EventTime, ComputerName, ProcessCommandLine, InitiatingProcessFileName, AccountName  
| top 1000 by EventTime

In the next post in this series I’ll take the skeleton application along with one of these advanced queries and show how to develop it into a working application.

References:

https://docs.microsoft.com/en-us/windows/security/threat-protection/microsoft-defender-atp/run-advanced-query-sample-powershell

https://github.com/beahunt3r/Windows-Hunting/tree/master/WindowsDefenderATP%20Hunting%20Queries%20

Attack Surface Reduction: Enabling Rules

Microsoft’s Attack Surface Reduction (ASR) helps defend against malware leveraging legitimate applications by implementing rules that actively prevent malicious behavior.

The best part about ASR is that these rules can easily be enabled with a simple PowerShell cmdlet.

For example, rule BE9BA2D9-53EA-4CDC-84E5-9B1EEEE46550 blocks executable content from email.

Enabling these rules can be done by using the Set-MpPreference cmdlet like so:

Set-MpPreference -AttackSurfaceReductionRules_Ids BE9BA2D9-53EA-4CDC-84E5-9B1EEEE46550 -AttackSurfaceReductionRules_Actions Enabled

We call the cmdlet, specify the parameter and the rule ID we want to enable and then enable the specified rule.

Using Add-MpPreference you can also exclude files or entire folders from ASR.

Add-MpPreference -AttackSurfaceReductionOnlyExclusions "<C:\Windows\System32\calc.exe>"

ASR is really robust and is a great way to harden systems. I’ll post more about ASR in the future and show some examples of it in action. 

For now, here is a list of some more ASR rules:

Block Adobe Reader from creating child processes7674ba52-37eb-4a4f-a9a1-f0f9a1619a2cSupportedWindows 10, version 1709 (RS3, build 16299) or greater
Block all Office applications from creating child processesD4F940AB-401B-4EFC-AADC-AD5F3C50688ASupportedWindows 10, version 1709 (RS3, build 16299) or greater
Block credential stealing from the Windows local security authority subsystem (lsass.exe)9e6c4e1f-7d60-472f-ba1a-a39ef669e4b2SupportedWindows 10, version 1709 (RS3, build 16299) or greater
Block executable content from email client and webmailBE9BA2D9-53EA-4CDC-84E5-9B1EEEE46550SupportedWindows 10, version 1709 (RS3, build 16299) or greater
Block executable files from running unless they meet a prevalence, age, or trusted list criterion01443614-cd74-433a-b99e-2ecdc07bfc25SupportedWindows 10, version 1709 (RS3, build 16299) or greater
Block execution of potentially obfuscated scripts5BEB7EFE-FD9A-4556-801D-275E5FFC04CCSupportedWindows 10, version 1709 (RS3, build 16299) or greater
Block JavaScript or VBScript from launching downloaded executable contentD3E037E1-3EB8-44C8-A917-57927947596DSupportedWindows 10, version 1709 (RS3, build 16299) or greater
Block Office applications from creating executable content3B576869-A4EC-4529-8536-B80A7769E899SupportedWindows 10, version 1709 (RS3, build 16299) or greater
Block Office applications from injecting code into other processes75668C1F-73B5-4CF0-BB93-3ECF5CB7CC84SupportedWindows 10, version 1709 (RS3, build 16299) or greater
Block Office communication application from creating child processes26190899-1602-49e8-8b27-eb1d0a1ce869SupportedWindows 10, version 1709 (RS3, build 16299) or greater
Block persistence through WMI event subscriptione6db77e5-3df2-4cf1-b95a-636979351e5bNot supportedWindows 10, version 1903 (build 18362) or greater
Block process creations originating from PSExec and WMI commandsd1e49aac-8f56-4280-b9ba-993a6d77406cSupportedWindows 10, version 1709 (RS3, build 16299) or greater
Block untrusted and unsigned processes that run from USBb2b3f03d-6a65-4f7b-a9c7-1c7ef74a9ba4SupportedWindows 10, version 1709 (RS3, build 16299) or greater
Block Win32 API calls from Office macros92E97FA1-2EDF-4476-BDD6-9DD0B4DDDC7BSupportedWindows 10, version 1709 (RS3, build 16299) or greater
Use advanced protection against ransomwarec1db55ab-c21a-4637-bb3f-a12568109d35SupportedWindows 10, version 1709 (RS3, build 16299) or greater

Reference:

 https://docs.microsoft.com/en-us/windows/security/threat-protection/windows-defender-exploit-guard/attack-surface-reduction-exploit-guard