Detection rules › Kusto
Whisper Security - Co-Hosted Malware Cluster Detection
Identifies IP addresses that host multiple domains associated with malware. When an IP has more than 3 co-hosted domains and at least 3 of those domains are flagged as malware by Whisper threat intelligence, it strongly indicates compromised or adversary-controlled infrastructure.
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Resource Development |
Rule body
id: 374a77f4-23ed-55dc-8441-8e47a1e079e9
name: Whisper Security - Co-Hosted Malware Cluster Detection
description: |
Identifies IP addresses that host multiple domains associated with malware. When an IP has more than 3 co-hosted domains and at least 3 of those domains are flagged as malware by Whisper threat intelligence, it strongly indicates compromised or adversary-controlled infrastructure.
severity: High
status: Available
requiredDataConnectors:
- connectorId: WhisperSecurityConnector
dataTypes:
- WhisperInfraContext_CL
- WhisperThreatIntel_CL
queryFrequency: 1h
queryPeriod: 1d
triggerOperator: gt
triggerThreshold: 0
tactics:
- ResourceDevelopment
relevantTechniques:
- T1584
query: |
// MITRE ATT&CK: T1584.001 - Compromise Infrastructure: Domains
// Tactic: Resource Development
// Detects clusters of malware-hosting domains sharing the same IP infrastructure
let minCohostedCount = 3;
let minMalwareCoHosts = 3;
let cohostedInfra = WhisperInfraContext_CL
| where TimeGenerated > ago(1d)
| where cohostedCount > minCohostedCount
| extend parsedIp = tostring(split(ipAddresses, ",")[0])
| project indicator, parsedIp, cohostedCount, countries, registrar;
let malwareIndicators = WhisperThreatIntel_CL
| where TimeGenerated > ago(1d)
| where isMalware == true
| project indicator, threatScore, threatLevel, feedNames;
cohostedInfra
| join kind=inner (malwareIndicators) on indicator
| summarize malwareCoHostCount = dcount(indicator), DnsDomains = make_set(indicator, 10), avgThreatScore = avg(threatScore), maxThreatScore = max(threatScore) by parsedIp, cohostedCount, countries, registrar
| where malwareCoHostCount >= minMalwareCoHosts
| extend DnsDomain = tostring(DnsDomains[0]), IPAddress = parsedIp
| project TimeGenerated = now(), DnsDomain, IPAddress, malwareCoHostCount, cohostedCount, avgThreatScore, maxThreatScore, countries, registrar, DnsDomains
entityMappings:
- entityType: DNS
fieldMappings:
- identifier: DomainName
columnName: DnsDomain
- entityType: IP
fieldMappings:
- identifier: Address
columnName: IPAddress
customDetails:
MalwareCoHostCount: malwareCoHostCount
CoHostedCount: cohostedCount
MaxThreatScore: maxThreatScore
incidentConfiguration:
createIncident: true
groupingConfiguration:
enabled: true
reopenClosedIncident: false
lookbackDuration: PT5H
matchingMethod: AllEntities
version: 1.0.0
kind: Scheduled
Stages and Predicates
Parameters
let minCohostedCount = 3;
let minMalwareCoHosts = 3;
let cohostedInfra is inlined into the numbered stages below.
Let binding: malwareIndicators
let malwareIndicators = WhisperThreatIntel_CL
| where TimeGenerated > ago(1d)
| where isMalware == true
| project indicator, threatScore, threatLevel, feedNames;
Stages 1 to 5 define let cohostedInfra (the rule's main pipeline source); stages 6 to 10 run on it.
Stage 1: source
WhisperInfraContext_CL
Stage 2: where
| where TimeGenerated > ago(1d)
Stage 3: where
| where cohostedCount > minCohostedCount
Stage 4: extend
| extend parsedIp = tostring(split(ipAddresses, ",")[0])
Stage 5: project
| project indicator, parsedIp, cohostedCount, countries, registrar
Stage 6: join
cohostedInfra
| join kind=inner (malwareIndicators) on indicator
Stage 7: summarize
| summarize malwareCoHostCount = dcount(indicator), DnsDomains = make_set(indicator, 10), avgThreatScore = avg(threatScore), maxThreatScore = max(threatScore) by parsedIp, cohostedCount, countries, registrar
Stage 8: where
| where malwareCoHostCount >= minMalwareCoHosts
Stage 9: extend
| extend DnsDomain = tostring(DnsDomains[0]), IPAddress = parsedIp
Stage 10: project
| project TimeGenerated = now(), DnsDomain, IPAddress, malwareCoHostCount, cohostedCount, avgThreatScore, maxThreatScore, countries, registrar, DnsDomains
Indicators
These rows show field, operator, and value matches.
Output fields
These fields are emitted when the rule matches.
| Field | Source |
|---|---|
DnsDomain | project |
DnsDomains | project |
IPAddress | project |
TimeGenerated | project |
avgThreatScore | project |
cohostedCount | project |
countries | project |
malwareCoHostCount | project |
maxThreatScore | project |
registrar | project |