Back
Id6db6a8e6-2959-440b-ba57-a505875fcb37
RulenameRecordedFuture Threat Hunting Hash All Actors
DescriptionRecorded Future Threat Hunting hash correlation for all actors.
SeverityMedium
TacticsInitialAccess
Execution
Persistence
TechniquesT1189
T1059
T1554
Required data connectorsThreatIntelligenceUploadIndicatorsAPI
KindScheduled
Query frequency15m
Query period1d
Trigger threshold0
Trigger operatorgt
Source Urihttps://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Recorded%20Future/Analytic%20Rules/ThreatHunting/RecordedFutureThreatHuntingHashAllActors.yaml
Version1.1.1
Arm template6db6a8e6-2959-440b-ba57-a505875fcb37.json
Deploy To Azure
let ioc_lookBack = 1d;
// The source table (imFileEvent) is a ASIM parser table, but can be replaced by any infrastructure table containing Hash data.
// The following workbook: Recorded Future - Hash Correlation will help researching available data and selecting tables and columns
imFileEvent
| where isnotempty(Hash)
| extend lowerHash=tolower(Hash)
| join kind=inner (
ThreatIntelIndicators
// Only look for IOCs
| where ObservableKey contains'file:hashes'
| where isnotempty(ObservableValue)
// Only look at Recorded Future Threat Hunt Indicators.
| where Data.description startswith "Recorded Future - Threat Hunt"
// Only work with the latest indicators
| where TimeGenerated >= ago(ioc_lookBack)
| summarize LatestIndicatorTime = arg_max(TimeGenerated, *) by Id
| where IsActive == true and ValidUntil > now()
| extend lowerHash=tolower(ObservableValue)
) on lowerHash
// select column from the source table to match with Recorded Future ThreatIntelIndicator $left.Hash
| mv-expand Label=Data.labels
| extend RecordedFuturePortalLink = parse_json(tostring(Label)).RecordedFuturePortalLink
// Hash and HashType is defaulted to data from Recorded Future, it can be changed to data from the infrastructure table.
| project Hash=ObservableValue, HashType=extract("file:hashes.('[^']*')", 1, ObservableKey), Description=Data.description, Type, TimeGenerated, RecordedFuturePortalLink
incidentConfiguration:
  groupingConfiguration:
    lookbackDuration: 1h
    reopenClosedIncident: false
    matchingMethod: AllEntities
    enabled: true
  createIncident: true
name: RecordedFuture Threat Hunting Hash All Actors
triggerOperator: gt
query: |
  let ioc_lookBack = 1d;
  // The source table (imFileEvent) is a ASIM parser table, but can be replaced by any infrastructure table containing Hash data.
  // The following workbook: Recorded Future - Hash Correlation will help researching available data and selecting tables and columns
  imFileEvent
  | where isnotempty(Hash)
  | extend lowerHash=tolower(Hash)
  | join kind=inner (
  ThreatIntelIndicators
  // Only look for IOCs
  | where ObservableKey contains'file:hashes'
  | where isnotempty(ObservableValue)
  // Only look at Recorded Future Threat Hunt Indicators.
  | where Data.description startswith "Recorded Future - Threat Hunt"
  // Only work with the latest indicators
  | where TimeGenerated >= ago(ioc_lookBack)
  | summarize LatestIndicatorTime = arg_max(TimeGenerated, *) by Id
  | where IsActive == true and ValidUntil > now()
  | extend lowerHash=tolower(ObservableValue)
  ) on lowerHash
  // select column from the source table to match with Recorded Future ThreatIntelIndicator $left.Hash
  | mv-expand Label=Data.labels
  | extend RecordedFuturePortalLink = parse_json(tostring(Label)).RecordedFuturePortalLink
  // Hash and HashType is defaulted to data from Recorded Future, it can be changed to data from the infrastructure table.
  | project Hash=ObservableValue, HashType=extract("file:hashes.('[^']*')", 1, ObservableKey), Description=Data.description, Type, TimeGenerated, RecordedFuturePortalLink
queryFrequency: 15m
description: |
  'Recorded Future Threat Hunting hash correlation for all actors.'
id: 6db6a8e6-2959-440b-ba57-a505875fcb37
triggerThreshold: 0
queryPeriod: 1d
version: 1.1.1
kind: Scheduled
customDetails:
  ActorInformation: RecordedFuturePortalLink
relevantTechniques:
- T1189
- T1059
- T1554
eventGroupingSettings:
  aggregationKind: AlertPerResult
