This commit is contained in:
JP Bourget 2023-09-27 00:13:26 -04:00
Родитель e7ab1c2d11
Коммит 58e0390cf2
8 изменённых файлов: 1003 добавлений и 64 удалений

Просмотреть файл

@ -0,0 +1,87 @@
id: f8960f1c-07d2-512b-9c41-952772d40c84
name: Threat Connect TI map Domain entity to DnsEvents
version: 1.0.0
kind: Scheduled
description: |
Identifies a match in DnsEvents from any ThreatConnect Domain IOC from TI
severity: Medium
requiredDataConnectors:
- connectorId: DNS
dataTypes:
- DnsEvents
- connectorId: ThreatIntelligence
dataTypes:
- ThreatIntelligenceIndicator
- connectorId: ThreatIntelligenceTaxii
dataTypes:
- ThreatIntelligenceIndicator
- connectorId: MicrosoftDefenderThreatIntelligence
dataTypes:
- ThreatIntelligenceIndicator
queryFrequency: 1h
queryPeriod: 7d
triggerOperator: gt
triggerThreshold: 0
tactics:
- Impact
query: |
// Define the lookback periods for time-based filters
let dt_lookBack = 1h; // Look back 1 hour for DNS events
let ioc_lookBack = 7d; // Look back 7 days for threat intelligence indicators
// Fetch threat intelligence indicators related to domains
let Domain_Indicators = ThreatIntelligenceIndicator
| where TimeGenerated >= ago(ioc_lookBack)
| summarize LatestIndicatorTime = arg_max(TimeGenerated, *) by IndicatorId
| where Active == true and ExpirationDateTime > now()
// Filter out non ThreatConnect TI Sources
| where SourceSystem startswith "ThreatConnect-"
// Filter out indicators without domain names
| where isnotempty(DomainName)
| extend TI_DomainEntity = DomainName;
// Create a list of TLDs in our threat feed for later validation
let maxListSize = 100000; // Define the maximum allowed size for each list
let list_tlds = Domain_Indicators
| extend parts = split(DomainName, '.')
| extend tld = parts[(array_length(parts)-1)]
| summarize count() by tostring(tld)
| project tld
| summarize make_list(tld, maxListSize);
// Perform a join between domain indicators and DNS events to identify potential malicious activity
Domain_Indicators
// Use innerunique to keep performance fast and result set low, as we only need one match to indicate potential malicious activity that needs investigation
| join kind=innerunique (
DnsEvents
| where TimeGenerated > ago(dt_lookBack)
// Extract domain patterns from syslog message
| where isnotempty(Name)
| extend parts = split(Name, '.')
| extend tld = parts[(array_length(parts)-1)]
// Validate parsed domain by checking if the TLD is in the list of TLDs in our threat feed
| where tld in~ (list_tlds)
| extend DNS_TimeGenerated = TimeGenerated
) on $left.TI_DomainEntity==$right.Name
// Filter out DNS events that occurred after the expiration of the corresponding indicator
| where DNS_TimeGenerated < ExpirationDateTime
// Group the results by IndicatorId and Name, and keep the DNS event with the latest timestamp
| summarize DNS_TimeGenerated = arg_max(DNS_TimeGenerated, *) by IndicatorId, Name
// Select the desired output fields
| project DNS_TimeGenerated, Description, ActivityGroupNames, IndicatorId, ThreatType, ExpirationDateTime, ConfidenceScore, Url, Computer, ClientIP, Name, QueryType, Type, TI_DomainEntity
// Extract hostname and DNS domain from the Computer field
| extend HostName = tostring(split(Computer, '.', 0)[0]), DnsDomain = tostring(strcat_array(array_slice(split(Computer, '.'), 1, -1), '.'))
// Rename the timestamp field
| extend timestamp = DNS_TimeGenerated
entityMappings:
- entityType: Host
fieldMappings:
- identifier: HostName
columnName: HostName
- identifier: DnsDomain
columnName: DnsDomain
- entityType: IP
fieldMappings:
- identifier: Address
columnName: ClientIP
- entityType: URL
fieldMappings:
- identifier: Url
columnName: Url

Просмотреть файл

@ -0,0 +1,66 @@
id: 4f7ade3e-7121-5274-83ea-d7ed22a01fea
name: ThreatConnect TI map Email entity to OfficeActivity
version: 1.2.4
kind: Scheduled
description: |
'Identifies a match in OfficeActivity table from any Email IOC from ThreatConnect TI'
severity: Medium
requiredDataConnectors:
- connectorId: Office365
dataTypes:
- OfficeActivity
- connectorId: ThreatIntelligence
dataTypes:
- ThreatIntelligenceIndicator
- connectorId: ThreatIntelligenceTaxii
dataTypes:
- ThreatIntelligenceIndicator
- connectorId: MicrosoftDefenderThreatIntelligence
dataTypes:
- ThreatIntelligenceIndicator
queryFrequency: 1h
queryPeriod: 14d
triggerOperator: gt
triggerThreshold: 0
tactics:
- Impact
query: |
let dt_lookBack = 1h;
let ioc_lookBack = 14d;
let emailregex = @'^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$';
ThreatIntelligenceIndicator
| where TimeGenerated >= ago(ioc_lookBack) and ExpirationDateTime > now()
| summarize LatestIndicatorTime = arg_max(TimeGenerated, *) by IndicatorId
| where Active == true
// Filter out non ThreatConnect TI Sources
| where SourceSystem startswith "ThreatConnect-"
//Filtering the table for Email related IOCs
| where isnotempty(EmailSenderAddress)
// using innerunique to keep perf fast and result set low, we only need one match to indicate potential malicious activity that needs to be investigated
| join kind=innerunique (
OfficeActivity | where TimeGenerated >= ago(dt_lookBack) and isnotempty(UserId)
| where UserId matches regex emailregex
| extend OfficeActivity_TimeGenerated = TimeGenerated
)
on $left.EmailSenderAddress == $right.UserId
| where OfficeActivity_TimeGenerated < ExpirationDateTime
| summarize OfficeActivity_TimeGenerated = arg_max(OfficeActivity_TimeGenerated, *) by IndicatorId, UserId
| project OfficeActivity_TimeGenerated, Description, ActivityGroupNames, IndicatorId, ThreatType, Url, ExpirationDateTime, ConfidenceScore,
EmailSenderName, EmailRecipient, EmailSourceDomain, EmailSourceIpAddress, EmailSubject, FileHashValue, FileHashType, UserId, ClientIP, Operation, UserType, RecordType, OfficeWorkload, Parameters
| extend Name = tostring(split(UserId, '@', 0)[0]), UPNSuffix = tostring(split(UserId, '@', 1)[0])
| extend timestamp = OfficeActivity_TimeGenerated
entityMappings:
- entityType: Account
fieldMappings:
- identifier: Name
columnName: Name
- identifier: UPNSuffix
columnName: UPNSuffix
- entityType: IP
fieldMappings:
- identifier: Address
columnName: ClientIP
- entityType: URL
fieldMappings:
- identifier: Url
columnName: Url

Просмотреть файл

