Analytic rule catalog
RedRays - Password Security
Back
| Id | ebd95a4d-cc56-5f01-a1de-36aa67e66794 |
| Rulename | RedRays - Password Security |
| Description | Identifies new or materially changed, actionable password security findings from RedRays. Only High or Critical findings are selected. Initial findings raise alerts only if you enable baseline alerting in RedRays. The ATT&CK mapping describes password recovery during an authorized assessment, not evidence of an adversary attack. Records outside the one-day query window do not trigger this rule. |
| Severity | High |
| Tactics | CredentialAccess |
| Techniques | T1110 |
| Required data connectors | RedRaysSAPSecurityFindings |
| Kind | Scheduled |
| Query frequency | 15m |
| Query period | 1d |
| Trigger threshold | 0 |
| Trigger operator | gt |
| Source Uri | https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/RedRays%20SAP%20Security%20Findings/Analytic%20Rules/RedRaysRecoveredPasswords.yaml |
| Version | 1.0.3 |
| Arm template | ebd95a4d-cc56-5f01-a1de-36aa67e66794.json |
// Map each ProductInstanceId to its RedRays origin to resolve relative source links.
// Example: dynamic({"<ProductInstanceId>": "https://redrays.example"})
let redRaysPortalUrls = dynamic({});
let observations = RedRaysPasswordFindings_CL
| where TimeGenerated >= ago(1d)
| extend ArrivedAt = ingestion_time()
| summarize arg_min(ArrivedAt, *) by EventId;
let candidates = observations
| where IsAlertCandidate == true and ArrivedAt > ago(15m)
| project FindingKey, AlertFingerprint, AlertEventId = EventId, AlertArrivedAt = ArrivedAt
| summarize arg_min(AlertArrivedAt, *) by FindingKey, AlertFingerprint;
observations
| summarize arg_max(Revision, *) by FindingKey
| where IsActionable == true
| where SourceSeverity in ("HIGH", "CRITICAL")
| join kind=inner candidates on FindingKey, AlertFingerprint
| extend EventId = AlertEventId
| extend EntityHost = trim_end(@"\.", trim(@"\s+", tostring(Host)))
| extend EntityIP = iff(EntityHost !contains "/" and isnotempty(parse_ipv6(EntityHost)), EntityHost, "")
| extend EntityHost = iff(isempty(EntityIP) and strlen(EntityHost) <= 253
and EntityHost matches regex @"(?i)^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?(?:\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)*$"
and not(EntityHost matches regex @"^[0-9.]+$"), tolower(EntityHost), "")
| extend _portalOrigin = tostring(redRaysPortalUrls[tostring(ProductInstanceId)]), _sourceLink = tostring(SourceUrl)
| extend _entityUrlCandidate = case(
_sourceLink startswith "/app/" and _portalOrigin matches regex @"(?i)^https?://[^/?#@\s\\]+/?$",
strcat(trim_end(@"/+", _portalOrigin), _sourceLink),
_sourceLink)
| extend _parsedEntityUrl = parse_url(_entityUrlCandidate)
| extend EntityUrl = iff(tostring(_parsedEntityUrl.Scheme) in~ ("https", "http")
and isnotempty(tostring(_parsedEntityUrl.Host))
and isempty(tostring(_parsedEntityUrl.Username)) and isempty(tostring(_parsedEntityUrl.Password))
and not(_entityUrlCandidate matches regex @"[\s\\]"), _entityUrlCandidate, "")
| project-away _portalOrigin, _sourceLink, _entityUrlCandidate, _parsedEntityUrl
queryFrequency: 15m
entityMappings:
- fieldMappings:
- columnName: EntityHost
identifier: FullName
entityType: Host
- fieldMappings:
- columnName: EntityIP
identifier: Address
entityType: IP
- fieldMappings:
- columnName: EntityUrl
identifier: Url
entityType: URL
incidentConfiguration:
createIncident: true
groupingConfiguration:
reopenClosedIncident: false
matchingMethod: Selected
lookbackDuration: PT24H
enabled: true
groupByCustomDetails:
- FindingKey
triggerThreshold: 0
triggerOperator: gt
severity: High
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/RedRays%20SAP%20Security%20Findings/Analytic%20Rules/RedRaysRecoveredPasswords.yaml
eventGroupingSettings:
aggregationKind: AlertPerResult
alertDetailsOverride:
alertDisplayNameFormat: 'RedRays: {{Title}}'
query: |-
// Map each ProductInstanceId to its RedRays origin to resolve relative source links.
// Example: dynamic({"<ProductInstanceId>": "https://redrays.example"})
let redRaysPortalUrls = dynamic({});
let observations = RedRaysPasswordFindings_CL
| where TimeGenerated >= ago(1d)
| extend ArrivedAt = ingestion_time()
| summarize arg_min(ArrivedAt, *) by EventId;
let candidates = observations
| where IsAlertCandidate == true and ArrivedAt > ago(15m)
| project FindingKey, AlertFingerprint, AlertEventId = EventId, AlertArrivedAt = ArrivedAt
| summarize arg_min(AlertArrivedAt, *) by FindingKey, AlertFingerprint;
observations
| summarize arg_max(Revision, *) by FindingKey
| where IsActionable == true
| where SourceSeverity in ("HIGH", "CRITICAL")
| join kind=inner candidates on FindingKey, AlertFingerprint
| extend EventId = AlertEventId
| extend EntityHost = trim_end(@"\.", trim(@"\s+", tostring(Host)))
| extend EntityIP = iff(EntityHost !contains "/" and isnotempty(parse_ipv6(EntityHost)), EntityHost, "")
| extend EntityHost = iff(isempty(EntityIP) and strlen(EntityHost) <= 253
and EntityHost matches regex @"(?i)^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?(?:\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)*$"
and not(EntityHost matches regex @"^[0-9.]+$"), tolower(EntityHost), "")
| extend _portalOrigin = tostring(redRaysPortalUrls[tostring(ProductInstanceId)]), _sourceLink = tostring(SourceUrl)
| extend _entityUrlCandidate = case(
_sourceLink startswith "/app/" and _portalOrigin matches regex @"(?i)^https?://[^/?#@\s\\]+/?$",
strcat(trim_end(@"/+", _portalOrigin), _sourceLink),
_sourceLink)
| extend _parsedEntityUrl = parse_url(_entityUrlCandidate)
| extend EntityUrl = iff(tostring(_parsedEntityUrl.Scheme) in~ ("https", "http")
and isnotempty(tostring(_parsedEntityUrl.Host))
and isempty(tostring(_parsedEntityUrl.Username)) and isempty(tostring(_parsedEntityUrl.Password))
and not(_entityUrlCandidate matches regex @"[\s\\]"), _entityUrlCandidate, "")
| project-away _portalOrigin, _sourceLink, _entityUrlCandidate, _parsedEntityUrl
tactics:
- CredentialAccess
queryPeriod: 1d
customDetails:
SourceStatus: SourceStatus
ProductInstanceId: ProductInstanceId
FindingKey: FindingKey
SourceUrl: SourceUrl
EventId: EventId
SourceSeverity: SourceSeverity
AccountName: AccountName
SapClient: SapClient
Module: Module
SystemId: SystemId
relevantTechniques:
- T1110
requiredDataConnectors:
- connectorId: RedRaysSAPSecurityFindings
dataTypes:
- RedRaysPasswordFindings_CL
id: ebd95a4d-cc56-5f01-a1de-36aa67e66794
version: 1.0.3
description: Identifies new or materially changed, actionable password security findings from RedRays. Only High or Critical findings are selected. Initial findings raise alerts only if you enable baseline alerting in RedRays. The ATT&CK mapping describes password recovery during an authorized assessment, not evidence of an adversary attack. Records outside the one-day query window do not trigger this rule.
kind: Scheduled
name: RedRays - Password Security
status: InPreview
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"workspace": {
"type": "String"
}
},
"resources": [
{
"apiVersion": "2024-01-01-preview",
"id": "[concat(resourceId('Microsoft.OperationalInsights/workspaces/providers', parameters('workspace'), 'Microsoft.SecurityInsights'),'/alertRules/ebd95a4d-cc56-5f01-a1de-36aa67e66794')]",
"kind": "Scheduled",
"name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/ebd95a4d-cc56-5f01-a1de-36aa67e66794')]",
"properties": {
"alertDetailsOverride": {
"alertDisplayNameFormat": "RedRays: {{Title}}"
},
"alertRuleTemplateName": "ebd95a4d-cc56-5f01-a1de-36aa67e66794",
"customDetails": {
"AccountName": "AccountName",
"EventId": "EventId",
"FindingKey": "FindingKey",
"Module": "Module",
"ProductInstanceId": "ProductInstanceId",
"SapClient": "SapClient",
"SourceSeverity": "SourceSeverity",
"SourceStatus": "SourceStatus",
"SourceUrl": "SourceUrl",
"SystemId": "SystemId"
},
"description": "Identifies new or materially changed, actionable password security findings from RedRays. Only High or Critical findings are selected. Initial findings raise alerts only if you enable baseline alerting in RedRays. The ATT&CK mapping describes password recovery during an authorized assessment, not evidence of an adversary attack. Records outside the one-day query window do not trigger this rule.",
"displayName": "RedRays - Password Security",
"enabled": true,
"entityMappings": [
{
"entityType": "Host",
"fieldMappings": [
{
"columnName": "EntityHost",
"identifier": "FullName"
}
]
},
{
"entityType": "IP",
"fieldMappings": [
{
"columnName": "EntityIP",
"identifier": "Address"
}
]
},
{
"entityType": "URL",
"fieldMappings": [
{
"columnName": "EntityUrl",
"identifier": "Url"
}
]
}
],
"eventGroupingSettings": {
"aggregationKind": "AlertPerResult"
},
"incidentConfiguration": {
"createIncident": true,
"groupingConfiguration": {
"enabled": true,
"groupByCustomDetails": [
"FindingKey"
],
"lookbackDuration": "PT24H",
"matchingMethod": "Selected",
"reopenClosedIncident": false
}
},
"OriginalUri": "https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/RedRays%20SAP%20Security%20Findings/Analytic%20Rules/RedRaysRecoveredPasswords.yaml",
"query": "// Map each ProductInstanceId to its RedRays origin to resolve relative source links.\n// Example: dynamic({\"<ProductInstanceId>\": \"https://redrays.example\"})\nlet redRaysPortalUrls = dynamic({});\nlet observations = RedRaysPasswordFindings_CL\n| where TimeGenerated >= ago(1d)\n| extend ArrivedAt = ingestion_time()\n| summarize arg_min(ArrivedAt, *) by EventId;\nlet candidates = observations\n| where IsAlertCandidate == true and ArrivedAt > ago(15m)\n| project FindingKey, AlertFingerprint, AlertEventId = EventId, AlertArrivedAt = ArrivedAt\n| summarize arg_min(AlertArrivedAt, *) by FindingKey, AlertFingerprint;\nobservations\n| summarize arg_max(Revision, *) by FindingKey\n| where IsActionable == true\n| where SourceSeverity in (\"HIGH\", \"CRITICAL\")\n| join kind=inner candidates on FindingKey, AlertFingerprint\n| extend EventId = AlertEventId\n| extend EntityHost = trim_end(@\"\\.\", trim(@\"\\s+\", tostring(Host)))\n| extend EntityIP = iff(EntityHost !contains \"/\" and isnotempty(parse_ipv6(EntityHost)), EntityHost, \"\")\n| extend EntityHost = iff(isempty(EntityIP) and strlen(EntityHost) <= 253\n and EntityHost matches regex @\"(?i)^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?(?:\\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)*$\"\n and not(EntityHost matches regex @\"^[0-9.]+$\"), tolower(EntityHost), \"\")\n| extend _portalOrigin = tostring(redRaysPortalUrls[tostring(ProductInstanceId)]), _sourceLink = tostring(SourceUrl)\n| extend _entityUrlCandidate = case(\n _sourceLink startswith \"/app/\" and _portalOrigin matches regex @\"(?i)^https?://[^/?#@\\s\\\\]+/?$\",\n strcat(trim_end(@\"/+\", _portalOrigin), _sourceLink),\n _sourceLink)\n| extend _parsedEntityUrl = parse_url(_entityUrlCandidate)\n| extend EntityUrl = iff(tostring(_parsedEntityUrl.Scheme) in~ (\"https\", \"http\")\n and isnotempty(tostring(_parsedEntityUrl.Host))\n and isempty(tostring(_parsedEntityUrl.Username)) and isempty(tostring(_parsedEntityUrl.Password))\n and not(_entityUrlCandidate matches regex @\"[\\s\\\\]\"), _entityUrlCandidate, \"\")\n| project-away _portalOrigin, _sourceLink, _entityUrlCandidate, _parsedEntityUrl",
"queryFrequency": "PT15M",
"queryPeriod": "P1D",
"severity": "High",
"status": "InPreview",
"subTechniques": [],
"suppressionDuration": "PT1H",
"suppressionEnabled": false,
"tactics": [
"CredentialAccess"
],
"techniques": [
"T1110"
],
"templateVersion": "1.0.3",
"triggerOperator": "GreaterThan",
"triggerThreshold": 0
},
"type": "Microsoft.OperationalInsights/workspaces/providers/alertRules"
}
]
}