severity: Medium
requiredDataConnectors:
- connectorId: ThreatIntelligenceUploadIndicatorsAPI
  dataTypes:
  - ThreatIntelIndicators
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Recorded%20Future/Analytic%20Rules/ThreatHunting/RecordedFutureThreatHuntingHashAllActors.yaml
alertDetailsOverride:
  alertDescriptionFormat: '**{{Description}}**\n\nCorrelation found on {{Hash}} from the {{Type}} table.\n'
  alertDisplayNameFormat: '{{Description}}'
  alertDynamicProperties:
  - value: RecordedFuturePortalLink
    alertProperty: AlertLink
tactics:
- InitialAccess
- Execution
- Persistence
entityMappings:
- fieldMappings:
  - identifier: Value
    columnName: Hash
  - identifier: Algorithm
    columnName: HashType
  entityType: FileHash
{
  "$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/6db6a8e6-2959-440b-ba57-a505875fcb37')]",
      "kind": "Scheduled",
      "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/6db6a8e6-2959-440b-ba57-a505875fcb37')]",
      "properties": {
        "alertDetailsOverride": {
          "alertDescriptionFormat": "**{{Description}}**\\n\\nCorrelation found on {{Hash}} from the {{Type}} table.\\n",
          "alertDisplayNameFormat": "{{Description}}",
          "alertDynamicProperties": [
            {
              "alertProperty": "AlertLink",
              "value": "RecordedFuturePortalLink"
            }
          ]
        },
        "alertRuleTemplateName": "6db6a8e6-2959-440b-ba57-a505875fcb37",
        "customDetails": {
          "ActorInformation": "RecordedFuturePortalLink"
        },
        "description": "'Recorded Future Threat Hunting hash correlation for all actors.'\n",
        "displayName": "RecordedFuture Threat Hunting Hash All Actors",
        "enabled": true,
        "entityMappings": [
          {
            "entityType": "FileHash",
            "fieldMappings": [
              {
                "columnName": "Hash",
                "identifier": "Value"
              },
              {
                "columnName": "HashType",
                "identifier": "Algorithm"
              }
            ]
          }
        ],
        "eventGroupingSettings": {
          "aggregationKind": "AlertPerResult"
        },
        "incidentConfiguration": {
          "createIncident": true,
          "groupingConfiguration": {
            "enabled": true,
            "lookbackDuration": "PT1H",
            "matchingMethod": "AllEntities",
            "reopenClosedIncident": false
          }
        },
        "OriginalUri": "https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Recorded%20Future/Analytic%20Rules/ThreatHunting/RecordedFutureThreatHuntingHashAllActors.yaml",
        "query": "let ioc_lookBack = 1d;\n// The source table (imFileEvent) is a ASIM parser table, but can be replaced by any infrastructure table containing Hash data.\n// The following workbook: Recorded Future - Hash Correlation will help researching available data and selecting tables and columns\nimFileEvent\n| where isnotempty(Hash)\n| extend lowerHash=tolower(Hash)\n| join kind=inner (\nThreatIntelIndicators\n// Only look for IOCs\n| where ObservableKey contains'file:hashes'\n| where isnotempty(ObservableValue)\n// Only look at Recorded Future Threat Hunt Indicators.\n| where Data.description startswith \"Recorded Future - Threat Hunt\"\n// Only work with the latest indicators\n| where TimeGenerated >= ago(ioc_lookBack)\n| summarize LatestIndicatorTime = arg_max(TimeGenerated, *) by Id\n| where IsActive == true and ValidUntil > now()\n| extend lowerHash=tolower(ObservableValue)\n) on lowerHash\n// select column from the source table to match with Recorded Future ThreatIntelIndicator $left.Hash\n| mv-expand Label=Data.labels\n| extend RecordedFuturePortalLink = parse_json(tostring(Label)).RecordedFuturePortalLink\n// Hash and HashType is defaulted to data from Recorded Future, it can be changed to data from the infrastructure table.\n| project Hash=ObservableValue, HashType=extract(\"file:hashes.('[^']*')\", 1, ObservableKey), Description=Data.description, Type, TimeGenerated, RecordedFuturePortalLink\n",
        "queryFrequency": "PT15M",
        "queryPeriod": "P1D",
        "severity": "Medium",
        "subTechniques": [],
        "suppressionDuration": "PT1H",
        "suppressionEnabled": false,
        "tactics": [
          "Execution",
          "InitialAccess",
          "Persistence"
        ],
        "techniques": [
          "T1059",
          "T1189",
          "T1554"
        ],
        "templateVersion": "1.1.1",
        "triggerOperator": "GreaterThan",
        "triggerThreshold": 0
      },
      "type": "Microsoft.OperationalInsights/workspaces/providers/alertRules"
    }
  ]
}