-
Notifications
You must be signed in to change notification settings - Fork 57
Modules
Automation Modules make it easier to perform routine triage tasks by using a preconfigured modules to retrieve and present data from your environment.
- Base Module
- Entra ID Risks
- File Insights
- Kusto Query Language (KQL)
- Microsoft Defender for Cloud Apps / MCAS (Deprecated)
- Microsoft Defender for Endpoint
- Out of Office
- Microsoft Sentinel Related Alerts
- Microsoft Sentinel Threat Intelligence
- Microsoft Sentinel User Entity Behavior Analytics
- Microsoft Sentinel Watchlists
- Risk Scoring
- Run Playbook
- Create Incident
The Base module processes incident or alert data and prepares it for consumption by other modules. This includes enriching entity data with Entra ID lookups and IP data with Geo location information. The base module must be called before any other modules in this solution as it performs important data enrichment and normalization activities that the other modules will use.
- Account
- IP
- Host
- File
- FileHash
- DnsDomain
- URL
Parameter | Expected Values | Description |
---|---|---|
AddAccountComment | True/False (Default:True) | Add comment to Sentinel incident with account enrichments |
AddIPComment | True/False (Default:True) | Add comment to Sentinel incident with IP enrichments |
EnrichIPsWithGeoData | True/False (Default:True) | When set to true, IP address entities will be returned with Geo enrichment data such as Country, City and LAT/LONG |
Incident or Alert Body | Trigger Body (dynamic content) | Carries the body of the Sentinel Incident or Alert trigger data to the STAT function |
MultiTenantConfig | For cross tenant deployments, this carries the necessary tenant information (see MSSP) | |
VersionCheckType | Major/Minor/Build/None (Default:Build) | Configures what type of STAT updates you will be notified about or disables all notifications |
The Entra ID Risks module (formally known as the Azure Active Directory Risks module) will retrieve the level of risk of the users in Azure AD Identity Protection as well as suspicious/fraudulent MFA Reports and MFA Failures. You need Entra ID P2 licenses to use this module.
- Accounts
Parameter | Expected Values | Description |
---|---|---|
AddIncidentComments | True/False (Default:True) | When set to true, the results of the query will be added to the Sentinel Incident Comments |
AddIncidentTask | True/False (Default:False) | When set to true, a task will be added to the Sentinel incident to review the query results if results are found. |
BaseModuleBody | Body (dynamic content) | The Body should be selected from the Dynamic content of the Base-Module response |
IncidentTaskInstructions | Markdown Text | A list of instructions you want to include in the task |
LookbackInDays | 1-90 | This defines how far back to look through the SecurityAlert tables in Sentinel |
MFAFailureLookup | True/False (Default:True) | This enables the lookup the SigninLogs table for MFA failures |
MFAFraudLookup | True/False (Default:True) | This enables the lookup the AuditLogs table for suspicious MFA and MFA fraud reports |
Property | Description |
---|---|
AnalyzedEntities | Returns the number of entities analyzed (returns 0 if no Account entities were found) |
HighestRiskLevel | Returns the highest risk level found in Entra ID for all entities(returns unknown if no Account entities were found) |
FailedMFATotalCount | Returns the total failed MFA request in the SigninLogs table for all entities (returns 0 if no Account entities were found) |
MFAFraudTotalCount | Returns the total MFA fraud reports in the AuditLogs table for all entities (returns 0 if no Account entities were found) |
ModuleName | The internal Name of the Playbook |
DetailedResults | An array containing the details for each entity |
{
"AnalyzedEntities": 2,
"FailedMFATotalCount": 31,
"HighestRiskLevel": "low",
"MFAFraudTotalCount": 1,
"ModuleName": "AADRisksModule",
"DetailedResults": [
{
"UserFailedMFACount": 0,
"UserMFAFraudCount": 1,
"UserId": "17de02b6-b883-4f4f-9acd-02ec09d160cd",
"UserPrincipalName": "alice@contoso.com",
"UserRiskLevel": "none"
},
{
"UserFailedMFACount": 31,
"UserMFAFraudCount": 0,
"UserId": "7ec8eef7-784d-4afd-91a1-1fd433bfc3ee",
"UserPrincipalName": "john@contoso.com",
"UserRiskLevel": "low"
}
]
}
The File Insights module will check if the entities are found as email attachments and will run the FileProfile() function on the provided hashes.
- File
- FileHash
Parameter | Expected Values | Description |
---|---|---|
BaseModuleBody | Body (dynamic content) | The Body should be selected from the Dynamic content of the Base-Module response |
AddIncidentComments | True/False (Default:True) | When set to true, the results of the query will be added to the Sentinel Incident Comments |
Property | Description |
---|---|
AnalyzedEntities | Number of entities analyzed in the module |
EntitiesAttachmentCount | Number of times the entities were found in email attachements |
HashedInvalidSignatureCount | Number of hashes of files with no or invalid signatures found |
HashesLinkedToThreatCount | Number of hashes of files linked with a known threat found |
HashesNotMicrosoftSignedCount | Number of hashes of files not signed by Microsoft found |
HashesThreatList | List of known threat for hashes parsed witht the function FileProfile() |
MaximumGlobalPrevalence | Highest global prevalence score found in the FileProfile() output |
MinimumGlobalPrevalence | Lowest global prevalence score found in the FileProfile() output |
ModuleName | The internal Name of the Playbook |
DetailedResults | An array of Files and HashFiles |
{
"AnalyzedEntities": 2,
"EntitiesAttachmentCount": 0,
"HashedInvalidSignatureCount": 0,
"HashesLinkedToThreatCount": 0,
"HashesNotMicrosoftSignedCount": 0,
"HashesThreatList": [],
"MaximumGlobalPrevalence": 948591,
"MinimumGlobalPrevalence": 751340,
"ModuleName": "FileModule",
"DetailedResults": [
{
"EmailAttachmentCount": 0,
"EmailAttachmentFileSize": "",
"EmailAttachmentFirstSeen": "",
"EmailAttachmentLastSeen": "",
"FileName": "",
"GlobalFirstSeen": "2018-09-17T22:09:03.4724305Z",
"GlobalLastSeen": "2021-11-04T13:34:41.1027033Z",
"GlobalPrevalence": 948591,
"IsCertificateValid": 1,
"MD5": "7353f60b1739074eb17c5f4dddefe239",
"Publisher": "Microsoft Corporation",
"SHA1": "6cbce4a295c163791b60fc23d285e6d84f28ee4c",
"SHA256": "de96a6e69944335375dc1ac238336066889d9ffc7d73628ef4fe1b1b160ab32c",
"SignatureState": "SignedValid",
"ThreatName": ""
},
{
"EmailAttachmentCount": 0,
"EmailAttachmentFileSize": "",
"EmailAttachmentFirstSeen": "",
"EmailAttachmentLastSeen": "",
"FileName": "",
"GlobalFirstSeen": "2018-09-18T21:23:46.1435835Z",
"GlobalLastSeen": "2021-11-04T13:32:43.879195Z",
"GlobalPrevalence": 751340,
"IsCertificateValid": 1,
"MD5": "ae61d8f04bcde8158304067913160b31",
"Publisher": "Microsoft Corporation",
"SHA1": "4f4970c3545972fea2bc1984d597fc810e6321e0",
"SHA256": "25c8266d2bc1d5626dcdf72419838b397d28d44d00ac09f02ff4e421b43ec369",
"SignatureState": "SignedValid",
"ThreatName": ""
}]
}
This module allows you to run custom KQL queries against Microsoft Sentinel, Azure Data Explorer or Microsoft 365 Advanced Hunting. In these queries you can filter the results based on the entities data from you Microsoft Sentinel Incident
- Account
- IP Address
- Host
Parameter | Expected Values | Description |
---|---|---|
BaseModuleBody | Body (dynamic content) | The Body should be selected from the Dynamic content of the Base-Module response |
AddIncidentComments | True/False (Default:True) | When set to true, the results of the query will be added to the Sentinel Incident Comments. A maximum of 10 search results will be included |
AddIncidentTask | True/False (Default:False) | When set to true, a task will be added to the Sentinel incident to review the query results if results are found. |
IncidentTaskInstructions | Markdown Text | A list of instructions you want to include in the task |
KQL Query | KQL Query | The KQL Query you wish to execute |
LookbackInDays | 1-90 | This defines how far back to look back in the data, note this is limited to 30 days for Microsoft 365 Advanced Hunting |
QueryDescription | Text String (optional) | This description will be added to the incident comments to provide additional context on the query |
RunQueryAgainst | Sentinel/M365 | This defines if the KQL query will run against the Microsoft Sentinel data or the M365 Defender Advanced Hunting data |
In your KQL query you will have access to 3 tables built from the entity data of your Sentinel Incident. You can use these tables through join or where clauses in your query to locate the results you are looking for.
For best results, limit your query results to as few columns of data as possible. Including many columns may result in the ability to add comments to the incident to fail. Also, while you query may return many records and the count will always be returned, on the the first 10 records will include detailed column data. Consider using project and/or summarize in your query to optimize the returned results to just the data that is needed.
- Only the first 10 records will be returned in the detailed results array. When using this array, such as when using the option to AddIncidentComments consider using the sort function so the most important records are returned in the first 10. This does not impact the ResultsCount that is returned.
- It is recommended to limit the number of column data returned to what is needed. Consider the use of project or summarize to do this.
- If you need your query to assess multiple time ranges, for example comparing the last day of data to the last week of data, ensure to set the LookbackInDays to the larger time window and incoroporate the more granular time windows through filter in your KQL query.
- Only the first 10 records will be returned in the detailed results array. When using this array, such as when using the option to AddIncidentComments consider using the sort or summarize functions so the most important records are returned in the first 10. This does not impact the ResultsCount that is returned.
- It is recommended to limit the number of column data returned to what is needed. Consider the use of project or summarize to do this.
- When querying Microsoft 365 Security advanced hunting the LookbackInDays parameter is ignored. To limit your query to a specific time period please include a time filter in your KQL query syntax such as:
DeviceLogonEvents
| where Timestamp > ago(7d)
To send a query Azure Data Explorer using this module select Sentinel in the RunQueryAgainst input. To perform this query we use the Azure Monitor proxy.
Queries to Azure Data Explorer should be formatted as:
adx('https://clustername.kusto.windows.net/DatabaseName').TableName
Additionally, you must give the STAT identity access to the Database Viewer role on all ADX databases you wish to query. This is not done by the GrantPermissions.ps1 PowerShell script.
More information on granting permissions in ADX can be found here
When adding a task to an Incident a link to the query results will be supplied in the task. This link will always search the time window when the KQL query was executed. However, if you include relative time filters such as ago(7d) the results will not be consistent over time as this will be evaluated at the time filter will be evaluated at the time you click the link.
If you need to embed a time range in your query, it is recommended to encode the static time range into the query.
accountEntities
UserPrincipalName | SamAccountName | ObjectSID | AADUserId | ManagerUPN |
---|---|---|---|---|
user@contoso.com | user | S-1-5-21-565368899-1117343155-2447612341-32656 | f4ab0870-413b-4716-845c-426821fc9e96 | manager@contoso.com |
ipEntities
IPAddress | Latitude | Longitude | Country | State |
---|---|---|---|---|
40.82.187.199 | 43.64280 | -79.38705 | canada | ontario |
hostEntities
FQDN | Hostname |
---|---|
computer01.contoso.com | computer01 |
These tables can be used in your KQL queries in any way you like. For example, if you wanted to check if any of the users in your Incident have failed to login to Azure AD due to a bad password more than 10 times, you could write a query like this:
accountEntities
| join kind=inner (SigninLogs | where ResultType == 50126 | summarize FailureCount=count() by UserPrincipalName | where FailureCount >= 10) on UserPrincipalName
If you would prefer to use a where statement instead of a join, the following query would produce a similar result:
let UPNs = accountEntities | project UserPrincipalName;
SigninLogs
| where UserPrincipalName in (UPNs) and ResultType == 50126
| summarize FailureCount=count() by UserPrincipalName
| where FailureCount >= 10
incidentArmId
incidentArmId will contain the string value of the Incident ARM Id such as: '/subscriptions/subId/resourceGroups/rgName/providers/Microsoft.OperationalInsights/workspaces/workspacename/providers/Microsoft.SecurityInsights/Incidents/incidentId'
This can be used if you want to retrieve the current incident details in a KQL query, such as the RelatedAnalyticRuleIds, AlertIds or other incident properties
SecurityIncident
| where IncidentUrl endswith incidentArmId
| summarize arg_max(TimeGenerated, *) by IncidentNumber
| project Title, Severity, Status, RelatedAnalyticRuleIds, AlertIds
Property | Description |
---|---|
DetailedResults | An array of each record found by the KQL query |
LogicAppRunId | Returns the Run id for that instance of the module run history to assist in troubleshooting |
ModuleName | The internal Name of the Playbook |
ResultsCount | Number of results found by the KQL query |
ResultsFound | true/false indicating if results were found by the KQL query |
{
"DetailedResults": [
{
"Result1Column1Name": "Column1Value",
"Result1Column2Name": "Column2Value",
"Result1Column3Name": "Column3Value",
"Resul1tColumn4Name": "Column4Value",
"Result1Column5Name": "Column5Value"
},
{
"Result2Column1Name": "Column1Value",
"Result2Column2Name": "Column2Value",
"Result2Column3Name": "Column3Value",
"Resul12Column4Name": "Column4Value",
"Result2Column5Name": "Column5Value"
}
],
"ModuleName": "KQLModule",
"ResultsCount": 2,
"ResultsFound": true,
}
Warning
The Investigation Priority score used by this module is being retired by Microsoft, as announced in Message Center MC889532. The use of this module will likely begin to fail in most environments in November 2024. STAT releases 2.0.17 and greater () will deprecate this module. This work is being tracked under .
The Microsoft Defender for Cloud Apps (formally known as Microsoft Cloud App Security) module will get the investigation score of the account entities of the incident along with the history of that score and trending information.
- Account
Parameter | Expected Values | Description |
---|---|---|
BaseModuleBody | Body (dynamic content) | The Body should be selected from the Dynamic content of the Base-Module response |
AddIncidentComments | True/False (Default:True) | When set to true, the results of the query will be added to the Sentinel Incident Comments |
TopUserThreshold | 0-100 (integer) | Return how many users are a part of the top X of account ordered by investigation score (X being the Top user threshold) |
ScoreThreshold | Score (integer) | Minimum investigation score for a user |
Property | Description |
---|---|
AnalysedEntities | Number of entities analyzed |
AboveThreholdCount | Number of accounts foud above the specified threshold |
MaximumScore | Maximum score found for all entities |
HighestScorePercentile | Highest score percentile for all entities |
TopUserThresholdCount | Number of accounts in the selected top number of users (defined by TopUserThreshold) |
AnyThreatScoreTrendingUp | Return true if any accounts have a score trending up |
ModuleName | The internal Name of the Playbook |
DetailedResults | An array of user with their respective score |
{
"AboveThreholdCount": 0,
"AnalyzedEntities": 1,
"HighestScorePercentile": 0,
"TopUserThresholdCount": 0,
"AnyThreatScoreTrendingUp": false,
"DetailedResults": [
{
"ThreatScore": 270,
"IsTopThreatScore": false,
"UserId": "312b4fab-fa2e-43d4-9885-5a78ae6772b9",
"UserPrincipalName": "bob@xontoso.com",
"ThreatScoreTrendingUp": false,
"LastThreatScorePercentile": 0,
"ThreatScoreHistory": [
{
"dateFormatted": "20221011",
"dateUtc": 1665531216000,
"score": 0,
"percentile": 0,
"breakdown": {}
},
{
"dateFormatted": "20221010",
"dateUtc": 1665444816000,
"score": 0,
"percentile": 0,
"breakdown": {}
}
]
}
],
"MaximumScore": 270,
"ModuleName": "MCASModule"
}
The Microsoft Defender for Endpoint module will return the risk score and exposure level from Microsoft Defender for Endpoint of all the machines on which a user logged on interactively and for all machines with specified IP addresses.
- Accounts (if the accounts have objectSid available)
- IPs
- Hosts (using the MdatpDeviceId if present, else construct the FQDN from the raw entitiy)
Parameter | Expected Values | Description |
---|---|---|
BaseModuleBody | Body (dynamic content) | The Body should be selected from the Dynamic content of the Base-Module response |
AddIncidentComments | True/False (Default:True) | When set to true, the results of the query will be added to the Sentinel Incident Comments |
LookbackInDays | 1-30 | This defines how far back to look through the DeviceLogonEvents table in Microsoft Defender for Endpoint |
Property | Description |
---|---|
AnalyzedEntities | Number of entities analyzed in the module |
UsersHighestRiskScore | The highest risk score found for all machines of a specific user |
UsersHighestExposureLevel | The highest exposure level found for all machines of a specific user |
IPsHighestExposureLevel | The highest risk score level found for all machines with a specific IP |
IPsHighestRiskScore | The highest exposure level found for all machines with a specific IP |
HostsHighestExposureLevel | The highest risk score level found for all hosts matching the MdatpDeviceId or the FQDN |
HostsHighestRiskScore | The highest exposure level found for all hosts matching the MdatpDeviceId or the FQDN |
ModuleName | The internal Name of the Playbook |
DetailedResults | An array of the accounts and IPs analyzed |
{
"AnalyzedEntities": 4,
"IPsHighestExposureLevel": "Unknown",
"IPsHighestRiskScore": "Unknown",
"UsersHighestExposureLevel": "Medium",
"UsersHighestRiskScore": "High",
"HostsHighestExposureLevel": "Medium",
"HostsHighestRiskScore": "Low",
"ModuleName": "MDEModule",
"DetailedResults":
{
"Accounts": [
{
"UserDevices": [],
"UserHighestExposureLevel": "Unknown",
"UserHighestRiskScore": "Unknown",
"UserId": "102b4fab-0a2e-43d4-9885-5a78ae6772a8",
"UserPrincipalName": "bob@contoso.com",
"UserSid": "S-1-5-21-1703388146-2621323185-1663833956-49112"
},
{
"UserHighestExposureLevel": "Medium",
"UserHighestRiskScore": "High",
"UserId": "ff2b4fab-0a2e-43d4-ed85-5a78ae6714a8",
"UserPrincipalName": "alice@contoso.com",
"UserSid": "S-1-5-21-1703388146-2621323185-1663833956-1111",
"UserDevices": [
{
"id": "d8992d10a94d4aad9ffe4853823456501544d300",
"computerDnsName": "client1.contoso.com",
"riskScore": "High",
"exposureLevel": "Low"
},
{
"id": "12392d10a94d4aad9ffe4853823456501544d3e4",
"computerDnsName": "client2.contoso.com",
"riskScore": "Low",
"exposureLevel": "Medium"
}]
}],
"IPs": [],
"Hosts": [
{
"id": "b9e57eb3ab888957a952f2b9fedd719264f5dbd9",
"computerDnsName": "server91.contoso.com",
"riskScore": "Low",
"exposureLevel": "Medium"
}]
}
}
The Out of Office module (also known as Office 365 Out of Office module) takes user entity data and determines if the user has an Out of Office message set on their Microsoft 365 mailbox.
- Account
Parameter | Expected Values | Description |
---|---|---|
BaseModuleBody | Body (dynamic content) | The Body should be selected from the Dynamic content of the Base-Module response |
AddIncidentComments | True/False (Default:True) | When set to true, the results of the query will be added to the Sentinel Incident Comments |
Property | Description |
---|---|
AllUsersInOffice | true/false if all checked users have Automatic Replies disabled |
AllUsersOutOfOffice | true/false if all checked users have Automatic Replies enabled |
DetailedResults | An array of Automatic Reply information for by user |
UsersInOffice | Integer representing number of users with Automatic Replies disabled |
UsersOutOfOffice | Integer representing number of users with Automatic Replies enabled |
UsersUnknown | Integer representing number of users with an unknown Automatic Replies status, this could be due to the user not having a mailbox in Microsoft 365 or other issues |
{
"AllUsersInOffice": true,
"AllUsersOutOfOffice": false,
"DetailedResults": [
{
"ExternalMessage": "",
"InternalMessage": "",
"OOFStatus": "disabled",
"UPN": "user1@contoso.com"
}
],
"UsersInOffice": 1,
"UsersOutOfOffice": 0,
"UsersUnknown": 0
}
The Related Alerts module takes the incident entity data and determines if other alerts about those same entities exist in Microsoft Sentinel within a specified timeframe.
- Account
- Host
- IP Address
Parameter | Expected Values | Description |
---|---|---|
Base Module Body | Body (dynamic content) | The Body should be selected from the Dynamic content of the Base-Module response |
AddIncidentComments | True/False (Default:True) | When set to true, the results of the query will be added to the Sentinel Incident Comments |
AddIncidentTask | True/False (Default:False) | When set to true, a task will be added to the Sentinel incident to review the query results if results are found. |
AlertKQLFilter | KQL Statement (Default:none) | Optionally, a KQL statement can be added to filter out alerts you want to exclude from this module, see Alert Filtering below for more inforomation |
CheckAccountEntityMatches | True/False (Default:True) | When set to true, the module will look for related alerts based on the Account entity type |
CheckHostEntityMatches | True/False (Default:True) | When set to true, the module will look for related alerts based on the Host entity type |
CheckIPEntityMatches | True/False (Default:True) | When set to true, the module will look for related alerts based on the IP entity type |
IncidentTaskInstructions | Markdown Text | A list of instructions you want to include in the task |
LookbackInDays | 1-90 | This defines how far back to look through the SecurityAlert tables in Sentinel |
Some alerts in the SecurityAlert table may be of limited security value when performing an automated triage and you may want to filter them out so they are not considered. The AlertKQLFilter property of this module allows you to add an optional KQL filter to limit the alerts that are returned by this module. This filter only supports adding one or more | where
statements, though other KQL may work, modifying the returned columns (reducing columns, adding columns, renaming) may cause the module to fail or produce unexpected results.
The AlertKQLFilter is applied in the KQL query after the most recent version of the alert has been returned and the entities array has been expanded using an mv-expand. To test a filter statement in Log search, use this KQL statement to test and place your filter at the end. Other filters, not shown below, are applied automatically in the module, such as only returning alerts that match the incidents account or ip entities.
SecurityAlert
| where TimeGenerated > ago(14d)
| summarize arg_max(TimeGenerated, *) by SystemAlertId
| where SystemAlertId !in (currentIncidentAlerts) or isFusionIncident
| mv-expand todynamic(Entities)
Property | Description |
---|---|
AllTactics | An array of unique MITRE tactics including all tactics linked directly to the incident as well as any found in related alerts |
AllTacticsCount | Count of unique MITRE tactics from AllTactics |
DetailedResults | An array of each related alert that was found |
HighestSeverityAlert | The severity of the highest severity alert found (High, Medium, Low or Informational) |
ModuleName | The internal Name of the Playbook |
RelatedAlertsCount | Number of related alerts found. This number may exceed the sum of other related alert counts as an alert may be related to more than one entity type. |
RelatedAlertsFound | true/false indicating if related alerts were found |
RelatedAccountAlertsCount | Number of alerts related to account entity found |
RelatedAccountAlertsFound | true/false indicating if alerts related to account entity were found |
RelatedHostAlertsCount | Number of alerts related to host entity found |
RelatedHostAlertsFound | true/false indicating if alerts related to host entity were found |
RelatedIPAlertsCount | Number of alerts related to ip entity found |
RelatedIPAlertsFound | true/false indicating if alerts related to ip entity were found |
{
"AllTactics": ["InitialAccess","Impact"],
"AllTacticsCount": 2,
"DetailedResults": [
{
"StartTime": "2021-11-03T12:16:29.541Z",
"DisplayName": "Alert1",
"AlertSeverity": "Informational",
"SystemAlertId": "55d2036d-e471-4210-bfcd-fead43b85cf8",
"ProviderName": "ASI Scheduled Alerts",
"Tactics": "InitialAccess",
"AccountEntityMatch": true,
"IPEntityMatch": true,
"HostEntityMatch": true
},
{
"StartTime": "2021-11-01T20:23:45.386Z",
"DisplayName": "Alert2",
"AlertSeverity": "Informational",
"SystemAlertId": "5342baa5-531d-7496-6f5f-b3e9c4a077dd",
"ProviderName": "ASI Scheduled Alerts",
"Tactics": "Impact",
"AccountEntityMatch": true,
"IPEntityMatch": false,
"HostEntityMatch": true
}
],
"HighestSeverityAlert": "Informational",
"ModuleName": "RelatedAlerts",
"RelatedAccountAlertsCount": 2,
"RelatedAccountAlertsFound": true,
"RelatedAlertsCount": 2,
"RelatedAlertsFound": true,
"RelatedHostAlertsCount": 2,
"RelatedHostAlertsFound": true,
"RelatedIPAlertsCount": 1,
"RelatedIPAlertsFound": true
}
The Threat Intelligence module takes the incident entities and allows you to cross reference them against data in the ThreatIntelligenceIndicator table.
- IP
- Domain
- URL
- FileHash
Parameter | Expected Values | Description |
---|---|---|
BaseModuleBody | Body (dynamic content) | The Body should be selected from the Dynamic content of the Base-Module response |
AddIncidentComments | True/False (Default:True) | When set to true, the results of the query will be added to the Sentinel Incident Comments |
AddIncidentTask | True/False (Default:False) | When set to true, a task will be added to the Sentinel incident to review the query results if results are found. |
CheckDomains | True/False (Default:True) | Check Domain Entities for Threat Intelligence Matches |
CheckFileHashes | True/False (Default:True) | Check File Hash Entities for Theat Intelligence Matches |
CheckIPs | True/False (Default:True) | Check IP Entities for Threat Intelligence Matches |
CheckURLs | True/False (Default:True) | Check URL Entities for Threat Intelligence Matches |
IncidentTaskInstructions | Markdown Text | A list of instructions you want to include in the task |
Property | Description |
---|---|
AnyTIFound | true/false if any Threat Intelligence was found for any indicator type |
DetailedResults | An array of Threat Intelligence that was matched with the incident entities |
DomainEntitiesCount | Count of Domain Entities in Incident |
DomainEntitiesWithTI | Count of Domain Entities with Threat Intelligence matches |
DomainTIFound | true/false if Domain Threat Intelligence was found |
FileHashEntitiesCount | Count of FileHash Entities in Incident |
FileHashEntitiesWithTI | Count of FileHash Entities with Threat Intelligence matches |
FileHashTIFound | true/false if FIleHash Threat Intelligence was found |
IPEntitiesCount | Count of IP Entities in Incident |
IPEntitiesWithTI | Count of IP Entities with Threat Intelligence matches |
IPTIFound | true/false if IP Threat Intelligence was found |
ModuleName | The internal Name of the Playbook |
TotalTIMatchCount | Count of all Threat Intelligence matches |
URLEntitiesCount | Count of URL Entities in Incident |
URLEntitiesWithTI | Count of URL Entities with Threat Intelligence matches |
URLTIFound | true/false if URL Threat Intelligence was found |
{
"AnyTIFound": true,
"DetailedResults": [
{
"TIType": "IP",
"TIData": "40.126.28.11",
"SourceSystem": "Azure Sentinel",
"Description": "TestingOnly Benign IP",
"ThreatType": "benign",
"ConfidenceScore": 0,
"IndicatorId": "73F782D74E5A8D0A144076FCEF875D2ED16A59EBC15E1A0053D9BEFBB7C35F8D"
},
{
"TIType": "URL",
"TIData": "https://www.contoso.com/folder/index.aspx",
"SourceSystem": "Azure Sentinel",
"Description": "TestingOnly-BenignUrl",
"ThreatType": "benign",
"ConfidenceScore": 0,
"IndicatorId": "6090F19551C4B7C7B5F7DEE6B1FC79B4457B3ACD6928313A860815190BC160D6"
},
{
"TIType": "Domain",
"TIData": "contoso.com",
"SourceSystem": "Azure Sentinel",
"Description": "BenignThreat-Testing only",
"ThreatType": "benign",
"ConfidenceScore": 0,
"IndicatorId": "EAB98E3ED850F21B5F23905E905B0338FC37B11D82428741F15F4505E9BDF9DA"
}
],
"DomainEntitiesCount": 1,
"DomainEntitiesWithTI": 1,
"DomainTIFound": true,
"FileHashEntitiesCount": 1,
"FileHashEntitiesWithTI": 0,
"FileHashTIFound": false,
"IPEntitiesCount": 1,
"IPEntitiesWithTI": 1,
"IPTIFound": true,
"ModuleName": "TIModule",
"TotalTIMatchCount": 3,
"URLEntitiesCount": 1,
"URLEntitiesWithTI": 1,
"URLTIFound": true
}
The UEBA module allows you to take user entity data and lookup those users in the BehaviorAnalytics table to identity activities performed by the user that deviate from their previous patterns of behavior.
- Account
Parameter | Expected Values | Description |
---|---|---|
BaseModuleBody | Body (dynamic content) | The Body should be selected from the Dynamic content of the Base-Module response |
AddIncidentComments | Yes/No | When set to yes, the results of the query will be added to the Sentinel Incident Comments |
AddIncidentTask | True/False (Default:False) | When set to true, a task will be added to the Sentinel incident to review the query results if results are found. |
IncidentTaskInstructions | Markdown Text | A list of instructions you want to include in the task |
LookbackInDays | 1-90 | This defines how far back to look through the UEBA tables in Sentinel |
MinimumInvestigationPriority | 1-10 | Only BehaviourAnalytics records with an InvestirgationPriority of >= this value will be considered |
Property | Description |
---|---|
AllEntityEventCount | Count of all related BehaviorAnalytics records |
AllEntityInvestigationPriorityAverage | Average investigation priority of all related BehaviorAnalytics records |
AllEntityInvestigationPriorityMax | Maximum investigation priority of all related BehaviorAnalytics records |
AllEntityInvestigationPrioritySum | Sum of investigation priority of all related BehaviorAnalytics records |
AnomalyCount | Count of matching account anomalies from the Anomalies table |
AnomalyTactics | Array of unique MITRE tactics associated with matching account anomalies |
AnomalyTacticsCount | Count of unique MITRE tactics from associated anomalies |
DetailedResults | An array of UEBA investigration priority values by UserPrincipalName |
InvestigationPrioritiesFound | true if any investigation priorities are found in all related BehaviorAnalytics records, otherwise false |
ModuleName | The internal Name of the Playbook |
ThreatIntelFound | true/false based on matching threat intelligence in BehaviorAnalytics table |
ThreatIntelMatchCount | Count of matching BehaviorAnalytics entries with matching threat intel |
{
"AllEntityEventCount": 222,
"AllEntityInvestigationPriorityAverage": 4.031073446327683,
"AllEntityInvestigationPriorityMax": 5,
"AllEntityInvestigationPrioritySum": 899,
"AnomalyCount": 8,
"AnomalyTactics": [
"Persistence",
"DefenseEvasion",
"InitialAccess"
],
"AnomalyTacticsCount": 3,
"DetailedResults": [
{
"InvestigationPrioritySum": 180,
"InvestigationPriorityAverage": 4,
"InvestigationPriorityMax": 4,
"EventCount": 45,
"ThreatIntelMatchCount": 1,
"UserPrincipalName": "user1@contoso.com"
},
{
"InvestigationPrioritySum": 719,
"InvestigationPriorityAverage": 4.062146892655368,
"InvestigationPriorityMax": 5,
"EventCount": 177,
"ThreatIntelMatchCount": 2,
"UserPrincipalName": "user2@contoso.com"
}
],
"InvestigationPrioritiesFound": true,
"ModuleName": "UEBAModule",
"ThreatIntelFound": true,
"ThreatIntelMatchCount": 3
}
The Microsoft Sentinel Watchlists module allows you to compare entity data from an incident against a watchlist to determine if that entity is present. This supports watchlists containing columns with UserPrincipalNames, IP Addresses, or CIDR address blocks.
- Account (UPN)
- IP Address
- Host (FQDN)
Note: For best results with host entities, the WatchlistKey should be in FQDN format (hostname.contoso.com) although the module will also attempt hostname matches.
Parameter | Expected Values | Description |
---|---|---|
BaseModuleBody | Body (dynamic content) | The Body should be selected from the Dynamic content of the Base-Module response |
AddIncidentComments | True/False (Default:True) | When set to true, the results of the query will be added to the Sentinel Incident Comments |
AddIncidentTask | True/False (Default:False) | When set to true, a task will be added to the Sentinel incident to review the query results if results are found. |
IncidentTaskInstructions | Markdown Text | A list of instructions you want to include in the task |
WatchlistKey | ColumnName | The column name of the watchlist to match with the entity data, such as the UPN or IP Address. If the WatchlistKey has a space in it, you must enter the key in the following format: ['Key Name'] |
WatchlistKeyDataType | upn, ip, cidr or fqdn | The type of data in the WatchlistKey column. Use CIDR if the WactchlistKey contains subnets using CIDR notation |
WatchlistAlias | Sentinel Watchlist Alias | This is the Alias of the Watchlist in Sentinel you want to check. |
Property | Description |
---|---|
DetailedResults | An Array of detailed results from each item that was checked against the watchlist |
EntitiesAnalyzedCount | Count of entities checked against the watchlist |
EntitiesOnWatchlist | True if any entities were found on the watchlist |
EntitiesOnWatchlistCount | Count of entities found on the watchlist |
ModuleName | The internal Name of the Playbook |
WatchListName | Name of the watchlist that was queried |
{
"DetailedResults": [
{
"OnWatchlist": false,
"EntityData": "40.126.28.11"
}
],
"EntitiesAnalyzedCount": 1,
"EntitiesOnWatchlist": false,
"EntitiesOnWatchlistCount": 0,
"ModuleName": "WatchlistModule",
"WatchlistName": "TrustedNetworks"
}
The Risk Scoring module takes the output from other STAT modules to calculate a relative risk score. This score can then be consumed by the calling Logic app to define different outcomes based on the score returned.
- Entra ID Risks Module
- Microsoft Defender for Endpoint Module
- Related Alerts Module
- KQL Module
- Threat Intelligence Module
- Watchlist Module
- User Entity Behavior Analytics Module
- File Module
- Custom Content Scoring
When scoring Entra ID Risks module the following default scores are assigned based on the user risk level in Entra ID Protection
Identity Protection Risk Level | Score |
---|---|
High | 10 |
Medium | 5 |
Low | 3 |
None | 0 |
Note: If ScorePerItem=True, the sum of all user scores will be returned. If ScorePerItem=False, only the score of the highest severity user will be returned.
When scoring the Defender for Endpoint module, the devices risk score will be calcuated from the UsersHighestRiskScore, HostsHighestRiskScore and IPsHighestRiskScore values from the MDE module. If ScorePerItem=True, the sum of the 3 values will be returned as the risk score, otherwise only the maximum value will be returned.
MDE HighestRiskScore | Score |
---|---|
High | 10 |
Medium | 5 |
Low | 3 |
Informational | 1 |
When scoring the Related Alerts module consider the following default scores are assigned based on the Alert Severity:
AlertSeverity | Score |
---|---|
High | 10 |
Medium | 5 |
Low | 3 |
Informational | 1 |
Note: If ScorePerItem=True, the sum of all alert scores will be returned. If ScorePerItem=False, only the score of the highest severity alert will be returned.
Additionally, a score of 10 is added per unique MITRE tactic associated with the incident and any related alerts.
When scoring the KQL Module if ScorePerItem=True then the returned score will be 5 * ItemCount * ScoreMultiplier. If ScorePerItem=False the returned score will be 5 * ScoreMultiplier if 1 or more results are returned
When scoring the Threat Intelligence Module if ScorePerItem=True then the returned score will be 10 * MatchedTIItemCount * ScoreMultiplier. If ScorePerItem=False the returned score will be 10 * ScoreMultiplier if 1 or more matching pieces of TI is found
When scoring the Watchlist Module if ScorePerItem=True then the returned score will be 10 * WatchlistMatchCount * ScoreMultiplier. If ScorePerItem=False the returned score will be 10 * ScoreMultiplier if 1 or more watchlist match is found
Scoring for the UEBA module consists of 3 parts:
Score Part | Explanation |
---|---|
InvestigationPriorityMax | The maximum investigation priority score is taken and mulitpled by the ScoreMultiplier |
ThreatIntelMatchCount | If realted threat intelligence matches are found in the BehaviorAnalytics table, 10 * ScoreMultiplier is added to the score |
AnomalyTacticsCount | If related anomalies around found in the Anomalies table the number of uniqure MITRE tactics is determined and the AnomalyTacticsCount * 10 * ScoreMultiplier is added to the score |
If ScorePerItem=False, AllEntityInvestigationPriorityMax is used and the global ThreatIntelMatchCount is used instead of the entity level counts.
When scoring the File Module the calculated score is based on (HashesLinkedToThreatCount * 10 * ScoreMultiplier) + (HashesInvalidSignatureCount * 5 * ScoreMultiplier). The ScorePerItem setting has no impact on the scoring of this module.
When scoring the MDCA module, if ScorePerItem=True the score is calculated based on (AboveThresholdCount * 10 * ScoreMultiplier). If ScorePerItem=False, the score is calculated if the AboveThresholdCount > 0 as (10 * ScoreMultiplier).
In addition to scoring STAT modules, the Scoring module can also incorporate score data from other sources such as 3rd party threat intelligence, 3rd party vulnerability management systems and other Microsoft sources not presently covered by STAT.
To add custom content to the scoring module you will need to retieve the necessary information for your score from the source, determine an appropriate score to assign and then format the message to send to the scoring module.
Module Input | Value |
Module Body |
{
"ModuleName": "Custom",
"ScoringData": [
{
"Score": 5,
"ScoreLabel": "Virus Total - Medium Risk"
},
{
"Score": 10,
"ScoreLabel": "Custom Vulnerability Management Score"
}
]
} |
Score Label | This field is ignored when sending custom data, the label from the JSON data in Module Body will be used |
Score Multiplier | The Score passed in the Module Body will be multiplied by this value |
Score Per Item | This field is ignored when sending custom data, all scores in the array will be processed regardless of this setting |
Note: Each item in the ScoringData array must include a Score property as an integer. If this property is not included, or it is not an integer the score item will be dropped.
Parameter | Expected Values | Description |
---|---|---|
BaseModuleBody | Body (dynamic content) | The Body should be selected from the Dynamic content of the Base-Module response |
AddIncidentComments | True/False (Default:True) | When set to true, the results of the scoring module will be added to the Sentinel Incident Comments |
ScoringData-ModuleBody | Body (dynamic content) | The Body of a supported module you want to score |
ScoringData-ScoreLabel | string (Default:ScoredModuleName) | Used to label the score outputs in the comment added to the incident |
ScoringData-ScoreMultiplier | Decimal value (Default:1) | Default scores will be multiplied by this value, this can be a negative value which will result in the cumulative score being reduced |
ScoreingData-ScorePerItem | true/false (Default:true) | true if you want to score the input on a row level (per alert or record) |
Property | Description |
---|---|
DetailedResults | An array of each scored item with label and score |
TotalScore | Sum of all scored items |
{
"DetailedResults": [
{
"Score": 25,
"ScoreSource": "Bad Password KQL Query"
},
{
"Score": 10,
"ScoreSource": "Related Alerts - Initial Access Incident"
},
{
"Score": 5,
"ScoreSource": "Related Alerts - Multiple Password changes"
},
{
"Score": -10,
"ScoreSource": "Watchlist - Check for Trusted IP Location"
}
],
"TotalScore": 30
}
The Run Playbook module can be used to invoke other Microsoft Sentinel Playbooks. In situations where you are analyzing an incident using STAT, under certain conditions you may want to initiate other playbooks instead of incorporating the logic of those playbooks into your main STAT triage playbooks. This module allows you to reuse other playbooks as needed during an incident triage.
The identity of the function needs to have the Microsoft Sentinel Playbook Operators role on the logic app you wish to call.
- N/A
Parameter | Expected Values | Description |
---|---|---|
BaseModuleBody | Body (dynamic content) | The Body should be selected from the Dynamic content of the Base-Module response |
AddIncidentComments | True/False (Default:True) | When set to true, the start of the Playbook will be logged to the incident comments |
LogicAppResourceId | resourceId | The resourceId of the Logic App (Playbook) you want to run against the incident |
TenantId | Entra ID (string) | The Entra ID Tenant Id associated with the subscriptions of the Logic App |
This module does not return a Body unless there is an error, but a status code is always included in the return.
Status Code | Description |
---|---|
200 | The called playbook successfully started |
500 | An error caused the called playbook from starting. This is usually due to the STAT managed identity not having Microsoft Sentinel Responder on the Sentinel resource group, the STAT managed identity not having Microsoft Sentinel Playbook Operator on the playbook you are trying to run or Microsoft Sentinel (Azure Security Insights) not having the Microsoft Sentinel Automation Contributor role on the resource group where the Playbook is located. This is needed to add a comment. |
Allows for the creation of Sentinel incidents from a Sentinel alert where an incident does not already exist. This is useful when triaging large volumes of low-quality alerts to determine which should be elevated to an incident.
ℹ️ Note: Incident creation is only supported when starting from an alert triggered Playbook.
- N/A
Parameter | Expected Values | Description |
---|---|---|
Title | Title (string) | Title of the incident |
Description | Description (string) | Description of the incident |
Severity | Informational|Low|Medium|High (string) | The severity of the incident (default is medium) |
{
"IncidentNumber": 123,
"IncidentUrl": "https://...",
"IncidentARMId": "/..."
}