Detection rules › Kusto
Whisper Security - Tor Exit Node Communication
Identifies network traffic communicating with known Tor exit nodes. While Tor usage may be legitimate in some environments, unexpected Tor communication can indicate data exfiltration, C2 tunneling, or policy violations.
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Command & Control |
Rule body
id: f5567c93-91de-577a-b35e-c2807715493d
name: Whisper Security - Tor Exit Node Communication
description: |
Identifies network traffic communicating with known Tor exit nodes. While Tor usage may be legitimate in some environments, unexpected Tor communication can indicate data exfiltration, C2 tunneling, or policy violations.
severity: Medium
status: Available
requiredDataConnectors:
- connectorId: WhisperSecurityConnector
dataTypes:
- WhisperThreatIntel_CL
queryFrequency: 1h
queryPeriod: 1d
triggerOperator: gt
triggerThreshold: 0
tactics:
- CommandAndControl
relevantTechniques:
- T1090
query: |
// MITRE ATT&CK: T1090.003 - Proxy: Multi-hop Proxy
// Tactic: Command and Control
// Detects communication with Tor exit nodes using Whisper threat intelligence
let timeRange = 1d;
let torIndicators = WhisperThreatIntel_CL
| where TimeGenerated > ago(timeRange)
| where isTor == true
| project indicator, threatScore, threatLevel, feedNames, lastSeen;
let CommonSecurityLogSafe = union isfuzzy=true CommonSecurityLog, (datatable(TimeGenerated:datetime, DestinationIP:string, SourceIP:string, DeviceProduct:string, DeviceAction:string, DeviceVendor:string, Activity:string)[]);
CommonSecurityLogSafe
| where TimeGenerated > ago(timeRange)
| where isnotempty(DestinationIP)
| join kind=inner (torIndicators) on $left.DestinationIP == $right.indicator
| extend SourceIP = SourceIP, DestinationIP = DestinationIP
| project TimeGenerated, SourceIP, DestinationIP, DeviceProduct, DeviceAction, DeviceVendor, Activity, threatScore, threatLevel, feedNames
entityMappings:
- entityType: IP
fieldMappings:
- identifier: Address
columnName: SourceIP
- entityType: IP
fieldMappings:
- identifier: Address
columnName: DestinationIP
customDetails:
ThreatScore: threatScore
ThreatLevel: threatLevel
FeedNames: feedNames
incidentConfiguration:
createIncident: true
groupingConfiguration:
enabled: true
reopenClosedIncident: false
lookbackDuration: PT5H
matchingMethod: AllEntities
version: 1.0.0
kind: Scheduled
Stages and Predicates
Stage 0: let
let timeRange = 1d;
let torIndicators = WhisperThreatIntel_CL
| where TimeGenerated > ago(timeRange)
| where isTor == true
| project indicator, threatScore, threatLevel, feedNames, lastSeen;
let CommonSecurityLogSafe = union <inlined as stages below>;
Stage 1: union
union of 2 branches
Stage 2: source
CommonSecurityLog
Stage 3: source
datatable
Stage 4: where
where TimeGenerated > ago(86400s)
Stage 5: where
where isnotempty(DestinationIP)
Stage 6: join
join kind=inner (torIndicators) on DestinationIP, indicator
Stage 7: extend
extend DestinationIP, SourceIP
Stage 8: project
project Activity, DestinationIP, DeviceAction, DeviceProduct, DeviceVendor, SourceIP, TimeGenerated, feedNames, threatLevel, threatScore
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
DestinationIP | is_not_null | field:"DestinationIP" kind:is_not_null | |
isTor | eq |
| field:"isTor" kind:eq value:"true" |
Output fields
These fields are emitted when the rule matches.
| Field | Source |
|---|---|
Activity | project |
DestinationIP | project |
DeviceAction | project |
DeviceProduct | project |
DeviceVendor | project |
SourceIP | project |
TimeGenerated | project |
feedNames | project |
threatLevel | project |
threatScore | project |