Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update DomainEntity_EmailUrlInfo.yaml #11369

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -25,44 +25,60 @@ tactics:
relevantTechniques:
- T1566
query: |
let dt_lookBack = 1h;
let ioc_lookBack = 14d;
let EmailUrlInfo_ = materialize(EmailUrlInfo
| where isnotempty(UrlDomain)
| where TimeGenerated > ago(dt_lookBack)
| project-rename Email_Url = Url);
let Domains = EmailUrlInfo_
| distinct UrlDomain
| summarize make_list(UrlDomain);
let Candidates = ThreatIntelligenceIndicator
| where isnotempty(DomainName)
| where TimeGenerated >= ago(ioc_lookBack)
| extend TI_Domain = tolower(DomainName)
| where TI_Domain in (Domains)
| summarize LatestIndicatorTime = arg_max(TimeGenerated, *) by IndicatorId
| where Active == true and ExpirationDateTime > now()
| where Description !contains_cs "State: inactive;" and Description !contains_cs "State: falsepos;"
| join kind=innerunique EmailUrlInfo_ on $left.TI_Domain == $right.UrlDomain
| join kind=innerunique (EmailEvents | where TimeGenerated >= ago(dt_lookBack) | project-rename EmailEvents_TimeGenerated = TimeGenerated) on $left.NetworkMessageId == $right.NetworkMessageId
| where DeliveryLocation !has "Quarantine"
// Customize and uncomment the following line to remove security related mailboxes
//| where tolower(RecipientEmailAddress) !in ("[email protected]", "[email protected]")
| where EmailEvents_TimeGenerated < ExpirationDateTime
| summarize EmailEvents_TimeGenerated = arg_max(EmailEvents_TimeGenerated, *) by IndicatorId, RecipientEmailAddress;
let Candidate_Domains = Candidates | distinct TI_Domain | summarize make_list(TI_Domain);
ThreatIntelligenceIndicator
| where isnotempty(Url)
| where TimeGenerated > ago(ioc_lookBack)
| extend Host = tostring(parse_url(Url).Host)
| where Host in (Candidate_Domains)
| summarize LatestIndicatorTime = arg_max(TimeGenerated, *) by IndicatorId
| where Active == true and ExpirationDateTime > now()
| where Description !contains_cs "State: inactive;" and Description !contains_cs "State: falsepos;"
| join kind=innerunique (Candidates | extend parsed_url = parse_url(Email_Url) | extend BaseUrl = strcat(parsed_url.Scheme, "://", parsed_url.Host, parsed_url.Path)) on $left.Url == $right.BaseUrl
| where DeliveryAction !has "Blocked"
| project EmailEvents_TimeGenerated, RecipientEmailAddress, IndicatorId, TI_Domain, ConfidenceScore, Description, Tags, TrafficLightProtocolLevel, Url = Email_Url, DeliveryAction, DeliveryLocation, EmailDirection, NetworkMessageId, AuthenticationDetails, SenderFromAddress, SenderIPv4, Subject
| extend Name = tostring(split(RecipientEmailAddress, '@', 0)[0]), UPNSuffix = tostring(split(RecipientEmailAddress, '@', 1)[0])
| extend timestamp = EmailEvents_TimeGenerated
let dt_lookBack = 1h; // Define the lookback period for email data as 1 hour
let ioc_lookBack = 14d; // Define the lookback period for threat intelligence data as 14 days
let EmailUrlInfo_ = EmailUrlInfo
| where isnotempty(Url) or isnotempty(UrlDomain) // Filter for non-empty URLs or URL domains
| where TimeGenerated >= ago(dt_lookBack) // Filter for records within the lookback period
| extend Url = tolower(Url), UrlDomain = tolower(UrlDomain) // Convert URLs and domains to lowercase
| extend EmailUrlInfo_TimeGenerated = TimeGenerated; // Create a new column for the time generated
let EmailEvents_ = EmailEvents
| where TimeGenerated >= ago(dt_lookBack); // Filter email events within the lookback period
let TI_Urls = ThreatIntelligenceIndicator
| where TimeGenerated >= ago(ioc_lookBack) // Filter threat intelligence indicators within the lookback period
| where isnotempty(Url) // Filter for non-empty URLs
| extend Url = tolower(Url) // Convert URLs to lowercase
| join kind=innerunique (EmailUrlInfo_) on Url // Join with email URL info on URL
| where Active == true and ExpirationDateTime > now() // Filter for active indicators that haven't expired
| where EmailUrlInfo_TimeGenerated < ExpirationDateTime // Ensure email info was generated before the indicator expired
| summarize EmailUrlInfo_TimeGenerated = arg_max(EmailUrlInfo_TimeGenerated, *) by IndicatorId, Url // Get the latest email info for each indicator
| project
EmailUrlInfo_TimeGenerated,
Description,
ActivityGroupNames,
IndicatorId,
ThreatType,
ExpirationDateTime,
ConfidenceScore,
Url,
UrlLocation,
NetworkMessageId; // Select relevant columns
let TI_Domains = ThreatIntelligenceIndicator
| where TimeGenerated >= ago(ioc_lookBack) // Filter threat intelligence indicators within the lookback period
| where isnotempty(DomainName) // Filter for non-empty domain names
| extend DomainName = tolower(DomainName) // Convert domain names to lowercase
| join kind=innerunique (EmailUrlInfo_) on $left.DomainName == $right.UrlDomain // Join with email URL info on domain name
| where Active == true and ExpirationDateTime > now() // Filter for active indicators that haven't expired
| where EmailUrlInfo_TimeGenerated < ExpirationDateTime // Ensure email info was generated before the indicator expired
| summarize EmailUrlInfo_TimeGenerated = arg_max(EmailUrlInfo_TimeGenerated, *) by IndicatorId, UrlDomain // Get the latest email info for each indicator
| project
EmailUrlInfo_TimeGenerated,
Description,
ActivityGroupNames,
IndicatorId,
ThreatType,
ExpirationDateTime,
ConfidenceScore,
UrlDomain,
UrlLocation,
NetworkMessageId; // Select relevant columns
union TI_Urls, TI_Domains // Combine URL and domain threat intelligence data
| extend timestamp = EmailUrlInfo_TimeGenerated // Add a timestamp column
| join kind=inner (EmailEvents_) on NetworkMessageId // Join with email events on network message ID
| where DeliveryAction !has "Blocked" // Filter out blocked delivery actions
| extend
Name = tostring(split(RecipientEmailAddress, '@', 0)[0]),
UPNSuffix = tostring(split(RecipientEmailAddress, '@', 1)[0]); // Extract name and UPN suffix from recipient email address
entityMappings:
- entityType: Account
fieldMappings:
Expand All @@ -76,5 +92,5 @@ entityMappings:
fieldMappings:
- identifier: Url
columnName: Url
version: 1.0.2
kind: Scheduled
version: 1.0.3
kind: Scheduled
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
id: a924d317-03d2-4420-a71f-4d347bda4bd8
name: TI map IP entity to Workday
description: |
Identifies a match in Workday Activity from any IP IOC from TI
severity: Medium
requiredDataConnectors:
- connectorId: ThreatIntelligence
dataTypes:
- ThreatIntelligenceIndicator
- connectorId: ThreatIntelligenceTaxii
dataTypes:
- ThreatIntelligenceIndicator
- connectorId: Workday
dataTypes:
- Workday
- connectorId: MicrosoftDefenderThreatIntelligence
dataTypes:
- ThreatIntelligenceIndicator
queryFrequency: 1h
queryPeriod: 14d
triggerOperator: gt
triggerThreshold: 0
tactics:
relevantTechniques:
query: |
let dtLookBack = 1h; // Define the lookback period for audit events
let iocLookBack = 14d; // Define the lookback period for threat intelligence indicators
ThreatIntelligenceIndicator
| where isnotempty(NetworkIP)
or isnotempty(EmailSourceIpAddress)
or isnotempty(NetworkDestinationIP)
or isnotempty(NetworkSourceIP) // Filter for indicators with relevant IP fields
| where TimeGenerated >= ago(iocLookBack) // Filter indicators within the lookback period
| extend TI_ipEntity = coalesce(NetworkIP, NetworkDestinationIP, NetworkSourceIP, EmailSourceIpAddress) // Combine IP fields into a single entity
| summarize LatestIndicatorTime = arg_max(TimeGenerated, *) by IndicatorId, TI_ipEntity // Get the latest indicator time for each entity
| where Active == true and ExpirationDateTime > now() // Filter for active indicators that have not expired
| join kind=inner (
ASimAuditEventLogs
| where EventVendor == "Workday" // Filter for Workday events
| where TimeGenerated >= ago(dtLookBack) // Filter events within the lookback period
| where isnotempty(DvcIpAddr) // Filter for events with a device IP address
| extend WD_TimeGenerated = EventStartTime // Rename the event start time column
| project WD_TimeGenerated, ActorUsername, DvcIpAddr, Operation, Object // Select relevant columns
)
on $left.TI_ipEntity == $right.DvcIpAddr // Join on the IP entity
| project
LatestIndicatorTime,
Description,
ActivityGroupNames,
IndicatorId,
ThreatType,
Url,
ExpirationDateTime,
ConfidenceScore,
WD_TimeGenerated,
ActorUsername,
DvcIpAddr,
Operation,
Object // Select relevant columns after the join
| extend
timestamp = WD_TimeGenerated,
Name = tostring(split(ActorUsername, '@', 0)[0]),
UPNSuffix = tostring(split(ActorUsername, '@', 1)[0]) // Add additional fields for timestamp, name, and UPN suffix
entityMappings:
- entityType: Account
fieldMappings:
- identifier: FullName
columnName: ActorUsername
- identifier: Name
columnName: Name
- identifier: UPNSuffix
columnName: UPNSuffix
- entityType: IP
fieldMappings:
- identifier: Address
columnName: DvcIpAddr