@ -0,0 +1,81 @@
id: ecb68ce7-c309-59a7-a8de-07ccf2a0ea4f
name: ThreatConnect TI map Email entity to SigninLogs
version: 1.2.4
kind: Scheduled
description: |
'Identifies a match in SigninLogs table from any Email IOC from ThreatConnect TI'
severity: Medium
requiredDataConnectors:
- connectorId: ThreatIntelligence
dataTypes:
- ThreatIntelligenceIndicator
- connectorId: ThreatIntelligenceTaxii
dataTypes:
- ThreatIntelligenceIndicator
- connectorId: AzureActiveDirectory
dataTypes:
- SigninLogs
- connectorId: AzureActiveDirectory
dataTypes:
- AADNonInteractiveUserSignInLogs
- connectorId: MicrosoftDefenderThreatIntelligence
dataTypes:
- ThreatIntelligenceIndicator
queryFrequency: 1h
queryPeriod: 14d
triggerOperator: gt
triggerThreshold: 0
tactics:
- Impact
query: |
let dt_lookBack = 1h;
let ioc_lookBack = 14d;
let emailregex = @'^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$';
let aadFunc = (tableName:string){
ThreatIntelligenceIndicator
| where TimeGenerated >= ago(ioc_lookBack) and ExpirationDateTime > now()
| summarize LatestIndicatorTime = arg_max(TimeGenerated, *) by IndicatorId
| where Active == true
// Filter out non ThreatConnect TI Sources
| where SourceSystem startswith "ThreatConnect-"
//Filtering the table for Email related IOCs
| where isnotempty(EmailSenderAddress)
// using innerunique to keep perf fast and result set low, we only need one match to indicate potential malicious activity that needs to be investigated
| join kind=innerunique (
table(tableName) | where TimeGenerated >= ago(dt_lookBack) and isnotempty(UserPrincipalName)
//Normalizing the column to lower case for exact match with EmailSenderAddress column
| extend UserPrincipalName = tolower(UserPrincipalName)
| where UserPrincipalName matches regex emailregex
| extend Status = todynamic(DeviceDetail), LocationDetails = todynamic(LocationDetails)
| extend StatusCode = tostring(Status.errorCode), StatusDetails = tostring(Status.additionalDetails)
| extend State = tostring(LocationDetails.state), City = tostring(LocationDetails.city), Region = tostring(LocationDetails.countryOrRegion)
// renaming timestamp column so it is clear the log this came from SigninLogs table
| extend SigninLogs_TimeGenerated = TimeGenerated, Type = Type
)
on $left.EmailSenderAddress == $right.UserPrincipalName
| where SigninLogs_TimeGenerated < ExpirationDateTime
| summarize SigninLogs_TimeGenerated = arg_max(SigninLogs_TimeGenerated, *) by IndicatorId, UserPrincipalName
| project SigninLogs_TimeGenerated, Description, ActivityGroupNames, IndicatorId, ThreatType, Url, ExpirationDateTime, ConfidenceScore,
EmailSenderName, EmailRecipient, EmailSourceDomain, EmailSourceIpAddress, EmailSubject, FileHashValue, FileHashType, IPAddress, UserPrincipalName, AppDisplayName,
StatusCode, StatusDetails, NetworkIP, NetworkDestinationIP, NetworkSourceIP, Type
| extend Name = tostring(split(UserPrincipalName, '@', 0)[0]), UPNSuffix = tostring(split(UserPrincipalName, '@', 1)[0])
| extend timestamp = SigninLogs_TimeGenerated
};
let aadSignin = aadFunc("SigninLogs");
let aadNonInt = aadFunc("AADNonInteractiveUserSignInLogs");
union isfuzzy=true aadSignin, aadNonInt
entityMappings:
- entityType: Account
fieldMappings:
- identifier: Name
columnName: Name
- identifier: UPNSuffix
columnName: UPNSuffix
- entityType: IP
fieldMappings:
- identifier: Address
columnName: IPAddress
- entityType: URL
fieldMappings:
- identifier: Url
columnName: Url

Просмотреть файл

@ -0,0 +1,63 @@
id: 12c3b31b-66a6-53ff-b6ab-6ae45e56dc92
name: ThreatConnect TI Map URL Entity to OfficeActivity Data
version: 1.0.0
kind: Scheduled
description: |
'This query identifies any URL indicators of compromise (IOCs) from threat intelligence (TI) by searching for matches in OfficeActivity data.'
severity: Medium
requiredDataConnectors:
- connectorId: Office365
dataTypes:
- OfficeActivity
- connectorId: ThreatIntelligence
dataTypes:
- ThreatIntelligenceIndicator
- connectorId: MicrosoftDefenderThreatIntelligence
dataTypes:
- ThreatIntelligenceIndicator
queryFrequency: 1h
queryPeriod: 14d
triggerOperator: gt
triggerThreshold: 0
tactics:
- Impact
query: |
let dt_lookBack = 1h;
let ioc_lookBack = 14d;
ThreatIntelligenceIndicator
| where TimeGenerated >= ago(ioc_lookBack) and ExpirationDateTime > now()
| summarize LatestIndicatorTime = arg_max(TimeGenerated, *) by IndicatorId
| where Active == true
// Filter out non ThreatConnect TI Sources
| where SourceSystem startswith "ThreatConnect-"
// Picking up only IOC's that contain the entities we want
| where isnotempty(Url)
// using innerunique to keep perf fast and result set low, we only need one match to indicate potential malicious activity that needs to be investigated
| join kind=innerunique (
OfficeActivity
| where TimeGenerated >= ago(dt_lookBack)
//Extract the Url from a number of potential fields
| extend Url = iif(OfficeWorkload == "AzureActiveDirectory",extract("(http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\\(\\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+);", 1,ModifiedProperties),tostring(parse_json(ModifiedProperties)[12].NewValue))
| where isnotempty(Url)
// Ensure we get a clean URL
| extend Url = tostring(split(Url, ';')[0])
| extend OfficeActivity_TimeGenerated = TimeGenerated
// Project a single user identity that we can use for entity mapping
| extend User = iif(isnotempty(UserId), UserId, iif(isnotempty(Actor), tostring(parse_json(Actor)[0].ID), tostring(parse_json(Parameters)[0].Value)))
) on Url
| where OfficeActivity_TimeGenerated < ExpirationDateTime
| summarize OfficeActivity_TimeGenerated = arg_max(OfficeActivity_TimeGenerated, *) by IndicatorId, Url
| project OfficeActivity_TimeGenerated, Description, ActivityGroupNames, IndicatorId, ThreatType, ExpirationDateTime, ConfidenceScore, Operation,
UserType, OfficeWorkload, Parameters, Url, User
| extend timestamp = OfficeActivity_TimeGenerated, Name = tostring(split(User, '@', 0)[0]), UPNSuffix = tostring(split(User, '@', 1)[0])
entityMappings:
- entityType: Account
fieldMappings:
- identifier: Name
columnName: Name
- identifier: UPNSuffix
columnName: UPNSuffix
- entityType: URL
fieldMappings:
- identifier: Url
columnName: Url

Просмотреть файл

@ -6,11 +6,15 @@
"WorkbookDescription": [],
"Workbooks": ["Solutions/ThreatConnect/Workbooks/ThreatConnectOverview.json"],
"WorkbookBladeDescription": "",
"AnalyticalRuleBladeDescription": "This solution installs the following analytic rule templates. After installing the solution, create and enable analytic rules in Manage solution view.",
"AnalyticalRuleBladeDescription": "This solution installs the following analytic rule templates. After installing the solution, create and enable analytic rules in Manage solution view. These rules require data from the ThreatConnect connector, and are meant to demonstrate what is possible by filering on just ThreatConnect TI.",
"HuntingQueryBladeDescription": "",
"PlaybooksBladeDescription": "",
"Analytic Rules": [
"Solutions/ThreatConnect/Analytic Rules/ThreatConnect_IPEntity_NetworkSessions.yaml"
"Solutions/ThreatConnect/Analytic Rules/ThreatConnect_DomainEntity_DnsEvents.yaml",
"Solutions/ThreatConnect/Analytic Rules/ThreatConnect_EmailEntity_OfficeActivity.yaml",
"Solutions/ThreatConnect/Analytic Rules/ThreatConnect_EmailEntity_SigninLogs.yaml",
"Solutions/ThreatConnect/Analytic Rules/ThreatConnect_IPEntity_NetworkSessions.yaml",
"Solutions/ThreatConnect/Analytic Rules/ThreatConnect_URLEntity_OfficeActivity.yaml"
],
"Playbooks": [],
"PlaybookDescription": [],

Двоичные данные
Solutions/ThreatConnect/Package/3.0.0.zip

Двоичный файл не отображается.

Просмотреть файл

