Detection rules › Kusto
Kusto rules: 1b
[AzureSubscription] Suspicious Azure VM Run Command Execution Detected
#Detects Azure VM Run Command execution correlated with unusual sign-in behavior from UEBA. This can indicate administrative abuse or post-compromise activity.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Credential Access | |
| Lateral Movement |
Telemetry Coverage
Rule Body
id: 6fa564ac-dfb7-4753-a49b-5fc919866c28
name: "[AzureSubscription] Suspicious Azure VM Run Command Execution Detected"
version: 1.0.0
kind: Scheduled
description: |
Detects Azure VM Run Command execution correlated with unusual sign-in behavior from UEBA. This can indicate administrative abuse or post-compromise activity.
severity: High
status: Available
requiredDataConnectors:
- connectorId: AzureActivity
dataTypes:
- AzureActivity
queryFrequency: 1d
queryPeriod: 2d
triggerOperator: gt
triggerThreshold: 0
tactics:
- LateralMovement
- CredentialAccess
relevantTechniques:
- T1570
- T1212
query: |
AzureActivity
// Isolate run command actions
| where OperationNameValue =~ "MICROSOFT.COMPUTE/VIRTUALMACHINES/RUNCOMMAND/ACTION"
// Confirm that the operation impacted a virtual machine
| where Authorization has "virtualMachines"
// Each runcommand operation consists of three events when successful, Started, Accepted (or Rejected), Successful (or Failed).
| summarize
StartTime=min(TimeGenerated),
EndTime=max(TimeGenerated),
max(CallerIpAddress),
make_list(ActivityStatusValue)
by CorrelationId, Authorization, Caller, OperationNameValue
// Limit to Run Command executions that Succeeded
| where list_ActivityStatusValue has_any ("Success", "Succeeded")
// Extract data from the Authorization field
| extend Authorization_d = parse_json(Authorization)
| extend Scope = Authorization_d.scope
| extend Scope_s = split(Scope, "/")
| extend Subscription = tostring(Scope_s[2])
| extend VirtualMachineName = tostring(Scope_s[-1])
| project
StartTime,
EndTime,
Subscription,
VirtualMachineName,
CorrelationId,
Caller,
CallerIpAddress=max_CallerIpAddress,
OperationNameValue
// Create a join key using the Caller (UPN)
| extend joinkey = tolower(Caller)
// Join the Run Command actions to UEBA data
| join kind = inner (
BehaviorAnalytics
// We are specifically interested in unusual logins
| where EventSource == "Azure AD" and ActivityInsights.ActionUncommonlyPerformedByUser == "True"
| project
UEBAEventTime=TimeGenerated,
UEBAActionType=ActionType,
UserPrincipalName,
UEBASourceIPLocation=SourceIPLocation,
UEBAActivityInsights=ActivityInsights,
UEBAUsersInsights=UsersInsights
| where isnotempty(UserPrincipalName) and isnotempty(UEBASourceIPLocation)
| extend joinkey = tolower(UserPrincipalName)
)
on joinkey
// Create a window around the UEBA event times, check to see if the Run Command action was performed within them
| extend UEBAWindowStart = UEBAEventTime - 1h, UEBAWindowEnd = UEBAEventTime + 6h
| where StartTime between (UEBAWindowStart .. UEBAWindowEnd)
| project
StartTime,
EndTime,
Subscription,
VirtualMachineName,
Caller,
CallerIpAddress,
UEBAEventTime,
UEBAActionType,
UEBASourceIPLocation,
UEBAActivityInsights,
UEBAUsersInsights,
OperationNameValue
| extend
AccountName = tostring(split(Caller, "@")[0]),
AccountUPNSuffix = tostring(split(Caller, "@")[1])
| extend Source_Network_IPLocation = ""
| project
Alert_Category_en = "Azure Subscription",
Alert_SubCategory_en = "Anomaly User Access Resource",
Alert_Name_en = "Suspicious Azure VM Run Command Execution Detected",
Alert_Description_en=
strcat(
"At Taiwan time: ",
format_datetime(datetime_utc_to_local(StartTime, "Asia/Taipei"), "yyyy-MM-dd HH:mm:ss"),
", detected user ",
iff(isnotempty(Caller), Caller, "<NoCaller>"),
" in subscription ",
iff(isnotempty(Subscription), Subscription, "<NoSubscription>"),
" executed against virtual machine ",
iff(isnotempty(VirtualMachineName), VirtualMachineName, "<NoVM>"),
" successfully performed Run Command operation: ",
OperationNameValue,
". Source IP: ",
iff(isnotempty(CallerIpAddress), CallerIpAddress, "<NoIP>"),
". The user was also flagged by UEBA detection for uncommon behavior: ",
iff(isnotempty(UEBAActionType), UEBAActionType, "<NoUEBAType>"),
", source location: ",
iff(isnotempty(UEBASourceIPLocation), UEBASourceIPLocation, "<NoLocation>"),
", indicating this administrative operation has potential account abuse risk."
),
Alert_TriageStep_en=
strcat(
"1. Confirm whether user ",
iff(isnotempty(Caller), Caller, "<NoCaller>"),
" is a legitimate operator/maintainer of the VM, and check whether there is a corresponding change or maintenance ticket.",
"2. Review whether Run Command is an expected command and confirm whether it involves download, account creation, service modification, or persistence behavior.",
"3. Compare source IP ",
iff(isnotempty(CallerIpAddress), CallerIpAddress, "<NoIP>"),
" with the location flagged by UEBA ",
iff(isnotempty(UEBASourceIPLocation), UEBASourceIPLocation, "<NoLocation>"),
" to determine whether it is abnormal (VPN, uncommon location, jump server)."
),
Alert_Containment_en=
strcat(
"1. If confirmed as an unauthorized operation, immediately revoke user ",
iff(isnotempty(Caller), Caller, "<NoCaller>"),
" 's existing sign-in sessions and access tokens, and force re-authentication or suspend the account.",
"2. Temporarily remove the account's administrative permissions on the target virtual machine (such as Virtual Machine Contributor / Owner) to prevent Run Command from being executed again.",
"3. For source IP ",
iff(isnotempty(CallerIpAddress), CallerIpAddress, "<NoIP>"),
" block it or increase Conditional Access restrictions to prevent continued abuse.",
"4. Depending on the risk level, isolate the affected VM and perform cybersecurity forensics to prevent lateral movement or malicious persistence."
),
Alert_Remediation_en=
strcat(
"1. Apply the least privilege principle to all roles that can execute Run Command, and manage high-privilege accounts through PIM/JIT.",
"2. Strengthen Conditional Access policies by requiring management operations to pass MFA, device compliance, and named location checks, and block uncommon location sign-ins.",
"3. Establish real-time alerts and automated response for Run Command-related activity, such as revoking sessions, disabling accounts, and notifying SOC.",
"4. Ensure Defender for Cloud and EDR are enabled on virtual machines, and regularly audit scheduled tasks, services, and startup items on VMs to avoid malicious command remnants.",
"5. Reduce the risk of hosts being exploited again through known vulnerabilities by applying regular security patches and vulnerability updates."
),
Alert_Time_TW = datetime_utc_to_local(StartTime, "Asia/Taipei"),
Alert_Time_UTC0 = StartTime,
Event_TimeRange_Start_TW = datetime_utc_to_local(StartTime, 'Asia/Taipei'),
Event_TimeRange_End_TW = datetime_utc_to_local(EndTime, 'Asia/Taipei'),
Event_TimeRange_Start_UTC0 = StartTime,
Event_TimeRange_End_UTC0 = EndTime,
Event_Action = OperationNameValue,
//Event_Code = score,
Source_Identity_FullName = Caller,
//Source_Identity_ID = ActorID,
Source_Identity_Type = iff(Caller contains '@', "User", "Service"),
Source_Network_IPAddress = CallerIpAddress,
Source_Network_IPLocation = Source_Network_IPLocation,
Target_Device_Name = VirtualMachineName,
Target_Resource_ID = Subscription,
Target_Resource_Type = "Azure Subscription"
entityMappings:
- entityType: Account
fieldMappings:
- identifier: FullName
columnName: Source_Identity_FullName
- entityType: Host
fieldMappings:
- identifier: HostName
columnName: Target_Device_Name
- entityType: IP
fieldMappings:
- identifier: Address
columnName: Source_Network_IPAddress
Stages and Predicates
Stage 1: source
AzureActivity
Stage 2: where
| where OperationNameValue =~ "MICROSOFT.COMPUTE/VIRTUALMACHINES/RUNCOMMAND/ACTION"
Stage 3: where
| where Authorization has "virtualMachines"
Stage 4: summarize
| summarize
StartTime=min(TimeGenerated),
EndTime=max(TimeGenerated),
max(CallerIpAddress),
make_list(ActivityStatusValue)
by CorrelationId, Authorization, Caller, OperationNameValue
Stage 5: where
| where list_ActivityStatusValue has_any ("Success", "Succeeded")
Stage 6: extend (5 consecutive steps)
| extend Authorization_d = parse_json(Authorization)
| extend Scope = Authorization_d.scope
| extend Scope_s = split(Scope, "/")
| extend Subscription = tostring(Scope_s[2])
| extend VirtualMachineName = tostring(Scope_s[-1])
Stage 7: project
| project
StartTime,
EndTime,
Subscription,
VirtualMachineName,
CorrelationId,
Caller,
CallerIpAddress=max_CallerIpAddress,
OperationNameValue
Stage 8: extend
| extend joinkey = tolower(Caller)
Stage 9: join
| join kind = inner (
BehaviorAnalytics
| where EventSource == "Azure AD" and ActivityInsights.ActionUncommonlyPerformedByUser == "True"
| project
UEBAEventTime=TimeGenerated,
UEBAActionType=ActionType,
UserPrincipalName,
UEBASourceIPLocation=SourceIPLocation,
UEBAActivityInsights=ActivityInsights,
UEBAUsersInsights=UsersInsights
| where isnotempty(UserPrincipalName) and isnotempty(UEBASourceIPLocation)
| extend joinkey = tolower(UserPrincipalName)
)
on joinkey
Stage 10: extend
extend UEBAWindowEnd, UEBAWindowStart
Stage 11: where
where StartTime >= "UEBAWindowStart" and StartTime <= "UEBAWindowEnd"
Stage 12: project
project Caller, CallerIpAddress, EndTime, OperationNameValue, StartTime, Subscription, UEBAActionType, UEBAActivityInsights, UEBAEventTime, UEBASourceIPLocation, UEBAUsersInsights, VirtualMachineName
Stage 13: extend
extend AccountName, AccountUPNSuffix
Stage 14: extend
extend Source_Network_IPLocation
Stage 15: project
project Alert_Category_en, Alert_Containment_en, Alert_Description_en, Alert_Name_en, Alert_Remediation_en, Alert_SubCategory_en, Alert_Time_TW, Alert_Time_UTC0, Alert_TriageStep_en, Event_Action, Event_TimeRange_End_TW, Event_TimeRange_End_UTC0, Event_TimeRange_Start_TW, Event_TimeRange_Start_UTC0, Source_Identity_FullName, Source_Identity_Type, Source_Network_IPAddress, Source_Network_IPLocation, Target_Device_Name, Target_Resource_ID, Target_Resource_Type
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
ActivityInsights.ActionUncommonlyPerformedByUser | eq |
| field:"ActivityInsights.ActionUncommonlyPerformedByUser" kind:eq value:"True" |
Authorization | match |
| field:"Authorization" kind:match value:"virtualMachines" |
EventSource | eq |
| field:"EventSource" kind:eq value:"Azure AD" |
OperationNameValue | eq |
| field:"azure_ad::operation_name_value" kind:eq value:"MICROSOFT.COMPUTE/VIRTUALMACHINES/RUNCOMMAND/ACTION" |
StartTime | ge |
| field:"StartTime" kind:ge value:"UEBAWindowStart" |
StartTime | le |
| field:"StartTime" kind:le value:"UEBAWindowEnd" |
UEBASourceIPLocation | is_not_null | field:"UEBASourceIPLocation" kind:is_not_null | |
UserPrincipalName | is_not_null | field:"UserPrincipalName" kind:is_not_null | |
list_ActivityStatusValue | match |
| field:"list_ActivityStatusValue" kind:match |
Output Fields
These fields are emitted when the rule matches.
| Field | Source |
|---|---|
Alert_Category_en | project |
Alert_Containment_en | project |
Alert_Description_en | project |
Alert_Name_en | project |
Alert_Remediation_en | project |
Alert_SubCategory_en | project |
Alert_Time_TW | project |
Alert_Time_UTC0 | project |
Alert_TriageStep_en | project |
Event_Action | project |
Event_TimeRange_End_TW | project |
Event_TimeRange_End_UTC0 | project |
Event_TimeRange_Start_TW | project |
Event_TimeRange_Start_UTC0 | project |
Source_Identity_FullName | project |
Source_Identity_Type | project |
Source_Network_IPAddress | project |
Source_Network_IPLocation | project |
Target_Device_Name | project |
Target_Resource_ID | project |
Target_Resource_Type | project |
API - JWT validation
#'42Crunch API protection against JWT validation'
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Initial Access | |
| Credential Access |
Rule Body
id: bbd163f4-1f56-434f-9c23-b06713c119c2
name: API - JWT validation
description: |
'42Crunch API protection against JWT validation'
severity: Low
requiredDataConnectors:
- connectorId: 42CrunchAPIProtection
dataTypes:
- FortyTwoCrunchAPIProtection
- connectorId: FortyTwoCrunchAPIProtection
dataTypes:
- FortyTwoCrunchAPIProtection
queryFrequency: 5m
queryPeriod: 5m
triggerOperator: gt
triggerThreshold: 0
eventGroupingSettings:
aggregationKind: SingleAlert
status: Available
tactics:
- InitialAccess
- CredentialAccess
relevantTechniques:
- T1190
- T1528
query: |
FortyTwoCrunchAPIProtection
| where TimeGenerated >= ago(5m)
| where ErrorMessage has "missing [\"x-access-token\"]"
| project-away NonBlockingMode, SourcePort, DestinationPort, Query, ApiId, ResponseHeader, RequestHeader, Errors, EventType, Uuid
| sort by TimeGenerated desc
customDetails:
entityMappings:
- entityType: IP
fieldMappings:
- identifier: Address
columnName: SourceIp
- entityType: Host
fieldMappings:
- identifier: HostName
columnName: Hostname
- entityType: Account
fieldMappings:
- identifier: FullName
columnName: InstanceName
version: 3.0.1
kind: Scheduled
Stages and Predicates
Stage 1: source
FortyTwoCrunchAPIProtection
Stage 2: where
| where TimeGenerated >= ago(5m)
Stage 3: where
| where ErrorMessage has "missing [\"x-access-token\"]"
Stage 4: project-away
| project-away NonBlockingMode, SourcePort, DestinationPort, Query, ApiId, ResponseHeader, RequestHeader, Errors, EventType, Uuid
Stage 5: sort
| sort by TimeGenerated desc
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
ErrorMessage | match |
| field:"aws::errorMessage" kind:match |
AWSCloudTrail - Privilege escalation via CloudFormation policy
#Detects creation of inline IAM policies with CloudFormation and IAM permissions associated with privilege escalation pathways, including iam:PassRole plus stack creation capabilities. This pattern can enable indirect elevation and should be investigated for unauthorized policy changes.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Privilege Escalation |
Telemetry Coverage
Rules Detecting the Same Action
These rules filter on the same operation.
- AWS IAM Access Key Compromise Detection (Panther)
- AWS Lateral Movement from Kubernetes SA via AssumeRoleWithWebIdentity (Elastic)
- AWSCloudTrail - Privilege escalation via CRUD DynamoDB policy (Kusto)
- AWSCloudTrail - Privilege escalation via CRUD IAM policy (Kusto)
- AWSCloudTrail - Privilege escalation via CRUD KMS policy (Kusto)
- AWSCloudTrail - Privilege escalation via CRUD Lambda policy (Kusto)
- AWSCloudTrail - Privilege escalation via CRUD S3 policy (Kusto)
- AWSCloudTrail - Privilege escalation via DataPipeline policy (Kusto)
Rule Body
id: 719d5204-10ab-4b1f-aee1-da7326750260
name: AWSCloudTrail - Privilege escalation via CloudFormation policy
description: |
Detects creation of inline IAM policies with CloudFormation and IAM permissions associated with privilege
escalation pathways, including iam:PassRole plus stack creation capabilities. This pattern can enable indirect
elevation and should be investigated for unauthorized policy changes.
severity: Medium
status: Available
requiredDataConnectors:
- connectorId: AWS
dataTypes:
- AWSCloudTrail
queryFrequency: 1d
queryPeriod: 1d
triggerOperator: gt
triggerThreshold: 0
tactics:
- PrivilegeEscalation
relevantTechniques:
- T1098.003
query: |
AWSCloudTrail
| where EventName in ("PutUserPolicy","PutRolePolicy","PutGroupPolicy") and isempty(ErrorCode) and isempty(ErrorMessage)
| extend PolicyName = tostring(parse_json(RequestParameters).policyName)
| extend Statement = parse_json(tostring((parse_json(RequestParameters).policyDocument))).Statement
| mvexpand Statement
| extend Action = parse_json(Statement).Action , Effect = tostring(parse_json(Statement).Effect), Resource = tostring(parse_json(Statement).Resource), Condition = tostring(parse_json(Statement).Condition)
| extend Action = tostring(Action)
| where Effect =~ "Allow" and (((Action has "iam:*" or Action has "iam:PassRole") and Action has "cloudformation:*") or ((Action has "iam:*" or Action has "iam:PassRole") and Action contains "cloudformation:DescribeStacks" and Action contains "cloudformation:CreateStack") or ((Action contains "iam:*" or Action contains "iam:PassRole") and Action contains "cloudformation:Describe*" and Action contains "cloudformation:Create*")) and Resource == "*" and Condition == ""
| extend UserIdentityArn = iif(isempty(UserIdentityArn), tostring(parse_json(Resources)[0].ARN), UserIdentityArn)
| extend UserName = tostring(split(UserIdentityArn, '/')[-1])
| extend AccountName = case( UserIdentityPrincipalid == "Anonymous", "Anonymous", isempty(UserIdentityUserName), UserName, UserIdentityUserName)
| extend AccountName = iif(AccountName contains "@", tostring(split(AccountName, '@', 0)[0]), AccountName),
AccountUPNSuffix = iif(AccountName contains "@", tostring(split(AccountName, '@', 1)[0]), "")
| distinct TimeGenerated, EventName, PolicyName, SourceIpAddress, RecipientAccountId, AccountName, AccountUPNSuffix, UserIdentityArn, UserIdentityUserName
entityMappings:
- entityType: Account
fieldMappings:
- identifier: Name
columnName: AccountName
- identifier: UPNSuffix
columnName: AccountUPNSuffix
- identifier: CloudAppAccountId
columnName: RecipientAccountId
- entityType: IP
fieldMappings:
- identifier: Address
columnName: SourceIpAddress
customDetails:
PolicyName: PolicyName
EventName: EventName
UserIdentityArn: UserIdentityArn
RecipientAccountId: RecipientAccountId
alertDetailsOverride:
alertDisplayNameFormat: 'AWS CloudFormation privilege escalation policy update by {{AccountName}}'
alertDescriptionFormat: 'Detected {{EventName}} Event, updating inline CloudFormation escalation policy {{PolicyName}} in account {{RecipientAccountId}}.'
version: 1.0.2
kind: Scheduled
Stages and Predicates
Stage 1: source
AWSCloudTrail
Stage 2: where
| where EventName in ("PutUserPolicy","PutRolePolicy","PutGroupPolicy") and isempty(ErrorCode) and isempty(ErrorMessage)
Stage 3: extend
| extend PolicyName = tostring(parse_json(RequestParameters).policyName)
Stage 4: extend
| extend Statement = parse_json(tostring((parse_json(RequestParameters).policyDocument))).Statement
Stage 5: mv-expand
| mvexpand Statement
Stage 6: extend
| extend Action = parse_json(Statement).Action , Effect = tostring(parse_json(Statement).Effect), Resource = tostring(parse_json(Statement).Resource), Condition = tostring(parse_json(Statement).Condition)
Stage 7: extend
| extend Action = tostring(Action)
Stage 8: where
| where Effect =~ "Allow" and (((Action has "iam:*" or Action has "iam:PassRole") and Action has "cloudformation:*") or ((Action has "iam:*" or Action has "iam:PassRole") and Action contains "cloudformation:DescribeStacks" and Action contains "cloudformation:CreateStack") or ((Action contains "iam:*" or Action contains "iam:PassRole") and Action contains "cloudformation:Describe*" and Action contains "cloudformation:Create*")) and Resource == "*" and Condition == ""
Stage 9: extend (4 consecutive steps)
| extend UserIdentityArn = iif(isempty(UserIdentityArn), tostring(parse_json(Resources)[0].ARN), UserIdentityArn)
| extend UserName = tostring(split(UserIdentityArn, '/')[-1])
| extend AccountName = case( UserIdentityPrincipalid == "Anonymous", "Anonymous", isempty(UserIdentityUserName), UserName, UserIdentityUserName)
| extend AccountName = iif(AccountName contains "@", tostring(split(AccountName, '@', 0)[0]), AccountName),
AccountUPNSuffix = iif(AccountName contains "@", tostring(split(AccountName, '@', 1)[0]), "")
Stage 10: distinct
| distinct TimeGenerated, EventName, PolicyName, SourceIpAddress, RecipientAccountId, AccountName, AccountUPNSuffix, UserIdentityArn, UserIdentityUserName
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
Action | contains |
| field:"Action" kind:contains |
Action | match |
| field:"Action" kind:match |
Effect | eq |
| field:"Effect" kind:eq value:"Allow" |
ErrorCode | is_null | field:"aws::errorCode" kind:is_null | |
ErrorMessage | is_null | field:"aws::errorMessage" kind:is_null | |
EventName | in |
| field:"aws::eventName" kind:in |
Resource | eq |
| field:"Resource" kind:eq value:"*" |
Output Fields
These fields are emitted when the rule matches.
| Field | Source |
|---|---|
PolicyName | extend |
Statement | extend |
Action | extend |
Condition | extend |
Effect | extend |
Resource | extend |
UserIdentityArn | extend |
UserName | extend |
AccountName | extend |
AccountUPNSuffix | extend |
Cisco Cloud Security - Empty User Agent Detected
#'Rule helps to detect empty and unusual user agent indicating web browsing activity by an unusual process other than a web browser.'
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Command & Control |
Rule Body
id: 2b328487-162d-4034-b472-59f1d53684a1
name: Cisco Cloud Security - Empty User Agent Detected
description: |
'Rule helps to detect empty and unusual user agent indicating web browsing activity by an unusual process other than a web browser.'
severity: Medium
status: Available
requiredDataConnectors:
- connectorId: CiscoUmbrellaDataConnector
dataTypes:
- Cisco_Umbrella_proxy_CL
queryFrequency: 15m
queryPeriod: 15m
triggerOperator: gt
triggerThreshold: 0
tactics:
- CommandAndControl
relevantTechniques:
- T1001.003
query: |
Cisco_Umbrella
| where EventType == "proxylogs"
| where HttpUserAgentOriginal == ''
| extend Message = "Empty User Agent"
| project TimeGenerated, Message, SrcIpAddr, DstIpAddr, UrlOriginal
entityMappings:
- entityType: URL
fieldMappings:
- identifier: Url
columnName: UrlOriginal
- entityType: IP
fieldMappings:
- identifier: Address
columnName: SrcIpAddr
version: 1.1.3
kind: Scheduled
Stages and Predicates
Stage 1: source
Cisco_Umbrella
Stage 2: where
| where EventType == "proxylogs"
Stage 3: where
| where HttpUserAgentOriginal == ''
Stage 4: extend
| extend Message = "Empty User Agent"
Stage 5: project
| project TimeGenerated, Message, SrcIpAddr, DstIpAddr, UrlOriginal
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
EventType | eq |
| field:"EventType" kind:eq value:"proxylogs" |
Output Fields
These fields are emitted when the rule matches.
| Field | Source |
|---|---|
DstIpAddr | project |
Message | project |
SrcIpAddr | project |
TimeGenerated | project |
UrlOriginal | project |
CiscoISE - Log collector was suspended
#'Detects when log collector was suspended.'
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Defense Impairment |
Rule Body
id: ce171782-1643-4f21-bbb7-fa954b1e6897
name: CiscoISE - Log collector was suspended
description: |
'Detects when log collector was suspended.'
severity: Medium
status: Available
requiredDataConnectors:
- connectorId: SyslogAma
datatypes:
- Syslog
queryFrequency: 10m
queryPeriod: 10m
triggerOperator: gt
triggerThreshold: 0
tactics:
- DefenseEvasion
relevantTechniques:
- T1562.002
query: |
let lbtime = 10m;
CiscoISEEvent
| where TimeGenerated > ago(lbtime)
| where EventId == '59207'
| project TimeGenerated, SrcIpAddr, DstIpAddr
| extend IPCustomEntity = DstIpAddr
entityMappings:
- entityType: IP
fieldMappings:
- identifier: Address
columnName: IPCustomEntity
version: 1.0.3
kind: Scheduled
Stages and Predicates
Parameters
let lbtime = 10m;
Stage 1: source
CiscoISEEvent
Stage 2: where
| where TimeGenerated > ago(lbtime)
Stage 3: where
| where EventId == '59207'
Stage 4: project
| project TimeGenerated, SrcIpAddr, DstIpAddr
Stage 5: extend
| extend IPCustomEntity = DstIpAddr
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
EventId | eq |
| field:"EventId" kind:eq value:"59207" |
Output Fields
These fields are emitted when the rule matches.
| Field | Source |
|---|---|
DstIpAddr | project |
SrcIpAddr | project |
TimeGenerated | project |
IPCustomEntity | extend |
CTE - Admin Login Detected
#An administrator logged into the Cybereinforce console.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Initial Access |
Rule Body
id: 65bc5f1d-d29d-4729-a5a6-d9614b0900e0
name: CTE - Admin Login Detected
description: |
An administrator logged into the Cybereinforce console.
severity: Informational
requiredDataConnectors:
- connectorId: cybereinforce_cte
dataTypes:
- CybereinforceCTE_CL
queryFrequency: 30m
queryPeriod: 30m
triggerOperator: gt
triggerThreshold: 0
tactics:
- InitialAccess
relevantTechniques:
- T1078
query: |
CybereinforceCTE_CL
| where EventType == "auth.login"
| extend AccountName = tostring(split(Actor, "@")[0]), UPNSuffix = tostring(split(Actor, "@")[1])
| project TimeGenerated, TenantId, Actor, AccountName, UPNSuffix, Severity, Category, Source
entityMappings:
- entityType: Account
fieldMappings:
- identifier: Name
columnName: AccountName
- identifier: UPNSuffix
columnName: UPNSuffix
version: 1.0.0
kind: Scheduled
Stages and Predicates
Stage 1: source
CybereinforceCTE_CL
Stage 2: where
| where EventType == "auth.login"
Stage 3: extend
| extend AccountName = tostring(split(Actor, "@")[0]), UPNSuffix = tostring(split(Actor, "@")[1])
Stage 4: project
| project TimeGenerated, TenantId, Actor, AccountName, UPNSuffix, Severity, Category, Source
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
EventType | eq |
| field:"EventType" kind:eq value:"auth.login" |
Output Fields
These fields are emitted when the rule matches.
| Field | Source |
|---|---|
AccountName | project |
Actor | project |
Category | project |
Severity | project |
Source | project |
TenantId | project |
TimeGenerated | project |
UPNSuffix | project |
DNS events related to mining pools (ASIM DNS Schema)
#Identifies IP addresses that may be performing DNS lookups associated with common currency mining pools. This analytic rule uses ASIM and supports any built-in or custom source that supports the ASIM DNS schema
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Impact |
Telemetry Coverage
| Provider | Record / event type |
|---|---|
| Sysmon | Event ID 22: DNSEvent (DNS query) |
Rule Body
id: c094384d-7ea7-4091-83be-18706ecca981
name: DNS events related to mining pools (ASIM DNS Schema)
description: |
'Identifies IP addresses that may be performing DNS lookups associated with common currency mining pools.
This analytic rule uses [ASIM](https://aka.ms/AboutASIM) and supports any built-in or custom source that supports the ASIM DNS schema'
severity: Low
requiredDataConnectors:
- connectorId: WindowsForwardedEvents
dataTypes:
- WindowsEvent
- connectorId: DNS
dataTypes:
- DnsEvents
- connectorId: AzureFirewall
dataTypes:
- AzureDiagnostics
- connectorId: Zscaler
dataTypes:
- CommonSecurityLog
- connectorId: InfobloxNIOS
dataTypes:
- Syslog
- connectorId: GCPDNSDataConnector
dataTypes:
- GCP_DNS_CL
- connectorId: NXLogDnsLogs
dataTypes:
- NXLog_DNS_Server_CL
- connectorId: CiscoUmbrellaDataConnector
dataTypes:
- Cisco_Umbrella_dns_CL
- connectorId: Corelight
dataTypes:
- Corelight_CL
queryFrequency: 1d
queryPeriod: 1d
triggerOperator: gt
triggerThreshold: 0
tactics:
- Impact
relevantTechniques:
- T1496
tags:
- ParentAlert: https://github.com/Azure/Azure-Sentinel/blob/master/Detections/DnsEvents/DNS_Miners.yaml
version: 1.0.0
- Schema: ASIMDns
SchemaVersion: 0.1.1
query: |
let minersDomains=dynamic(["monerohash.com", "do-dear.com", "xmrminerpro.com", "secumine.net", "xmrpool.com", "minexmr.org", "hashanywhere.com",
"xmrget.com", "mininglottery.eu", "minergate.com", "moriaxmr.com", "multipooler.com", "moneropools.com", "xmrpool.eu", "coolmining.club",
"supportxmr.com", "minexmr.com", "hashvault.pro", "xmrpool.net", "crypto-pool.fr", "xmr.pt", "miner.rocks", "walpool.com", "herominers.com",
"gntl.co.uk", "semipool.com", "coinfoundry.org", "cryptoknight.cc", "fairhash.org", "baikalmine.com", "tubepool.xyz", "fairpool.xyz", "asiapool.io",
"coinpoolit.webhop.me", "nanopool.org", "moneropool.com", "miner.center", "prohash.net", "poolto.be", "cryptoescrow.eu", "monerominers.net", "cryptonotepool.org",
"extrmepool.org", "webcoin.me", "kippo.eu", "hashinvest.ws", "monero.farm", "supportxmr.com", "xmrpool.eu", "linux-repository-updates.com", "1gh.com",
"dwarfpool.com", "hash-to-coins.com", "hashvault.pro", "pool-proxy.com", "hashfor.cash", "fairpool.cloud", "litecoinpool.org", "mineshaft.ml", "abcxyz.stream",
"moneropool.ru", "cryptonotepool.org.uk", "extremepool.org", "extremehash.com", "hashinvest.net", "unipool.pro", "crypto-pools.org", "monero.net",
"backup-pool.com", "mooo.com", "freeyy.me", "cryptonight.net", "shscrypto.net"]);
_Im_Dns(domain_has_any=minersDomains)
| extend HostName = tostring(split(Dvc, ".")[0]), DomainIndex = toint(indexof(Dvc, '.'))
| extend HostNameDomain = iff(DomainIndex != -1, substring(Dvc, DomainIndex + 1), Dvc)
| project-away DomainIndex
entityMappings:
- entityType: Host
fieldMappings:
- identifier: FullName
columnName: Dvc
- identifier: HostName
columnName: HostName
- identifier: DnsDomain
columnName: HostNameDomain
- entityType: IP
fieldMappings:
- identifier: Address
columnName: SrcIpAddr
- entityType: AzureResource
fieldMappings:
- identifier: ResourceId
columnName: _ResourceId
version: 1.3.5
kind: Scheduled
metadata:
source:
kind: Community
author:
name: Microsoft Security Research
support:
tier: Community
categories:
domains: [ "Security - Network" ]
Stages and Predicates
Let Binding: minersDomains
let minersDomains = dynamic(["monerohash.com", "do-dear.com", "xmrminerpro.com", "secumine.net", "xmrpool.com", "minexmr.org", "hashanywhere.com",
"xmrget.com", "mininglottery.eu", "minergate.com", "moriaxmr.com", "multipooler.com", "moneropools.com", "xmrpool.eu", "coolmining.club",
"supportxmr.com", "minexmr.com", "hashvault.pro", "xmrpool.net", "crypto-pool.fr", "xmr.pt", "miner.rocks", "walpool.com", "herominers.com",
"gntl.co.uk", "semipool.com", "coinfoundry.org", "cryptoknight.cc", "fairhash.org", "baikalmine.com", "tubepool.xyz", "fairpool.xyz", "asiapool.io",
"coinpoolit.webhop.me", "nanopool.org", "moneropool.com", "miner.center", "prohash.net", "poolto.be", "cryptoescrow.eu", "monerominers.net", "cryptonotepool.org",
"extrmepool.org", "webcoin.me", "kippo.eu", "hashinvest.ws", "monero.farm", "supportxmr.com", "xmrpool.eu", "linux-repository-updates.com", "1gh.com",
"dwarfpool.com", "hash-to-coins.com", "hashvault.pro", "pool-proxy.com", "hashfor.cash", "fairpool.cloud", "litecoinpool.org", "mineshaft.ml", "abcxyz.stream",
"moneropool.ru", "cryptonotepool.org.uk", "extremepool.org", "extremehash.com", "hashinvest.net", "unipool.pro", "crypto-pools.org", "monero.net",
"backup-pool.com", "mooo.com", "freeyy.me", "cryptonight.net", "shscrypto.net"]);
Stage 1: source
_Im_Dns(domain_has_any=minersDomains)
Stage 2: extend
| extend HostName = tostring(split(Dvc, ".")[0]), DomainIndex = toint(indexof(Dvc, '.'))
Stage 3: extend
| extend HostNameDomain = iff(DomainIndex != -1, substring(Dvc, DomainIndex + 1), Dvc)
HostNameDomain =DomainIndex != -1substring(Dvc, (DomainIndex + 1))DvcStage 4: project-away
| project-away DomainIndex
Output Fields
These fields are emitted when the rule matches.
| Field | Source |
|---|---|
HostName | extend |
HostNameDomain | extend |
Flare source code results
#This is a third-party alert feed, not a detection over modeled telemetry. The vendor product raised the finding; this rule forwards it into the SIEM. It is searchable for reference but is excluded from the detection-rule browse and the ATT&CK coverage matrix.
'This query searches for events found on code sharing platforms.'
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Reconnaissance |
Rule Body
id: 9cb7c337-f178-4af6-b0e8-b6b7552d762d
name: Flare source code results
description: |
'This query searches for events found on code sharing platforms.'
severity: Medium
status: Available
requiredDataConnectors:
- connectorId: Flare
dataTypes:
- FireworkV2_CL
queryFrequency: 1h
queryPeriod: 1h
triggerOperator: gt
triggerThreshold: 0
tactics:
- Reconnaissance
relevantTechniques:
- T1593
query: |
FireworkV2_CL
| where notempty(uid) and RiskScore >= 3
| extend index_name = split(uid, "/")[0]
| extend category_name = split(uid, "/")[1]
| where index_name == "driller" and category_name contains "github"
version: 3.0.0
kind: Scheduled
Stages and Predicates
Stage 1: source
FireworkV2_CL
Stage 2: where
| where notempty(uid) and RiskScore >= 3
Stage 3: extend
| extend index_name = split(uid, "/")[0]
Stage 4: extend
| extend category_name = split(uid, "/")[1]
Stage 5: where
| where index_name == "driller" and category_name contains "github"
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
RiskScore | ge |
| field:"RiskScore" kind:ge value:"3" |
category_name | contains |
| field:"category_name" kind:contains value:"github" |
index_name | eq |
| field:"index_name" kind:eq value:"driller" |
uid | is_not_null | field:"uid" kind:is_not_null |
Output Fields
These fields are emitted when the rule matches.
| Field | Source |
|---|---|
index_name | extend |
category_name | extend |
Four-Eyes Authorization Request Rejected
#Detects when a four-eyes authorization request is rejected.
Rule Body
id: dfd1d756-623d-4951-84a5-ce51f726d322
name: Four-Eyes Authorization Request Rejected
description: Detects when a four-eyes authorization request is rejected.
severity: Informational
status: Available
requiredDataConnectors:
- connectorId: Syslog
dataTypes:
- Syslog
- connectorId: SyslogAma
dataTypes:
- Syslog
queryFrequency: 1d
queryPeriod: 1d
triggerOperator: gt
triggerThreshold: 0
eventGroupingSettings:
aggregationKind: AlertPerResult
tactics: []
relevantTechniques: []
query: "Veeam_GetSecurityEvents\n| where instanceId == 42404\n| extend Operation =\
\ extract(\"Operation=\\\"([^\\\"]*)\\\"\", 1, SyslogMessage)\n| project\n Date\
\ = format_datetime(TimeGenerated, 'dd.MM.yyyy HH:mm'),\n DataSource = original_host,\n\
\ EventId = instanceId,\n [\"User Name\"] = user,\n [\"Operation Name\"\
] = Operation,\n MessageDetails = Description,\n Severity = SeverityDescription"
version: 1.0.1
kind: Scheduled
customDetails:
Date: Date
VbrHostName: DataSource
EventId: EventId
MessageDetails: MessageDetails
Severity: Severity
Stages and Predicates
Stage 1: source
Veeam_GetSecurityEvents
Stage 2: where
| where instanceId == 42404
Stage 3: extend
| extend Operation = extract("Operation=\"([^\"]*)\"", 1, SyslogMessage)
Stage 4: project
| project
Date = format_datetime(TimeGenerated, 'dd.MM.yyyy HH:mm'),
DataSource = original_host,
EventId = instanceId,
["User Name"] = user,
["Operation Name"] = Operation,
MessageDetails = Description,
Severity = SeverityDescription
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
instanceId | eq |
| field:"instanceId" kind:eq value:"42404" |
Output Fields
These fields are emitted when the rule matches.
| Field | Source |
|---|---|
DataSource | project |
Date | project |
EventId | project |
MessageDetails | project |
Operation Name | project |
Severity | project |
User Name | project |
GCP IAM - High privileged role added to service account
#'Detects when high privileged role was added to service account.'
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Privilege Escalation |
Rules Detecting the Same Action
These rules filter on the same operation.
Rule Body
id: 86112c4b-2535-4178-aa0e-ed9e32e3f054
name: GCP IAM - High privileged role added to service account
description: |
'Detects when high privileged role was added to service account.'
severity: High
status: Available
requiredDataConnectors:
- connectorId: GCPIAMDataConnector
dataTypes:
- GCP_IAM
queryFrequency: 15m
queryPeriod: 15m
triggerOperator: gt
triggerThreshold: 0
tactics:
- PrivilegeEscalation
relevantTechniques:
- T1078
query: |
let privileged_roles = dynamic(['roles/iam.securityAdmin', 'roles/secretmanager.admin', 'roles/secretmanager.secretAccessor', 'roles/apigateway.admin', 'roles/logging.admin', 'roles/iam.organizationRoleAdmin', 'roles/iam.roleAdmin', 'roles/iam.serviceAccountAdmin', 'roles/iam.serviceAccountCreator', 'roles/iam.serviceAccountKeyAdmin']);
GCP_IAM
| where PayloadMethodname =~ 'SetIamPolicy'
| extend action = parse_json(todynamic(PayloadServicedataPolicydeltaBindingdeltas))[0]['action']
| where action =~ 'ADD'
| extend role = parse_json(todynamic(PayloadServicedataPolicydeltaBindingdeltas))[0]['role']
| where role in~ (privileged_roles)
| project-away action
| extend AccountName = tostring(split(PayloadAuthenticationinfoPrincipalemail, "@")[0]), AccountUPNSuffix = tostring(split(PayloadAuthenticationinfoPrincipalemail, "@")[1])
entityMappings:
- entityType: Account
fieldMappings:
- identifier: FullName
columnName: PayloadAuthenticationinfoPrincipalemail
- identifier: Name
columnName: AccountName
- identifier: UPNSuffix
columnName: AccountUPNSuffix
- entityType: IP
fieldMappings:
- identifier: Address
columnName: SrcIpAddr
version: 1.0.1
kind: Scheduled
Stages and Predicates
Let Binding: privileged_roles
let privileged_roles = dynamic(['roles/iam.securityAdmin', 'roles/secretmanager.admin', 'roles/secretmanager.secretAccessor', 'roles/apigateway.admin', 'roles/logging.admin', 'roles/iam.organizationRoleAdmin', 'roles/iam.roleAdmin', 'roles/iam.serviceAccountAdmin', 'roles/iam.serviceAccountCreator', 'roles/iam.serviceAccountKeyAdmin']);
Stage 1: source
GCP_IAM
Stage 2: where
| where PayloadMethodname =~ 'SetIamPolicy'
Stage 3: extend
| extend action = parse_json(todynamic(PayloadServicedataPolicydeltaBindingdeltas))[0]['action']
Stage 4: where
| where action =~ 'ADD'
Stage 5: extend
| extend role = parse_json(todynamic(PayloadServicedataPolicydeltaBindingdeltas))[0]['role']
Stage 6: where
| where role in~ (privileged_roles)
Stage 7: project-away
| project-away action
Stage 8: extend
| extend AccountName = tostring(split(PayloadAuthenticationinfoPrincipalemail, "@")[0]), AccountUPNSuffix = tostring(split(PayloadAuthenticationinfoPrincipalemail, "@")[1])
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
PayloadMethodname | eq |
| field:"gcp::method_name" kind:eq value:"SetIamPolicy" |
action | eq |
| field:"action" kind:eq value:"ADD" |
role | in |
| field:"role" kind:in |
Output Fields
These fields are emitted when the rule matches.
| Field | Source |
|---|---|
role | extend |
AccountName | extend |
AccountUPNSuffix | extend |
PaloAlto - Forbidden countries
#'Detects suspicious connections from forbidden countries.'
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Initial Access |
Rule Body
id: 9fcc7734-4d1b-11ec-81d3-0242ac130003
name: PaloAlto - Forbidden countries
description: |
'Detects suspicious connections from forbidden countries.'
severity: Medium
status: Available
requiredDataConnectors:
- connectorId: CefAma
dataTypes:
- CommonSecurityLog
queryFrequency: 1h
queryPeriod: 1h
triggerOperator: gt
triggerThreshold: 0
tactics:
- InitialAccess
relevantTechniques:
- T1190
- T1133
query: |
let bl_countries = dynamic(['CH', 'RU']);
PaloAltoCDLEvent
| where EventResourceId =~ 'TRAFFIC'
| where MaliciousIPCountry in (bl_countries)
| summarize count() by DstUsername, SrcIpAddr
| extend IPCustomEntity = SrcIpAddr, AccountCustomEntity = DstUsername
entityMappings:
- entityType: Account
fieldMappings:
- identifier: Name
columnName: AccountCustomEntity
- entityType: IP
fieldMappings:
- identifier: Address
columnName: IPCustomEntity
version: 1.0.4
kind: Scheduled
Stages and Predicates
Parameters
let bl_countries = dynamic(['CH', 'RU']);
Stage 1: source
PaloAltoCDLEvent
Stage 2: where
| where EventResourceId =~ 'TRAFFIC'
Stage 3: where
| where MaliciousIPCountry in (bl_countries)
Stage 4: summarize
| summarize count() by DstUsername, SrcIpAddr
Stage 5: extend
| extend IPCustomEntity = SrcIpAddr, AccountCustomEntity = DstUsername
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
EventResourceId | eq |
| field:"EventResourceId" kind:eq value:"TRAFFIC" |
MaliciousIPCountry | in |
| field:"MaliciousIPCountry" kind:in |
Output Fields
These fields are emitted when the rule matches.
| Field | Source |
|---|---|
DstUsername | summarize |
SrcIpAddr | summarize |
AccountCustomEntity | extend |
IPCustomEntity | extend |
Pathlock TDnR - SAP Authorization Changes
#Detects changes to SAP authorization objects, forwarded by Pathlock Threat Detection and Response. Unauthorized authorization changes may be used to escalate privileges, bypass access controls, or create persistent privileged access in SAP systems.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Persistence | |
| Privilege Escalation |
Rule Body
id: 2a3b4c5d-6e7f-4a0b-8c1d-2e3f4a5b6c03
name: Pathlock TDnR - SAP Authorization Changes
kind: Scheduled
description: >-
Detects changes to SAP authorization objects, forwarded by Pathlock Threat Detection and Response.
Unauthorized authorization changes may be used to escalate privileges, bypass access controls,
or create persistent privileged access in SAP systems.
severity: High
status: Available
requiredDataConnectors:
- connectorId: Pathlock_TDnR
dataTypes:
- Pathlock_TDnR_CL
queryFrequency: 1h
queryPeriod: 1h
triggerOperator: gt
triggerThreshold: 0
tactics:
- PrivilegeEscalation
- Persistence
relevantTechniques:
- T1548
- T1098
query: |
Pathlock_TDnR_CL
| where DataSource == "AUTH_CHANGES"
| project TimeGenerated, Sysid, DataSource, Eventid, Instance, Hostname, Bname,
Tcode, Report, Area, Subid, SrcIp, DestIp, AffectedUser, LogLine,
MsgType, MsgId, MsgNo, MessageV1, MessageV2, MessageV3, MessageV4, CentralTs
entityMappings:
- entityType: Account
fieldMappings:
- identifier: Name
columnName: Bname
- entityType: Host
fieldMappings:
- identifier: HostName
columnName: Hostname
- entityType: IP
fieldMappings:
- identifier: Address
columnName: SrcIp
eventGroupingSettings:
aggregationKind: SingleAlert
incidentConfiguration:
createIncident: true
groupingConfiguration:
enabled: true
reopenClosedIncident: false
lookbackDuration: 5h
matchingMethod: AnyAlert
groupByEntities: []
groupByAlertDetails: []
groupByCustomDetails: []
suppressionDuration: 5h
suppressionEnabled: false
version: 1.0.0
Stages and Predicates
Stage 1: source
Pathlock_TDnR_CL
Stage 2: where
| where DataSource == "AUTH_CHANGES"
Stage 3: project
| project TimeGenerated, Sysid, DataSource, Eventid, Instance, Hostname, Bname,
Tcode, Report, Area, Subid, SrcIp, DestIp, AffectedUser, LogLine,
MsgType, MsgId, MsgNo, MessageV1, MessageV2, MessageV3, MessageV4, CentralTs
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
DataSource | eq |
| field:"DataSource" kind:eq value:"AUTH_CHANGES" |
Output Fields
These fields are emitted when the rule matches.
| Field | Source |
|---|---|
AffectedUser | project |
Area | project |
Bname | project |
CentralTs | project |
DataSource | project |
DestIp | project |
Eventid | project |
Hostname | project |
Instance | project |
LogLine | project |
MessageV1 | project |
MessageV2 | project |
MessageV3 | project |
MessageV4 | project |
MsgId | project |
MsgNo | project |
MsgType | project |
Report | project |
SrcIp | project |
Subid | project |
Sysid | project |
Tcode | project |
TimeGenerated | project |
Potential beaconing activity (ASIM Network Session schema)
#This rule identifies beaconing patterns from Network traffic logs based on recurrent frequency patterns. Such potential outbound beaconing patterns to untrusted public networks should be investigated for any malware callbacks or data exfiltration attempts as discussed in this Blog. This analytic rule uses ASIM and supports any built-in or custom source that supports the ASIM NetworkSession schema'
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Command & Control |
Telemetry Coverage
Rule Body
id: fcb9d75c-c3c1-4910-8697-f136bfef2363
name: Potential beaconing activity (ASIM Network Session schema)
description: |
This rule identifies beaconing patterns from Network traffic logs based on recurrent frequency patterns.
Such potential outbound beaconing patterns to untrusted public networks should be investigated for any malware callbacks or data exfiltration attempts as discussed in this [Blog](https://medium.com/@HuntOperator/detect-beaconing-with-flare-elastic-stack-and-intrusion-detection-systems-110dc74e0c56).
This analytic rule uses [ASIM](https://aka.ms/AboutASIM) and supports any built-in or custom source that supports the ASIM NetworkSession schema'
severity: Low
status: Available
requiredDataConnectors:
- connectorId: AWSS3
dataTypes:
- AWSVPCFlow
- connectorId: MicrosoftThreatProtection
dataTypes:
- DeviceNetworkEvents
- connectorId: SecurityEvents
dataTypes:
- SecurityEvent
- connectorId: WindowsSecurityEvents
dataTypes:
- SecurityEvent
- connectorId: WindowsForwardedEvents
dataTypes:
- WindowsEvent
- connectorId: Zscaler
dataTypes:
- CommonSecurityLog
- connectorId: MicrosoftSysmonForLinux
dataTypes:
- Syslog
- connectorId: PaloAltoNetworks
dataTypes:
- CommonSecurityLog
- connectorId: AzureMonitor(VMInsights)
dataTypes:
- VMConnection
- connectorId: AzureFirewall
dataTypes:
- AzureDiagnostics
- connectorId: AzureNSG
dataTypes:
- AzureDiagnostics
- connectorId: CiscoASA
dataTypes:
- CommonSecurityLog
- connectorId: CiscoAsaAma
dataTypes:
- CommonSecurityLog
- connectorId: Corelight
dataTypes:
- Corelight_CL
- connectorId: AIVectraStream
dataTypes:
- VectraStream
- connectorId: CheckPoint
dataTypes:
- CommonSecurityLog
- connectorId: Fortinet
dataTypes:
- CommonSecurityLog
- connectorId: CiscoMeraki
dataTypes:
- Syslog
- CiscoMerakiNativePoller
queryFrequency: 1d
queryPeriod: 2d
triggerOperator: gt
triggerThreshold: 0
tactics:
- CommandAndControl
relevantTechniques:
- T1071
- T1571
tags:
- ParentAlert: https://github.com/Azure/Azure-Sentinel/blob/master/Detections/CommonSecurityLog/PaloAlto-NetworkBeaconing.yaml
ParentVersion: 1.0.0
- Schema: ASIMNetworkSession
SchemaVersion: 0.2.4
query: |
let querystarttime = 2d;
let queryendtime = 1d;
let TimeDeltaThreshold = 10;
let TotalEventsThreshold = 15;
let PercentBeaconThreshold = 80;
let LocalNetworks=dynamic(["169.254.0.0/16","127.0.0.0/8"]);
_Im_NetworkSession(starttime=ago(querystarttime), endtime=ago(queryendtime))
| where not(ipv4_is_private(DstIpAddr))
| where not (ipv4_is_in_any_range(DstIpAddr, LocalNetworks))
| project
TimeGenerated
, SrcIpAddr
, SrcPortNumber
, DstIpAddr
, DstPortNumber
, DstBytes
, SrcBytes
| sort by
SrcIpAddr asc
, TimeGenerated asc
, DstIpAddr asc
, DstPortNumber asc
| serialize
| extend
nextTimeGenerated = next(TimeGenerated, 1)
, nextSrcIpAddr = next(SrcIpAddr, 1)
| extend
TimeDeltainSeconds = datetime_diff('second', nextTimeGenerated, TimeGenerated)
| where SrcIpAddr == nextSrcIpAddr
//Whitelisting criteria/ threshold criteria
| where TimeDeltainSeconds > TimeDeltaThreshold
| project
TimeGenerated
, TimeDeltainSeconds
, SrcIpAddr
, SrcPortNumber
, DstIpAddr
, DstPortNumber
, DstBytes
, SrcBytes
| summarize
count()
, sum(DstBytes)
, sum(SrcBytes)
, make_list(TimeDeltainSeconds)
by TimeDeltainSeconds
, bin(TimeGenerated, 1h)
, SrcIpAddr
, DstIpAddr
, DstPortNumber
| summarize
(MostFrequentTimeDeltaCount, MostFrequentTimeDeltainSeconds) = arg_max(count_, TimeDeltainSeconds)
, TotalEvents=sum(count_)
, TotalSrcBytes = sum(sum_SrcBytes)
, TotalDstBytes = sum(sum_DstBytes)
by bin(TimeGenerated, 1h)
, SrcIpAddr
, DstIpAddr
, DstPortNumber
| where TotalEvents > TotalEventsThreshold
| extend BeaconPercent = MostFrequentTimeDeltaCount/toreal(TotalEvents) * 100
| where BeaconPercent > PercentBeaconThreshold
entityMappings:
- entityType: IP
fieldMappings:
- identifier: Address
columnName: SrcIpAddr
- entityType: IP
fieldMappings:
- identifier: Address
columnName: DstIpAddr
alertDetailsOverride:
alertDisplayNameFormat: Potential beaconing from {{SrcIpAddr}} to {{DstIpAddr}}
alertDescriptionFormat: Potential beaconing pattern from a client at address {{SrcIpAddr}} to a server at address {{DstIpAddr}} over port {{DstPortNumber}} identified. Such potential outbound beaconing pattern to untrusted public networks should be investigated for any malware callbacks or data exfiltration attempts as discussed in this [Blog](http://www.austintaylor.io/detect/beaconing/intrusion/detection/system/command/control/flare/elastic/stack/2017/06/10/detect-beaconing-with-flare-elasticsearch-and-intrusion-detection-systems/). The recurring frequency, reported as FrequencyTime in the custom details, and the total transferred volume reported as TotalDstBytes in the custom details, can help to determine the significance of this incident.
customDetails:
DstPortNumber: DstPortNumber
FrequencyCount: TotalSrcBytes
FrequencyTime: MostFrequentTimeDeltaCount
TotalDstBytes: TotalDstBytes
version: 1.1.6
kind: Scheduled
Stages and Predicates
Parameters
let querystarttime = 2d;
let queryendtime = 1d;
let TimeDeltaThreshold = 10;
let TotalEventsThreshold = 15;
let PercentBeaconThreshold = 80;
let LocalNetworks = dynamic(["169.254.0.0/16","127.0.0.0/8"]);
Stage 1: source
_Im_NetworkSession(starttime=ago(querystarttime), endtime=ago(queryendtime))
Stage 2: where
| where not(ipv4_is_private(DstIpAddr))
Stage 3: where
| where not (ipv4_is_in_any_range(DstIpAddr, LocalNetworks))
Stage 4: project
| project
TimeGenerated
, SrcIpAddr
, SrcPortNumber
, DstIpAddr
, DstPortNumber
, DstBytes
, SrcBytes
Stage 5: sort
| sort by
SrcIpAddr asc
, TimeGenerated asc
, DstIpAddr asc
, DstPortNumber asc
Stage 6: kusto:serialize
| serialize
Stage 7: extend
| extend
nextTimeGenerated = next(TimeGenerated, 1)
, nextSrcIpAddr = next(SrcIpAddr, 1)
Stage 8: extend
| extend
TimeDeltainSeconds = datetime_diff('second', nextTimeGenerated, TimeGenerated)
Stage 9: where
| where SrcIpAddr == nextSrcIpAddr
Stage 10: where
| where TimeDeltainSeconds > TimeDeltaThreshold
Stage 11: project
| project
TimeGenerated
, TimeDeltainSeconds
, SrcIpAddr
, SrcPortNumber
, DstIpAddr
, DstPortNumber
, DstBytes
, SrcBytes
Stage 12: summarize
| summarize
count()
, sum(DstBytes)
, sum(SrcBytes)
, make_list(TimeDeltainSeconds)
by TimeDeltainSeconds
, bin(TimeGenerated, 1h)
, SrcIpAddr
, DstIpAddr
, DstPortNumber
Stage 13: summarize
| summarize
(MostFrequentTimeDeltaCount, MostFrequentTimeDeltainSeconds) = arg_max(count_, TimeDeltainSeconds)
, TotalEvents=sum(count_)
, TotalSrcBytes = sum(sum_SrcBytes)
, TotalDstBytes = sum(sum_DstBytes)
by bin(TimeGenerated, 1h)
, SrcIpAddr
, DstIpAddr
, DstPortNumber
Stage 14: where
| where TotalEvents > TotalEventsThreshold
Stage 15: extend
| extend BeaconPercent = MostFrequentTimeDeltaCount/toreal(TotalEvents) * 100
Stage 16: where
| where BeaconPercent > PercentBeaconThreshold
Indicators
These rows show field, operator, and value matches.
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
DstIpAddr | cidr_match | 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 169.254.0.0/16, 127.0.0.0/8 | excludes:DstIpAddr |
DstIpAddr | cidr_match | 169.254.0.0/16, 127.0.0.0/8 | excludes:DstIpAddr field:"DstIpAddr" value:"169.254.0.0/16" field:"DstIpAddr" value:"127.0.0.0/8" |
Output Fields
These fields are emitted when the rule matches.
| Field | Source |
|---|---|
DstIpAddr | summarize |
DstPortNumber | summarize |
MostFrequentTimeDeltaCount | summarize |
MostFrequentTimeDeltainSeconds | summarize |
SrcIpAddr | summarize |
TotalDstBytes | summarize |
TotalEvents | summarize |
TotalSrcBytes | summarize |
BeaconPercent | extend |
Registries Alerts for Prancer
#'High severity registry alerts found by Prancer.'
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Reconnaissance |
Rule Body
id: 08706063-c15e-4d96-beae-9e8d92ccefbb
name: Registries Alerts for Prancer
description: |
'High severity registry alerts found by Prancer.'
severity: High
requiredDataConnectors:
- connectorId: PrancerLogData
dataTypes:
- prancer_CL
queryFrequency: 5h
queryPeriod: 5h
triggerOperator: gt
triggerThreshold: 0
eventGroupingSettings:
aggregationKind: SingleAlert
status: Available
tactics:
- Reconnaissance
relevantTechniques:
- T1595
query: |
union prancer_CL
| where deviceProduct_s == 'azure'
| where parse_json(data_data_snapshots_s)[0].type == 'Microsoft.ContainerRegistry/registries'
| where data_data_severity_s == 'High' and data_data_result_s == 'failed'
| extend snapshot = parse_json(data_data_snapshots_s)
| mv-expand snapshot
| extend
id = tostring(snapshot.id),
structure = tostring(snapshot.structure),
reference = tostring(snapshot.reference),
source = tostring(snapshot.source),
collection = tostring(snapshot.collection),
type = tostring(snapshot.type),
region = tostring(snapshot.region),
resourceTypes = tostring(snapshot.resourceTypes),
path = tostring(snapshot.path)
customDetails:
entityMappings:
- entityType: AzureResource
fieldMappings:
- identifier: ResourceId
columnName: path
alertDetailsOverride:
alertDisplayNameFormat: "{{data_data_message_s}}"
alertDescriptionFormat: "{{data_data_description_s}}"
alertSeverityColumnName: "{{data_data_severity_s}}"
alertDynamicProperties:
- alertProperty: RemediationSteps
value: data_data_remediation_description_s
version: 1.0.2
kind: Scheduled
Stages and Predicates
Stage 1: union
union of 1 branches
Stage 2: source
prancer_CL
Stage 3: where
where deviceProduct_s == "azure"
Stage 4: where
where parse_json(data_data_snapshots_s)[0].type == "Microsoft.ContainerRegistry/registries"
Stage 5: where
where data_data_result_s == "failed" and data_data_severity_s == "High"
Stage 6: extend
extend snapshot
Stage 7: mv-expand
mv-expand snapshot
Stage 8: extend
extend collection, id, path, reference, region, resourceTypes, source, structure, type
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
data_data_result_s | eq |
| field:"data_data_result_s" kind:eq value:"failed" |
data_data_severity_s | eq |
| field:"data_data_severity_s" kind:eq value:"High" |
data_data_snapshots_s[0].type | eq |
| field:"data_data_snapshots_s[0].type" kind:eq value:"Microsoft.ContainerRegistry/registries" |
deviceProduct_s | eq |
| field:"deviceProduct_s" kind:eq value:"azure" |
Output Fields
These fields are emitted when the rule matches.
| Field | Source |
|---|---|
snapshot | extend |
collection | extend |
id | extend |
path | extend |
reference | extend |
region | extend |
resourceTypes | extend |
source | extend |
structure | extend |
type | extend |
Sentinel One - Multiple alerts on host
#'Detects when multiple alerts received from same host.'
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Initial Access |
Rule Body
id: 47e427e6-61bc-4e24-8d16-a12871b9f939
name: Sentinel One - Multiple alerts on host
description: |
'Detects when multiple alerts received from same host.'
severity: High
status: Available
requiredDataConnectors:
- connectorId: SentinelOne
dataTypes:
- SentinelOne
queryFrequency: 1h
queryPeriod: 1h
triggerOperator: gt
triggerThreshold: 0
tactics:
- InitialAccess
relevantTechniques:
- T1190
query: |
SentinelOne
| where ActivityType == 3608
| extend RuleName = extract(@'Custom Rule:\s(.*?)\sin Group', 1, EventOriginalMessage)
| extend DstHostname = extract(@'detected on\s(\S+)\.', 1, EventOriginalMessage)
| summarize count() by DstHostname, bin(TimeGenerated, 15m)
| where count_ > 1
| extend HostCustomEntity = DstHostname
entityMappings:
- entityType: Host
fieldMappings:
- identifier: HostName
columnName: HostCustomEntity
version: 1.0.2
kind: Scheduled
Stages and Predicates
Stage 1: source
SentinelOne
Stage 2: where
| where ActivityType == 3608
Stage 3: extend
| extend RuleName = extract(@'Custom Rule:\s(.*?)\sin Group', 1, EventOriginalMessage)
Stage 4: extend
| extend DstHostname = extract(@'detected on\s(\S+)\.', 1, EventOriginalMessage)
Stage 5: summarize
| summarize count() by DstHostname, bin(TimeGenerated, 15m)
Stage 6: where
| where count_ > 1
Stage 7: extend
| extend HostCustomEntity = DstHostname
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
ActivityType | eq |
| field:"ActivityType" kind:eq value:"3608" |
count_ | gt |
| field:"count_" kind:gt value:"1" |
Output Fields
These fields are emitted when the rule matches.
| Field | Source |
|---|---|
DstHostname | summarize |
HostCustomEntity | extend |
Sentinel One - User viewed agent's passphrase
#'Detects when a user viewed agent's passphrase.'
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Credential Access |
Rule Body
id: 51999097-60f4-42c0-bee8-fa28160e5583
name: Sentinel One - User viewed agent's passphrase
description: |
'Detects when a user viewed agent's passphrase.'
severity: Medium
status: Available
requiredDataConnectors:
- connectorId: SentinelOne
dataTypes:
- SentinelOne
queryFrequency: 1h
queryPeriod: 1h
triggerOperator: gt
triggerThreshold: 0
tactics:
- CredentialAccess
relevantTechniques:
- T1555
query: |
SentinelOne
| where ActivityType == 64
| extend AccountCustomEntity = SrcUserName, HostCustomEntity = DataComputerName
entityMappings:
- entityType: Account
fieldMappings:
- identifier: Name
columnName: AccountCustomEntity
- entityType: Host
fieldMappings:
- identifier: HostName
columnName: HostCustomEntity
version: 1.0.0
kind: Scheduled
Stages and Predicates
Stage 1: source
SentinelOne
Stage 2: where
| where ActivityType == 64
Stage 3: extend
| extend AccountCustomEntity = SrcUserName, HostCustomEntity = DataComputerName
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
ActivityType | eq |
| field:"ActivityType" kind:eq value:"64" |
Output Fields
These fields are emitted when the rule matches.
| Field | Source |
|---|---|
AccountCustomEntity | extend |
HostCustomEntity | extend |
SOCRadar Unsynced Closed Incident
#'Detects Microsoft Sentinel incidents tagged as SOCRadar that were closed more than 30 minutes ago but do not have the Synced tag. This may indicate the SOCRadar-Alarm-Sync playbook has failed to update the SOCRadar platform with the closure status.'
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Discovery |
Rule Body
id: 6e2f8d4b-5a71-4c9e-b3f6-8a1c9d4e7b2a
name: SOCRadar Unsynced Closed Incident
description: |
'Detects Microsoft Sentinel incidents tagged as SOCRadar that were closed more than 30 minutes ago but do not have the Synced tag. This may indicate the SOCRadar-Alarm-Sync playbook has failed to update the SOCRadar platform with the closure status.'
severity: Low
status: Available
requiredDataConnectors: []
queryFrequency: 1h
queryPeriod: 1d
triggerOperator: gt
triggerThreshold: 0
tactics:
- Discovery
relevantTechniques:
- T1526
query: |
SecurityIncident
| where Labels has "SOCRadar"
| where Status == "Closed"
| where LastModifiedTime < ago(30m)
| where not(Labels has "Synced")
| extend AlarmId = extract(@"#(\d+)", 1, Title)
| extend AccountName = AlarmId
| project TimeGenerated, IncidentName, Title, Status, Classification, LastModifiedTime, AlarmId, AccountName
entityMappings:
- entityType: Account
fieldMappings:
- identifier: Name
columnName: AccountName
version: 1.0.0
kind: Scheduled
Stages and Predicates
Stage 1: source
SecurityIncident
Stage 2: where
| where Labels has "SOCRadar"
Stage 3: where
| where Status == "Closed"
Stage 4: where
| where LastModifiedTime < ago(30m)
Stage 5: where
| where not(Labels has "Synced")
Stage 6: extend
| extend AlarmId = extract(@"#(\d+)", 1, Title)
Stage 7: extend
| extend AccountName = AlarmId
Stage 8: project
| project TimeGenerated, IncidentName, Title, Status, Classification, LastModifiedTime, AlarmId, AccountName
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
Labels | match |
| field:"Labels" kind:match value:"SOCRadar" |
Status | eq |
| field:"Status" kind:eq value:"Closed" |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
Labels | match | Synced | excludes:Labels field:"Labels" value:"Synced" |
Output Fields
These fields are emitted when the rule matches.
| Field | Source |
|---|---|
AccountName | project |
AlarmId | project |
Classification | project |
IncidentName | project |
LastModifiedTime | project |
Status | project |
TimeGenerated | project |
Title | project |
SpyCloud plaintext credential exposure detected
#'Identifies user accounts exposed with a plaintext password in a third-party data breach. Unremediated exposures of this kind can lead directly to account takeover.'
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Credential Access |
Rule Body
id: a25eba0e-ff42-4c97-a379-d76bdb2aa1e3
name: SpyCloud plaintext credential exposure detected
description: |
'Identifies user accounts exposed with a plaintext password in a third-party data breach.
Unremediated exposures of this kind can lead directly to account takeover.'
severity: High
requiredDataConnectors:
- connectorId: SpyCloudEnterpriseProtectionCCF
dataTypes:
- SpyCloudBreachWatchlistV2_CL
queryFrequency: 1h
queryPeriod: 2d
triggerOperator: gt
triggerThreshold: 0
tactics:
- CredentialAccess
relevantTechniques:
- T1555
query: |
// Human-readable constant for the severity threshold used below
let severityThreshold = 20;
SpyCloudBreachWatchlistV2_CL
| where Severity == severityThreshold
| mv-expand IPAddress = IPAddresses to typeof(string)
| extend AccountName = Username, AccountEmail = Email
| project TimeGenerated, DocumentId, SourceId, SpyCloudPublishDate, AccountEmail,
TargetDomain, PasswordPlaintext, AccountName, IPAddress
eventGroupingSettings:
aggregationKind: SingleAlert
entityMappings:
- entityType: Account
fieldMappings:
- identifier: Name
columnName: AccountName
- entityType: IP
fieldMappings:
- identifier: Address
columnName: IPAddress
- entityType: Mailbox
fieldMappings:
- identifier: MailboxPrimaryAddress
columnName: AccountEmail
version: 1.0.0
kind: scheduled
Stages and Predicates
Parameters
let severityThreshold = 20;
Stage 1: source
SpyCloudBreachWatchlistV2_CL
Stage 2: where
| where Severity == severityThreshold
Stage 3: mv-expand
| mv-expand IPAddress = IPAddresses to typeof(string)
Stage 4: extend
| extend AccountName = Username, AccountEmail = Email
Stage 5: project
| project TimeGenerated, DocumentId, SourceId, SpyCloudPublishDate, AccountEmail,
TargetDomain, PasswordPlaintext, AccountName, IPAddress
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
Severity | eq |
| field:"Severity" kind:eq value:"20" |
Output Fields
These fields are emitted when the rule matches.
| Field | Source |
|---|---|
AccountEmail | project |
AccountName | project |
DocumentId | project |
IPAddress | project |
PasswordPlaintext | project |
SourceId | project |
SpyCloudPublishDate | project |
TargetDomain | project |
TimeGenerated | project |
Trend Micro CAS - Infected user
#'Detects when malware was detected for user account.'
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Initial Access |
Rule Body
id: 3649dfb8-a5ca-47dd-8965-cd2f633ca533
name: Trend Micro CAS - Infected user
description: |
'Detects when malware was detected for user account.'
severity: High
status: Available
requiredDataConnectors:
- connectorId: TrendMicroCAS
dataTypes:
- TrendMicroCAS
queryFrequency: 10m
queryPeriod: 10m
triggerOperator: gt
triggerThreshold: 0
tactics:
- InitialAccess
relevantTechniques:
- T1566
query: |
TrendMicroCAS
| where EventType has_all ('virtual', 'analyzer')
| where isnotempty(VirusName)
| extend AccountCustomEntity = DstUserName, MalwareCustomEntity = VirusName
entityMappings:
- entityType: Account
fieldMappings:
- identifier: Name
columnName: AccountCustomEntity
- entityType: Malware
fieldMappings:
- identifier: Name
columnName: MalwareCustomEntity
version: 1.0.1
kind: Scheduled
Stages and Predicates
Stage 1: source
TrendMicroCAS
Stage 2: where
| where EventType has_all ('virtual', 'analyzer')
Stage 3: where
| where isnotempty(VirusName)
Stage 4: extend
| extend AccountCustomEntity = DstUserName, MalwareCustomEntity = VirusName
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
EventType | match |
| field:"EventType" kind:match |
VirusName | is_not_null | field:"VirusName" kind:is_not_null |
Output Fields
These fields are emitted when the rule matches.
| Field | Source |
|---|---|
AccountCustomEntity | extend |
MalwareCustomEntity | extend |
Trend Micro CAS - Suspicious filename
#'Detects unexpected filename.'
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Initial Access |
Rule Body
id: 52c4640a-1e2b-4155-b69e-e1869c9a57c9
name: Trend Micro CAS - Suspicious filename
description: |
'Detects unexpected filename.'
severity: Medium
status: Available
requiredDataConnectors:
- connectorId: TrendMicroCAS
dataTypes:
- TrendMicroCAS
queryFrequency: 1h
queryPeriod: 1h
triggerOperator: gt
triggerThreshold: 0
tactics:
- InitialAccess
relevantTechniques:
- T1566
query: |
TrendMicroCAS
| where isnotempty(SrcFileName)
| where SrcFileName matches regex @'\A[a-zA-Z0-9_\-.]{1,3}\.\w+$'
| extend AccountCustomEntity = DstUserName
entityMappings:
- entityType: Account
fieldMappings:
- identifier: Name
columnName: AccountCustomEntity
version: 1.0.0
kind: Scheduled
Stages and Predicates
Stage 1: source
TrendMicroCAS
Stage 2: where
| where isnotempty(SrcFileName)
Stage 3: where
| where SrcFileName matches regex @'\A[a-zA-Z0-9_\-.]{1,3}\.\w+$'
Stage 4: extend
| extend AccountCustomEntity = DstUserName
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
SrcFileName | is_not_null | field:"SrcFileName" kind:is_not_null | |
SrcFileName | regex_match |
| field:"SrcFileName" kind:regex_match value:"\A[a-zA-Z0-9_\-.]{1,3}.\w+$" |
Output Fields
These fields are emitted when the rule matches.
| Field | Source |
|---|---|
AccountCustomEntity | extend |