version: 1.0.0
kind: Scheduled
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@
"Analytic Rules/EmailEntity_CloudAppEvents.yaml",
"Analytic Rules/FileHashEntity_CloudAppEvents.yaml",
"Analytic Rules/IPEntity_CloudAppEvents.yaml",
"Analytic Rules/URLEntity_CloudAppEvents.yaml"
"Analytic Rules/URLEntity_CloudAppEvents.yaml",
"Analytic Rules/IPEntity_Workday.yaml"
],
"Metadata": "SolutionMetadata.json",
"BasePath": "C:\\GitHub\\Azure-Sentinel\\Solutions\\Threat Intelligence\\",
Expand Down
Binary file added Solutions/Threat Intelligence/Package/3.0.8.zip
Binary file not shown.
16 changes: 15 additions & 1 deletion Solutions/Threat Intelligence/Package/createUiDefinition.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"config": {
"isWizard": false,
"basics": {
"description": "<img src=\"https://raw.githubusercontent.com/Azure/Azure-Sentinel/master/Logos/Azure_Sentinel.svg\"width=\"75px\" height=\"75px\">\n\n**Note:** Please refer to the following before installing the solution: \n\n• Review the solution [Release Notes](https://github.com/Azure/Azure-Sentinel/tree/master/Solutions/Threat%20Intelligence/ReleaseNotes.md)\n\n • There may be [known issues](https://aka.ms/sentinelsolutionsknownissues) pertaining to this Solution, please refer to them before installing.\n\nThe Threat Intelligence solution contains data connectors for import of threat indicators into Microsoft Sentinel, analytic rules for matching TI data with event data, workbook, and hunting queries. Threat indicators can be malicious IP's, URL's, filehashes, domains, email addresses etc.\n\n**Data Connectors:** 5, **Workbooks:** 1, **Analytic Rules:** 52, **Hunting Queries:** 5\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/Azure_Sentinel.svg\"width=\"75px\" height=\"75px\">\n\n**Note:** Please refer to the following before installing the solution: \n\n• Review the solution [Release Notes](https://github.com/Azure/Azure-Sentinel/tree/master/Solutions/Threat%20Intelligence/ReleaseNotes.md)\n\n • There may be [known issues](https://aka.ms/sentinelsolutionsknownissues) pertaining to this Solution, please refer to them before installing.\n\nThe Threat Intelligence solution contains data connectors for import of threat indicators into Microsoft Sentinel, analytic rules for matching TI data with event data, workbook, and hunting queries. Threat indicators can be malicious IP's, URL's, filehashes, domains, email addresses etc.\n\n**Data Connectors:** 5, **Workbooks:** 1, **Analytic Rules:** 53, **Hunting Queries:** 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",
Expand Down Expand Up @@ -954,6 +954,20 @@
}
}
]
},
{
"name": "analytic53",
"type": "Microsoft.Common.Section",
"label": "TI map IP entity to Workday",
"elements": [
{
"name": "analytic53-text",
"type": "Microsoft.Common.TextBlock",
"options": {
"text": "Identifies a match in Workday Activity from any IP IOC from TI"
}
}
]
}
]
},
Expand Down
Loading
Loading