@ -6,7 +6,7 @@
"config": {
"isWizard": false,
"basics": {
"description": "<img src=\"https://raw.githubusercontent.com/Azure/Azure-Sentinel/master/Logos/ThreatConnect.svg\" width=\"75px\" height=\"75px\">\n\n**Note:** _There may be [known issues](https://aka.ms/sentinelsolutionsknownissues) pertaining to this Solution, please refer to them before installing._\n\nThe [ThreatConnect Threat Intelligence Platform](https://threatconnect.com/) solution for Microsoft Sentinel provides Workbooks and Analytics to demonstrate the value of ThreatConnect data inside Microsoft Sentintel.\n\n**Workbooks:** 1, **Analytic Rules:** 1\n\n[Learn more about Microsoft Sentinel](https://aka.ms/azuresentinel) | [Learn more about Solutions](https://aka.ms/azuresentinelsolutionsdoc)",
"description": "<img src=\"https://raw.githubusercontent.com/Azure/Azure-Sentinel/master/Logos/ThreatConnect.svg\" width=\"75px\" height=\"75px\">\n\n**Note:** _There may be [known issues](https://aka.ms/sentinelsolutionsknownissues) pertaining to this Solution, please refer to them before installing._\n\nThe [ThreatConnect Threat Intelligence Platform](https://threatconnect.com/) solution for Microsoft Sentinel provides Workbooks and Analytics to demonstrate the value of ThreatConnect data inside Microsoft Sentintel.\n\n**Workbooks:** 1, **Analytic Rules:** 5\n\n[Learn more about Microsoft Sentinel](https://aka.ms/azuresentinel) | [Learn more about Solutions](https://aka.ms/azuresentinelsolutionsdoc)",
"subscription": {
"resourceProviders": [
"Microsoft.OperationsManagement/solutions",
@ -80,13 +80,13 @@
{
"name": "workbook1",
"type": "Microsoft.Common.Section",
"label": "ThreatConnect Overview Workbook",
"label": null,
"elements": [
{
"name": "workbook1-text",
"type": "Microsoft.Common.TextBlock",
"options": {
"text": "This workbook provides visualization of ThreatConnect threat indicators which are ingested in the Microsoft Sentinel Threat intelligence."
"text": null
}
}
]
@ -106,7 +106,7 @@
"name": "analytics-text",
"type": "Microsoft.Common.TextBlock",
"options": {
"text": "This solution installs the following analytic rule templates. After installing the solution, create and enable analytic rules in Manage solution view."
"text": "This solution installs the following analytic rule templates. After installing the solution, create and enable analytic rules in Manage solution view. These rules require data from the ThreatConnect connector, and are meant to demonstrate what is possible by filering on just ThreatConnect TI."
}
},
{
@ -122,16 +122,72 @@
{
"name": "analytic1",
"type": "Microsoft.Common.Section",
"label": "ThreatConnect TI map IP entity to Network Session Events (ASIM Network Session schema)",
"label": "Threat Connect TI map Domain entity to DnsEvents",
"elements": [
{
"name": "analytic1-text",
"type": "Microsoft.Common.TextBlock",
"options": {
"text": "Identifies a match in DnsEvents from any ThreatConnect Domain IOC from TI"
}
}
]
},
{
"name": "analytic2",
"type": "Microsoft.Common.Section",
"label": "ThreatConnect TI map Email entity to OfficeActivity",
"elements": [
{
"name": "analytic2-text",
"type": "Microsoft.Common.TextBlock",
"options": {
"text": "Identifies a match in OfficeActivity table from any Email IOC from ThreatConnect TI"
}
}
]
},
{
"name": "analytic3",
"type": "Microsoft.Common.Section",
"label": "ThreatConnect TI map Email entity to SigninLogs",
"elements": [
{
"name": "analytic3-text",
"type": "Microsoft.Common.TextBlock",
"options": {
"text": "Identifies a match in SigninLogs table from any Email IOC from ThreatConnect TI"
}
}
]
},
{
"name": "analytic4",
"type": "Microsoft.Common.Section",
"label": "ThreatConnect TI map IP entity to Network Session Events (ASIM Network Session schema)",
"elements": [
{
"name": "analytic4-text",
"type": "Microsoft.Common.TextBlock",
"options": {
"text": "ThreatConnect Specific:\nThis rule identifies a match Network Sessions for which the source or destination IP address is a known IoC. <br><br>\nThis analytic rule uses [ASIM](https://aka.ms/AboutASIM) and supports any built-in or custom source that supports the ASIM NetworkSession schema"
}
}
]
},
{
"name": "analytic5",
"type": "Microsoft.Common.Section",
"label": "ThreatConnect TI Map URL Entity to OfficeActivity Data",
"elements": [
{
"name": "analytic5-text",
"type": "Microsoft.Common.TextBlock",
"options": {
"text": "This query identifies any URL indicators of compromise (IOCs) from threat intelligence (TI) by searching for matches in OfficeActivity data."
}
}
]
}
]
}

Просмотреть файл

@ -30,7 +30,7 @@
},
"workbook1-name": {
"type": "string",
"defaultValue": "ThreatConnect Overview Workbook",
"defaultValue": null,
"minLength": 1,
"metadata": {
"description": "Name for the workbook"
@ -42,19 +42,43 @@
"_solutionVersion": "3.0.0",
"solutionId": "threatconnect1234.threatconnect-api-enterprise",
"_solutionId": "[variables('solutionId')]",
"workbookVersion1": "1.0.0",
"workbookContentId1": "ThreatConnectOverviewWorkbook",
"workbookVersion1": "",
"workbookContentId1": "",
"workbookId1": "[resourceId('Microsoft.Insights/workbooks', variables('workbookContentId1'))]",
"workbookTemplateSpecName1": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-wb-',uniquestring(variables('_workbookContentId1'))))]",
"_workbookContentId1": "[variables('workbookContentId1')]",
"workspaceResourceId": "[resourceId('microsoft.OperationalInsights/Workspaces', parameters('workspace'))]",
"_workbookcontentProductId1": "[concat(take(variables('_solutionId'),50),'-','wb','-', uniqueString(concat(variables('_solutionId'),'-','Workbook','-',variables('_workbookContentId1'),'-', variables('workbookVersion1'))))]",
"analyticRuleVersion1": "1.2.4",
"analyticRulecontentId1": "ee1fd303-2081-47b7-8f02-e38bfd0868e6",
"analyticRuleVersion1": "1.0.0",
"analyticRulecontentId1": "f8960f1c-07d2-512b-9c41-952772d40c84",
"_analyticRulecontentId1": "[variables('analyticRulecontentId1')]",
"analyticRuleId1": "[resourceId('Microsoft.SecurityInsights/AlertRuleTemplates', variables('analyticRulecontentId1'))]",
"analyticRuleTemplateSpecName1": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-ar-',uniquestring(variables('_analyticRulecontentId1'))))]",
"_analyticRulecontentProductId1": "[concat(take(variables('_solutionId'),50),'-','ar','-', uniqueString(concat(variables('_solutionId'),'-','AnalyticsRule','-',variables('_analyticRulecontentId1'),'-', variables('analyticRuleVersion1'))))]",
"analyticRuleVersion2": "1.2.4",
"analyticRulecontentId2": "4f7ade3e-7121-5274-83ea-d7ed22a01fea",
"_analyticRulecontentId2": "[variables('analyticRulecontentId2')]",
"analyticRuleId2": "[resourceId('Microsoft.SecurityInsights/AlertRuleTemplates', variables('analyticRulecontentId2'))]",
"analyticRuleTemplateSpecName2": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-ar-',uniquestring(variables('_analyticRulecontentId2'))))]",
"_analyticRulecontentProductId2": "[concat(take(variables('_solutionId'),50),'-','ar','-', uniqueString(concat(variables('_solutionId'),'-','AnalyticsRule','-',variables('_analyticRulecontentId2'),'-', variables('analyticRuleVersion2'))))]",
"analyticRuleVersion3": "1.2.4",
"analyticRulecontentId3": "ecb68ce7-c309-59a7-a8de-07ccf2a0ea4f",
"_analyticRulecontentId3": "[variables('analyticRulecontentId3')]",
"analyticRuleId3": "[resourceId('Microsoft.SecurityInsights/AlertRuleTemplates', variables('analyticRulecontentId3'))]",
"analyticRuleTemplateSpecName3": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-ar-',uniquestring(variables('_analyticRulecontentId3'))))]",
"_analyticRulecontentProductId3": "[concat(take(variables('_solutionId'),50),'-','ar','-', uniqueString(concat(variables('_solutionId'),'-','AnalyticsRule','-',variables('_analyticRulecontentId3'),'-', variables('analyticRuleVersion3'))))]",
"analyticRuleVersion4": "1.0.0",
"analyticRulecontentId4": "ee1fd303-2081-47b7-8f02-e38bfd0868e6",
"_analyticRulecontentId4": "[variables('analyticRulecontentId4')]",
"analyticRuleId4": "[resourceId('Microsoft.SecurityInsights/AlertRuleTemplates', variables('analyticRulecontentId4'))]",
"analyticRuleTemplateSpecName4": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-ar-',uniquestring(variables('_analyticRulecontentId4'))))]",
"_analyticRulecontentProductId4": "[concat(take(variables('_solutionId'),50),'-','ar','-', uniqueString(concat(variables('_solutionId'),'-','AnalyticsRule','-',variables('_analyticRulecontentId4'),'-', variables('analyticRuleVersion4'))))]",
"analyticRuleVersion5": "1.0.0",
"analyticRulecontentId5": "12c3b31b-66a6-53ff-b6ab-6ae45e56dc92",
"_analyticRulecontentId5": "[variables('analyticRulecontentId5')]",
"analyticRuleId5": "[resourceId('Microsoft.SecurityInsights/AlertRuleTemplates', variables('analyticRulecontentId5'))]",
"analyticRuleTemplateSpecName5": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-ar-',uniquestring(variables('_analyticRulecontentId5'))))]",
"_analyticRulecontentProductId5": "[concat(take(variables('_solutionId'),50),'-','ar','-', uniqueString(concat(variables('_solutionId'),'-','AnalyticsRule','-',variables('_analyticRulecontentId5'),'-', variables('analyticRuleVersion5'))))]",
"_solutioncontentProductId": "[concat(take(variables('_solutionId'),50),'-','sl','-', uniqueString(concat(variables('_solutionId'),'-','Solution','-',variables('_solutionId'),'-', variables('_solutionVersion'))))]"
},
"resources": [
@ -81,7 +105,7 @@
"kind": "shared",
"apiVersion": "2021-08-01",
"metadata": {
"description": "This workbook provides visualization of ThreatConnect threat indicators which are ingested in the Microsoft Sentinel Threat intelligence."
"description": ""
},
"properties": {
"displayName": "[parameters('workbook1-name')]",
@ -96,7 +120,7 @@
"apiVersion": "2022-01-01-preview",
"name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('Workbook-', last(split(variables('workbookId1'),'/'))))]",
"properties": {
"description": "@{workbookKey=ThreatConnectOverviewWorkbook; logoFileName=ThreatConnect.svg; description=This workbook provides visualization of ThreatConnect threat indicators which are ingested in the Microsoft Sentinel Threat intelligence.; dataTypesDependencies=System.Object[]; dataConnectorsDependencies=System.Object[]; previewImagesFileNames=System.Object[]; version=1.0.0; title=ThreatConnect Overview Workbook; templateRelativePath=ThreatConnectOverview.json; subtitle=; provider=ThreatConnect, Inc.}.description",
"description": ".description",
"parentId": "[variables('workbookId1')]",
"contentId": "[variables('_workbookContentId1')]",
"kind": "Workbook",
@ -114,19 +138,6 @@
"email": "support@threatconnect.com",
"tier": "Partner",
"link": "https://threatconnect.com/contact/"
},
"dependencies": {
"operator": "AND",
"criteria": [
{
"contentId": "ThreatIntelligenceIndicator",
"kind": "DataType"
},
{
"contentId": "ThreatIntelligence",
"kind": "DataConnector"
}
]
}
}
}
@ -154,7 +165,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
"description": "ThreatConnect_IPEntity_NetworkSessions_AnalyticalRules Analytics Rule with template version 3.0.0",
"description": "ThreatConnect_DomainEntity_DnsEvents_AnalyticalRules Analytics Rule with template version 3.0.0",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleVersion1')]",
@ -168,12 +179,12 @@
"kind": "Scheduled",
"location": "[parameters('workspace-location')]",
"properties": {
"description": "ThreatConnect Specific:\nThis rule identifies a match Network Sessions for which the source or destination IP address is a known IoC. <br><br>\nThis analytic rule uses [ASIM](https://aka.ms/AboutASIM) and supports any built-in or custom source that supports the ASIM NetworkSession schema",
"displayName": "ThreatConnect TI map IP entity to Network Session Events (ASIM Network Session schema)",
"description": "Identifies a match in DnsEvents from any ThreatConnect Domain IOC from TI",
"displayName": "Threat Connect TI map Domain entity to DnsEvents",
"enabled": false,
"query": "let dt_lookBack = 1h;\nlet ioc_lookBack = 14d;\nlet IP_TI = materialize (\n ThreatIntelligenceIndicator\n | where TimeGenerated >= ago(ioc_lookBack)\n | summarize LatestIndicatorTime = arg_max(TimeGenerated, *) by IndicatorId\n | where ExpirationDateTime > now() and Active == true\n | where SourceSystem startswith \"ThreatConnect-\"\n | extend TI_ipEntity = coalesce(NetworkIP, NetworkDestinationIP, NetworkSourceIP,EmailSourceIpAddress,\"NO_IP\")\n | where TI_ipEntity != \"NO_IP\"\n);\nIP_TI\n // using innerunique to keep perf fast and result set low, we only need one match to indicate potential malicious activity that needs to be investigated\n| join kind=innerunique \n(\n _Im_NetworkSession (starttime=ago(dt_lookBack))\n | where isnotempty(SrcIpAddr)\n | summarize imNWS_mintime=min(TimeGenerated), imNWS_maxtime=max(TimeGenerated) by SrcIpAddr, DstIpAddr, Dvc, EventProduct, EventVendor \n | lookup (IP_TI | project TI_ipEntity, Active) on $left.SrcIpAddr == $right.TI_ipEntity\n | project-rename SrcMatch = Active\n | lookup (IP_TI | project TI_ipEntity, Active) on $left.DstIpAddr == $right.TI_ipEntity\n | project-rename DstMatch = Active\n | where SrcMatch or DstMatch\n | extend \n IoCIP = iff(SrcMatch, SrcIpAddr, DstIpAddr),\n IoCDirection = iff(SrcMatch, \"Source\", \"Destination\")\n)on $left.TI_ipEntity == $right.IoCIP\n| where imNWS_mintime < ExpirationDateTime\n| project imNWS_mintime, imNWS_maxtime, Description, ActivityGroupNames, IndicatorId, ThreatType, ExpirationDateTime, ConfidenceScore, SrcIpAddr, DstIpAddr, IoCDirection, IoCIP, Dvc, EventVendor, EventProduct\n",
"query": "// Define the lookback periods for time-based filters\nlet dt_lookBack = 1h; // Look back 1 hour for DNS events\nlet ioc_lookBack = 7d; // Look back 7 days for threat intelligence indicators\n// Fetch threat intelligence indicators related to domains\nlet Domain_Indicators = ThreatIntelligenceIndicator\n | where TimeGenerated >= ago(ioc_lookBack)\n | summarize LatestIndicatorTime = arg_max(TimeGenerated, *) by IndicatorId\n | where Active == true and ExpirationDateTime > now()\n // Filter out non ThreatConnect TI Sources\n | where SourceSystem startswith \"ThreatConnect-\"\n // Filter out indicators without domain names\n | where isnotempty(DomainName)\n | extend TI_DomainEntity = DomainName;\n// Create a list of TLDs in our threat feed for later validation\nlet maxListSize = 100000; // Define the maximum allowed size for each list\nlet list_tlds = Domain_Indicators\n | extend parts = split(DomainName, '.')\n | extend tld = parts[(array_length(parts)-1)]\n | summarize count() by tostring(tld)\n | project tld\n | summarize make_list(tld, maxListSize);\n// Perform a join between domain indicators and DNS events to identify potential malicious activity\nDomain_Indicators\n // Use innerunique to keep performance fast and result set low, as we only need one match to indicate potential malicious activity that needs investigation\n | join kind=innerunique (\n DnsEvents\n | where TimeGenerated > ago(dt_lookBack)\n // Extract domain patterns from syslog message\n | where isnotempty(Name)\n | extend parts = split(Name, '.')\n | extend tld = parts[(array_length(parts)-1)]\n // Validate parsed domain by checking if the TLD is in the list of TLDs in our threat feed\n | where tld in~ (list_tlds)\n | extend DNS_TimeGenerated = TimeGenerated\n ) on $left.TI_DomainEntity==$right.Name\n // Filter out DNS events that occurred after the expiration of the corresponding indicator\n | where DNS_TimeGenerated < ExpirationDateTime\n // Group the results by IndicatorId and Name, and keep the DNS event with the latest timestamp\n | summarize DNS_TimeGenerated = arg_max(DNS_TimeGenerated, *) by IndicatorId, Name\n // Select the desired output fields\n | project DNS_TimeGenerated, Description, ActivityGroupNames, IndicatorId, ThreatType, ExpirationDateTime, ConfidenceScore, Url, Computer, ClientIP, Name, QueryType, Type, TI_DomainEntity\n // Extract hostname and DNS domain from the Computer field\n | extend HostName = tostring(split(Computer, '.', 0)[0]), DnsDomain = tostring(strcat_array(array_slice(split(Computer, '.'), 1, -1), '.'))\n // Rename the timestamp field\n | extend timestamp = DNS_TimeGenerated\n",
"queryFrequency": "PT1H",
"queryPeriod": "P14D",
"queryPeriod": "P7D",
"severity": "Medium",
"suppressionDuration": "PT1H",
"suppressionEnabled": false,
@ -181,54 +192,67 @@
"triggerThreshold": 0,
"status": "Available",
"requiredDataConnectors": [
{
"dataTypes": [
"DnsEvents"
],
"connectorId": "DNS"
},
{
"dataTypes": [
"ThreatIntelligenceIndicator"
],
"connectorId": "ThreatIntelligence"
},
{
"dataTypes": [
"ThreatIntelligenceIndicator"
],
"connectorId": "ThreatIntelligenceTaxii"
},
{
"dataTypes": [
"ThreatIntelligenceIndicator"
],
"connectorId": "MicrosoftDefenderThreatIntelligence"
}
],
"tactics": [
"Impact"
],
"entityMappings": [
{
"entityType": "Host",
"fieldMappings": [
{
"columnName": "HostName",
"identifier": "HostName"
},
{
"columnName": "DnsDomain",
"identifier": "DnsDomain"
}
]
},
{
"entityType": "IP",
"fieldMappings": [
{
"identifier": "Address",
"columnName": "IoCIP"
"columnName": "ClientIP",
"identifier": "Address"
}
]
},
{
"entityType": "URL",
"fieldMappings": [
{
"columnName": "Url",
"identifier": "Url"
}
]
}
],
"eventGroupingSettings": {
"aggregationKind": "SingleAlert"
},
"customDetails": {
"ActivityGroupNames": "ActivityGroupNames",
"IoCDescription": "Description",
"EventEndTime": "imNWS_maxtime",
"IoCConfidenceScore": "ConfidenceScore",
"ThreatType": "ThreatType",
"IoCIPDirection": "IoCDirection",
"IndicatorId": "IndicatorId",
"IoCExpirationTime": "ExpirationDateTime",
"EventStartTime": "imNWS_mintime"
},
"alertDetailsOverride": {
"alertDisplayNameFormat": "A network session {{IoCDirection}} address {{IoCIP}} matched an IoC.",
"alertDescriptionFormat": "The {{IoCDirection}} address {{IoCIP}} of a network session matched a known indicator of compromise of {{ThreatType}}. Consult the threat intelligence blead for more information on the indicator."
},
"incidentConfiguration": {
"groupingConfiguration": {
"enabled": true,
"matchingMethod": "AllEntities",
"lookbackDuration": "4h",
"reopenClosedIncident": false
},
"createIncident": true
}
]
}
},
{
@ -266,12 +290,550 @@
"contentSchemaVersion": "3.0.0",
"contentId": "[variables('_analyticRulecontentId1')]",
"contentKind": "AnalyticsRule",
"displayName": "ThreatConnect TI map IP entity to Network Session Events (ASIM Network Session schema)",
"displayName": "Threat Connect TI map Domain entity to DnsEvents",
"contentProductId": "[variables('_analyticRulecontentProductId1')]",
"id": "[variables('_analyticRulecontentProductId1')]",
"version": "[variables('analyticRuleVersion1')]"
}
},
{
"type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
"apiVersion": "2023-04-01-preview",
"name": "[variables('analyticRuleTemplateSpecName2')]",
"location": "[parameters('workspace-location')]",
"dependsOn": [
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
"description": "ThreatConnect_EmailEntity_OfficeActivity_AnalyticalRules Analytics Rule with template version 3.0.0",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleVersion2')]",
"parameters": {},
"variables": {},
"resources": [
{
"type": "Microsoft.SecurityInsights/AlertRuleTemplates",
"name": "[variables('analyticRulecontentId2')]",
"apiVersion": "2022-04-01-preview",
"kind": "Scheduled",
"location": "[parameters('workspace-location')]",
"properties": {
"description": "Identifies a match in OfficeActivity table from any Email IOC from ThreatConnect TI",
"displayName": "ThreatConnect TI map Email entity to OfficeActivity",
"enabled": false,
"query": "let dt_lookBack = 1h;\nlet ioc_lookBack = 14d;\nlet emailregex = @'^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\\.[a-zA-Z0-9-.]+$';\nThreatIntelligenceIndicator\n| where TimeGenerated >= ago(ioc_lookBack) and ExpirationDateTime > now()\n| summarize LatestIndicatorTime = arg_max(TimeGenerated, *) by IndicatorId\n| where Active == true\n// Filter out non ThreatConnect TI Sources\n| where SourceSystem startswith \"ThreatConnect-\"\n//Filtering the table for Email related IOCs\n| where isnotempty(EmailSenderAddress)\n// using innerunique to keep perf fast and result set low, we only need one match to indicate potential malicious activity that needs to be investigated\n| join kind=innerunique (\n OfficeActivity | where TimeGenerated >= ago(dt_lookBack) and isnotempty(UserId)\n | where UserId matches regex emailregex\n | extend OfficeActivity_TimeGenerated = TimeGenerated\n)\non $left.EmailSenderAddress == $right.UserId\n| where OfficeActivity_TimeGenerated < ExpirationDateTime\n| summarize OfficeActivity_TimeGenerated = arg_max(OfficeActivity_TimeGenerated, *) by IndicatorId, UserId\n| project OfficeActivity_TimeGenerated, Description, ActivityGroupNames, IndicatorId, ThreatType, Url, ExpirationDateTime, ConfidenceScore,\nEmailSenderName, EmailRecipient, EmailSourceDomain, EmailSourceIpAddress, EmailSubject, FileHashValue, FileHashType, UserId, ClientIP, Operation, UserType, RecordType, OfficeWorkload, Parameters\n| extend Name = tostring(split(UserId, '@', 0)[0]), UPNSuffix = tostring(split(UserId, '@', 1)[0])\n| extend timestamp = OfficeActivity_TimeGenerated\n",
"queryFrequency": "PT1H",
"queryPeriod": "P14D",
"severity": "Medium",
"suppressionDuration": "PT1H",
"suppressionEnabled": false,
"triggerOperator": "GreaterThan",
"triggerThreshold": 0,
"status": "Available",
"requiredDataConnectors": [
{
"dataTypes": [
"OfficeActivity"
],
"connectorId": "Office365"
},
{
"dataTypes": [
"ThreatIntelligenceIndicator"
],
"connectorId": "ThreatIntelligence"
},
{
"dataTypes": [
"ThreatIntelligenceIndicator"
],
"connectorId": "ThreatIntelligenceTaxii"
},
{
"dataTypes": [
"ThreatIntelligenceIndicator"
],
"connectorId": "MicrosoftDefenderThreatIntelligence"
}
],
"tactics": [
"Impact"
],
"entityMappings": [
{
"entityType": "Account",
"fieldMappings": [
{
"columnName": "Name",
"identifier": "Name"
},
{
"columnName": "UPNSuffix",
"identifier": "UPNSuffix"
}
]
},
{
"entityType": "IP",
"fieldMappings": [
{
"columnName": "ClientIP",
"identifier": "Address"
}
]
},
{
"entityType": "URL",
"fieldMappings": [
{
"columnName": "Url",
"identifier": "Url"
}
]
}
]
}
},
{
"type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
"apiVersion": "2022-01-01-preview",
"name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('AnalyticsRule-', last(split(variables('analyticRuleId2'),'/'))))]",
"properties": {
"description": "ThreatConnect Analytics Rule 2",
"parentId": "[variables('analyticRuleId2')]",
"contentId": "[variables('_analyticRulecontentId2')]",
"kind": "AnalyticsRule",
"version": "[variables('analyticRuleVersion2')]",
"source": {
"kind": "Solution",
"name": "ThreatConnect",
"sourceId": "[variables('_solutionId')]"
},
"author": {
"name": "JP Bourget jp@bluecycle.net"
},
"support": {
"name": "ThreatConnect, Inc.",
"email": "support@threatconnect.com",
"tier": "Partner",
"link": "https://threatconnect.com/contact/"
}
}
}
]
},
"packageKind": "Solution",
"packageVersion": "[variables('_solutionVersion')]",
"packageName": "[variables('_solutionName')]",
"packageId": "[variables('_solutionId')]",
"contentSchemaVersion": "3.0.0",
"contentId": "[variables('_analyticRulecontentId2')]",
"contentKind": "AnalyticsRule",
"displayName": "ThreatConnect TI map Email entity to OfficeActivity",
"contentProductId": "[variables('_analyticRulecontentProductId2')]",
"id": "[variables('_analyticRulecontentProductId2')]",
"version": "[variables('analyticRuleVersion2')]"
}
},
{
"type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
"apiVersion": "2023-04-01-preview",
"name": "[variables('analyticRuleTemplateSpecName3')]",
"location": "[parameters('workspace-location')]",
"dependsOn": [
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
"description": "ThreatConnect_EmailEntity_SigninLogs_AnalyticalRules Analytics Rule with template version 3.0.0",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleVersion3')]",
"parameters": {},
"variables": {},
"resources": [
{
"type": "Microsoft.SecurityInsights/AlertRuleTemplates",
"name": "[variables('analyticRulecontentId3')]",
"apiVersion": "2022-04-01-preview",
"kind": "Scheduled",
"location": "[parameters('workspace-location')]",
"properties": {
"description": "Identifies a match in SigninLogs table from any Email IOC from ThreatConnect TI",
"displayName": "ThreatConnect TI map Email entity to SigninLogs",
"enabled": false,
"query": "let dt_lookBack = 1h;\nlet ioc_lookBack = 14d;\nlet emailregex = @'^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\\.[a-zA-Z0-9-.]+$';\nlet aadFunc = (tableName:string){\nThreatIntelligenceIndicator\n| where TimeGenerated >= ago(ioc_lookBack) and ExpirationDateTime > now()\n| summarize LatestIndicatorTime = arg_max(TimeGenerated, *) by IndicatorId\n| where Active == true\n// Filter out non ThreatConnect TI Sources\n| where SourceSystem startswith \"ThreatConnect-\"\n//Filtering the table for Email related IOCs\n| where isnotempty(EmailSenderAddress)\n// using innerunique to keep perf fast and result set low, we only need one match to indicate potential malicious activity that needs to be investigated\n| join kind=innerunique (\n table(tableName) | where TimeGenerated >= ago(dt_lookBack) and isnotempty(UserPrincipalName)\n //Normalizing the column to lower case for exact match with EmailSenderAddress column\n | extend UserPrincipalName = tolower(UserPrincipalName)\n | where UserPrincipalName matches regex emailregex\n | extend Status = todynamic(DeviceDetail), LocationDetails = todynamic(LocationDetails)\n | extend StatusCode = tostring(Status.errorCode), StatusDetails = tostring(Status.additionalDetails)\n | extend State = tostring(LocationDetails.state), City = tostring(LocationDetails.city), Region = tostring(LocationDetails.countryOrRegion)\n // renaming timestamp column so it is clear the log this came from SigninLogs table\n | extend SigninLogs_TimeGenerated = TimeGenerated, Type = Type\n)\non $left.EmailSenderAddress == $right.UserPrincipalName\n| where SigninLogs_TimeGenerated < ExpirationDateTime\n| summarize SigninLogs_TimeGenerated = arg_max(SigninLogs_TimeGenerated, *) by IndicatorId, UserPrincipalName\n| project SigninLogs_TimeGenerated, Description, ActivityGroupNames, IndicatorId, ThreatType, Url, ExpirationDateTime, ConfidenceScore,\nEmailSenderName, EmailRecipient, EmailSourceDomain, EmailSourceIpAddress, EmailSubject, FileHashValue, FileHashType, IPAddress, UserPrincipalName, AppDisplayName,\nStatusCode, StatusDetails, NetworkIP, NetworkDestinationIP, NetworkSourceIP, Type\n| extend Name = tostring(split(UserPrincipalName, '@', 0)[0]), UPNSuffix = tostring(split(UserPrincipalName, '@', 1)[0])\n| extend timestamp = SigninLogs_TimeGenerated\n};\nlet aadSignin = aadFunc(\"SigninLogs\");\nlet aadNonInt = aadFunc(\"AADNonInteractiveUserSignInLogs\");\nunion isfuzzy=true aadSignin, aadNonInt\n",
"queryFrequency": "PT1H",
"queryPeriod": "P14D",
"severity": "Medium",
"suppressionDuration": "PT1H",
"suppressionEnabled": false,
"triggerOperator": "GreaterThan",
"triggerThreshold": 0,
"status": "Available",
"requiredDataConnectors": [
{
"dataTypes": [
"ThreatIntelligenceIndicator"
],
"connectorId": "ThreatIntelligence"
},
{
"dataTypes": [
"ThreatIntelligenceIndicator"
],
"connectorId": "ThreatIntelligenceTaxii"
},
{
"dataTypes": [
"SigninLogs"
],
"connectorId": "AzureActiveDirectory"
},
{
"dataTypes": [
"AADNonInteractiveUserSignInLogs"
],
"connectorId": "AzureActiveDirectory"
},
{
"dataTypes": [
"ThreatIntelligenceIndicator"
],
"connectorId": "MicrosoftDefenderThreatIntelligence"
}
],
"tactics": [
"Impact"
],
"entityMappings": [
{
"entityType": "Account",
"fieldMappings": [
{
"columnName": "Name",
"identifier": "Name"
},
{
"columnName": "UPNSuffix",
"identifier": "UPNSuffix"
}
]
},
{
"entityType": "IP",
"fieldMappings": [
{
"columnName": "IPAddress",
"identifier": "Address"
}
]
},
{
"entityType": "URL",
"fieldMappings": [
{
"columnName": "Url",
"identifier": "Url"
}
]
}
]
}
},
{
"type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
"apiVersion": "2022-01-01-preview",
"name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('AnalyticsRule-', last(split(variables('analyticRuleId3'),'/'))))]",
"properties": {
"description": "ThreatConnect Analytics Rule 3",
"parentId": "[variables('analyticRuleId3')]",
"contentId": "[variables('_analyticRulecontentId3')]",
"kind": "AnalyticsRule",
"version": "[variables('analyticRuleVersion3')]",
"source": {
"kind": "Solution",
"name": "ThreatConnect",
"sourceId": "[variables('_solutionId')]"
},
"author": {
"name": "JP Bourget jp@bluecycle.net"
},
"support": {
"name": "ThreatConnect, Inc.",
"email": "support@threatconnect.com",
"tier": "Partner",
"link": "https://threatconnect.com/contact/"
}
}
}
]
},
"packageKind": "Solution",
"packageVersion": "[variables('_solutionVersion')]",
"packageName": "[variables('_solutionName')]",
"packageId": "[variables('_solutionId')]",
"contentSchemaVersion": "3.0.0",
"contentId": "[variables('_analyticRulecontentId3')]",
"contentKind": "AnalyticsRule",
"displayName": "ThreatConnect TI map Email entity to SigninLogs",
"contentProductId": "[variables('_analyticRulecontentProductId3')]",
"id": "[variables('_analyticRulecontentProductId3')]",
"version": "[variables('analyticRuleVersion3')]"
}
},
{
"type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
"apiVersion": "2023-04-01-preview",
"name": "[variables('analyticRuleTemplateSpecName4')]",
"location": "[parameters('workspace-location')]",
"dependsOn": [
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
"description": "ThreatConnect_IPEntity_NetworkSessions_AnalyticalRules Analytics Rule with template version 3.0.0",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleVersion4')]",
"parameters": {},
"variables": {},
"resources": [
{
"type": "Microsoft.SecurityInsights/AlertRuleTemplates",
"name": "[variables('analyticRulecontentId4')]",
"apiVersion": "2022-04-01-preview",
"kind": "Scheduled",
"location": "[parameters('workspace-location')]",
"properties": {
"description": "ThreatConnect Specific:\nThis rule identifies a match Network Sessions for which the source or destination IP address is a known IoC. <br><br>\nThis analytic rule uses [ASIM](https://aka.ms/AboutASIM) and supports any built-in or custom source that supports the ASIM NetworkSession schema",
"displayName": "ThreatConnect TI map IP entity to Network Session Events (ASIM Network Session schema)",
"enabled": false,
"query": "let dt_lookBack = 1h;\nlet ioc_lookBack = 14d;\nlet IP_TI = materialize (\n ThreatIntelligenceIndicator\n | where TimeGenerated >= ago(ioc_lookBack)\n | summarize LatestIndicatorTime = arg_max(TimeGenerated, *) by IndicatorId\n | where ExpirationDateTime > now() and Active == true\n | where SourceSystem startswith \"ThreatConnect-\"\n | extend TI_ipEntity = coalesce(NetworkIP, NetworkDestinationIP, NetworkSourceIP,EmailSourceIpAddress,\"NO_IP\")\n | where TI_ipEntity != \"NO_IP\"\n);\nIP_TI\n // using innerunique to keep perf fast and result set low, we only need one match to indicate potential malicious activity that needs to be investigated\n| join kind=innerunique \n(\n _Im_NetworkSession (starttime=ago(dt_lookBack))\n | where isnotempty(SrcIpAddr)\n | summarize imNWS_mintime=min(TimeGenerated), imNWS_maxtime=max(TimeGenerated) by SrcIpAddr, DstIpAddr, Dvc, EventProduct, EventVendor \n | lookup (IP_TI | project TI_ipEntity, Active) on $left.SrcIpAddr == $right.TI_ipEntity\n | project-rename SrcMatch = Active\n | lookup (IP_TI | project TI_ipEntity, Active) on $left.DstIpAddr == $right.TI_ipEntity\n | project-rename DstMatch = Active\n | where SrcMatch or DstMatch\n | extend \n IoCIP = iff(SrcMatch, SrcIpAddr, DstIpAddr),\n IoCDirection = iff(SrcMatch, \"Source\", \"Destination\")\n)on $left.TI_ipEntity == $right.IoCIP\n| where imNWS_mintime < ExpirationDateTime\n| project imNWS_mintime, imNWS_maxtime, Description, ActivityGroupNames, IndicatorId, ThreatType, ExpirationDateTime, ConfidenceScore, SrcIpAddr, DstIpAddr, IoCDirection, IoCIP, Dvc, EventVendor, EventProduct\n",
"queryFrequency": "PT1H",
"queryPeriod": "P14D",
"severity": "Medium",
"suppressionDuration": "PT1H",
"suppressionEnabled": false,
"triggerOperator": "GreaterThan",
"triggerThreshold": 0,
"status": "Available",
"requiredDataConnectors": [
{
"dataTypes": [
"ThreatIntelligenceIndicator"
],
"connectorId": "ThreatIntelligence"
}
],
"tactics": [
"Impact"
],
"entityMappings": [
{
"entityType": "IP",
"fieldMappings": [
{
"columnName": "IoCIP",
"identifier": "Address"
}
]
}
],
"eventGroupingSettings": {
"aggregationKind": "SingleAlert"
},
"customDetails": {
"IoCExpirationTime": "ExpirationDateTime",
"IndicatorId": "IndicatorId",
"EventEndTime": "imNWS_maxtime",
"IoCDescription": "Description",
"EventStartTime": "imNWS_mintime",
"IoCIPDirection": "IoCDirection",
"ActivityGroupNames": "ActivityGroupNames",
"ThreatType": "ThreatType",
"IoCConfidenceScore": "ConfidenceScore"
},
"alertDetailsOverride": {
"alertDisplayNameFormat": "A network session {{IoCDirection}} address {{IoCIP}} matched an IoC.",
"alertDescriptionFormat": "The {{IoCDirection}} address {{IoCIP}} of a network session matched a known indicator of compromise of {{ThreatType}}. Consult the threat intelligence blead for more information on the indicator."
},
"incidentConfiguration": {
"groupingConfiguration": {
"matchingMethod": "AllEntities",
"lookbackDuration": "4h",
"enabled": true,
"reopenClosedIncident": false
},
"createIncident": true
}
}
},
{
"type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
"apiVersion": "2022-01-01-preview",
"name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('AnalyticsRule-', last(split(variables('analyticRuleId4'),'/'))))]",
"properties": {
"description": "ThreatConnect Analytics Rule 4",
"parentId": "[variables('analyticRuleId4')]",
"contentId": "[variables('_analyticRulecontentId4')]",
"kind": "AnalyticsRule",
"version": "[variables('analyticRuleVersion4')]",
"source": {
"kind": "Solution",
"name": "ThreatConnect",
"sourceId": "[variables('_solutionId')]"
},
"author": {
"name": "JP Bourget jp@bluecycle.net"
},
"support": {
"name": "ThreatConnect, Inc.",
"email": "support@threatconnect.com",
"tier": "Partner",
"link": "https://threatconnect.com/contact/"
}
}
}
]
},
"packageKind": "Solution",
"packageVersion": "[variables('_solutionVersion')]",
"packageName": "[variables('_solutionName')]",
"packageId": "[variables('_solutionId')]",
"contentSchemaVersion": "3.0.0",
"contentId": "[variables('_analyticRulecontentId4')]",
"contentKind": "AnalyticsRule",
"displayName": "ThreatConnect TI map IP entity to Network Session Events (ASIM Network Session schema)",
"contentProductId": "[variables('_analyticRulecontentProductId4')]",
"id": "[variables('_analyticRulecontentProductId4')]",
"version": "[variables('analyticRuleVersion4')]"
}
},
{
"type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
"apiVersion": "2023-04-01-preview",
"name": "[variables('analyticRuleTemplateSpecName5')]",
"location": "[parameters('workspace-location')]",
"dependsOn": [
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
"description": "ThreatConnect_URLEntity_OfficeActivity_AnalyticalRules Analytics Rule with template version 3.0.0",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleVersion5')]",
"parameters": {},
"variables": {},
"resources": [
{
"type": "Microsoft.SecurityInsights/AlertRuleTemplates",
"name": "[variables('analyticRulecontentId5')]",
"apiVersion": "2022-04-01-preview",
"kind": "Scheduled",
"location": "[parameters('workspace-location')]",
"properties": {
"description": "This query identifies any URL indicators of compromise (IOCs) from threat intelligence (TI) by searching for matches in OfficeActivity data.",
"displayName": "ThreatConnect TI Map URL Entity to OfficeActivity Data",
"enabled": false,
"query": "let dt_lookBack = 1h;\nlet ioc_lookBack = 14d;\nThreatIntelligenceIndicator\n| where TimeGenerated >= ago(ioc_lookBack) and ExpirationDateTime > now()\n| summarize LatestIndicatorTime = arg_max(TimeGenerated, *) by IndicatorId\n| where Active == true\n// Filter out non ThreatConnect TI Sources\n| where SourceSystem startswith \"ThreatConnect-\"\n// Picking up only IOC's that contain the entities we want\n| where isnotempty(Url)\n// using innerunique to keep perf fast and result set low, we only need one match to indicate potential malicious activity that needs to be investigated\n| join kind=innerunique (\n OfficeActivity\n | where TimeGenerated >= ago(dt_lookBack)\n //Extract the Url from a number of potential fields\n | extend Url = iif(OfficeWorkload == \"AzureActiveDirectory\",extract(\"(http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\\\\(\\\\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+);\", 1,ModifiedProperties),tostring(parse_json(ModifiedProperties)[12].NewValue))\n | where isnotempty(Url)\n // Ensure we get a clean URL\n | extend Url = tostring(split(Url, ';')[0])\n | extend OfficeActivity_TimeGenerated = TimeGenerated\n // Project a single user identity that we can use for entity mapping\n | extend User = iif(isnotempty(UserId), UserId, iif(isnotempty(Actor), tostring(parse_json(Actor)[0].ID), tostring(parse_json(Parameters)[0].Value)))\n) on Url\n| where OfficeActivity_TimeGenerated < ExpirationDateTime\n| summarize OfficeActivity_TimeGenerated = arg_max(OfficeActivity_TimeGenerated, *) by IndicatorId, Url\n| project OfficeActivity_TimeGenerated, Description, ActivityGroupNames, IndicatorId, ThreatType, ExpirationDateTime, ConfidenceScore, Operation,\nUserType, OfficeWorkload, Parameters, Url, User\n| extend timestamp = OfficeActivity_TimeGenerated, Name = tostring(split(User, '@', 0)[0]), UPNSuffix = tostring(split(User, '@', 1)[0])\n",
"queryFrequency": "PT1H",
"queryPeriod": "P14D",
"severity": "Medium",
"suppressionDuration": "PT1H",
"suppressionEnabled": false,
"triggerOperator": "GreaterThan",
"triggerThreshold": 0,
"status": "Available",
"requiredDataConnectors": [
{
"dataTypes": [
"OfficeActivity"
],
"connectorId": "Office365"
},
{
"dataTypes": [
"ThreatIntelligenceIndicator"
],
"connectorId": "ThreatIntelligence"
},
{
"dataTypes": [
"ThreatIntelligenceIndicator"
],
"connectorId": "MicrosoftDefenderThreatIntelligence"
}
],
"tactics": [
"Impact"
],
"entityMappings": [
{
"entityType": "Account",
"fieldMappings": [
{
"columnName": "Name",
"identifier": "Name"
},
{
"columnName": "UPNSuffix",
"identifier": "UPNSuffix"
}
]
},
{
"entityType": "URL",
"fieldMappings": [
{
"columnName": "Url",
"identifier": "Url"
}
]
}
]
}
},
{
"type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
"apiVersion": "2022-01-01-preview",
"name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('AnalyticsRule-', last(split(variables('analyticRuleId5'),'/'))))]",
"properties": {
"description": "ThreatConnect Analytics Rule 5",
"parentId": "[variables('analyticRuleId5')]",
"contentId": "[variables('_analyticRulecontentId5')]",
"kind": "AnalyticsRule",
"version": "[variables('analyticRuleVersion5')]",
"source": {
"kind": "Solution",
"name": "ThreatConnect",
"sourceId": "[variables('_solutionId')]"
},
"author": {
"name": "JP Bourget jp@bluecycle.net"
},
"support": {
"name": "ThreatConnect, Inc.",
"email": "support@threatconnect.com",
"tier": "Partner",
"link": "https://threatconnect.com/contact/"
}
}
}
]
},
"packageKind": "Solution",
"packageVersion": "[variables('_solutionVersion')]",
"packageName": "[variables('_solutionName')]",
"packageId": "[variables('_solutionId')]",
"contentSchemaVersion": "3.0.0",
"contentId": "[variables('_analyticRulecontentId5')]",
"contentKind": "AnalyticsRule",
"displayName": "ThreatConnect TI Map URL Entity to OfficeActivity Data",
"contentProductId": "[variables('_analyticRulecontentProductId5')]",
"id": "[variables('_analyticRulecontentProductId5')]",
"version": "[variables('analyticRuleVersion5')]"
}
},
{
"type": "Microsoft.OperationalInsights/workspaces/providers/contentPackages",
"apiVersion": "2023-04-01-preview",
@ -282,7 +844,7 @@
"contentSchemaVersion": "3.0.0",
"displayName": "ThreatConnect",
"publisherDisplayName": "ThreatConnect, Inc.",
"descriptionHtml": "<p><strong>Note:</strong> <em>There may be <a href=\"https://aka.ms/sentinelsolutionsknownissues\">known issues</a> pertaining to this Solution, please refer to them before installing.</em></p>\n<p>The <a href=\"https://threatconnect.com/\">ThreatConnect Threat Intelligence Platform</a> solution for Microsoft Sentinel provides Workbooks and Analytics to demonstrate the value of ThreatConnect data inside Microsoft Sentintel.</p>\n<p><strong>Workbooks:</strong> 1, <strong>Analytic Rules:</strong> 1</p>\n<p><a href=\"https://aka.ms/azuresentinel\">Learn more about Microsoft Sentinel</a> | <a href=\"https://aka.ms/azuresentinelsolutionsdoc\">Learn more about Solutions</a></p>\n",
"descriptionHtml": "<p><strong>Note:</strong> <em>There may be <a href=\"https://aka.ms/sentinelsolutionsknownissues\">known issues</a> pertaining to this Solution, please refer to them before installing.</em></p>\n<p>The <a href=\"https://threatconnect.com/\">ThreatConnect Threat Intelligence Platform</a> solution for Microsoft Sentinel provides Workbooks and Analytics to demonstrate the value of ThreatConnect data inside Microsoft Sentintel.</p>\n<p><strong>Workbooks:</strong> 1, <strong>Analytic Rules:</strong> 5</p>\n<p><a href=\"https://aka.ms/azuresentinel\">Learn more about Microsoft Sentinel</a> | <a href=\"https://aka.ms/azuresentinelsolutionsdoc\">Learn more about Solutions</a></p>\n",
"contentKind": "Solution",
"contentProductId": "[variables('_solutioncontentProductId')]",
"id": "[variables('_solutioncontentProductId')]",
@ -315,6 +877,26 @@
"kind": "AnalyticsRule",
"contentId": "[variables('analyticRulecontentId1')]",
"version": "[variables('analyticRuleVersion1')]"
},
{
"kind": "AnalyticsRule",
"contentId": "[variables('analyticRulecontentId2')]",
"version": "[variables('analyticRuleVersion2')]"
},
{
"kind": "AnalyticsRule",
"contentId": "[variables('analyticRulecontentId3')]",
"version": "[variables('analyticRuleVersion3')]"
},
{
"kind": "AnalyticsRule",
"contentId": "[variables('analyticRulecontentId4')]",
"version": "[variables('analyticRuleVersion4')]"
},
{
"kind": "AnalyticsRule",
"contentId": "[variables('analyticRulecontentId5')]",
"version": "[variables('analyticRuleVersion5')]"
}
]
},