Detection rules › Kusto
CYFIRMA - Medium severity TOR Node Network Indicators - Monitor Recommended Rule
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 KQL query identifies network-based indicators from CYFIRMA intelligence that are associated with the role 'TOR'. These indicators may include IP addresses, domains, and URLs related to Tor network activity. Threat actors often use Tor for anonymous communication, command and control, data exfiltration, and evasion of network defenses."
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Reconnaissance | T1595.002 Active Scanning: Vulnerability Scanning |
| Initial Access | T1189 Drive-by Compromise |
| Persistence | T1505.003 Server Software Component: Web Shell |
| Command & Control | T1071.001 Application Layer Protocol: Web Protocols, T1090.003 Proxy: Multi-hop Proxy, T1572 Protocol Tunneling |
| Exfiltration | T1048.002 Exfiltration Over Alternative Protocol: Exfiltration Over Asymmetric Encrypted Non-C2 Protocol |
Rule body kusto
id: e41b7640-9ba6-42d6-a4c9-1ab6932a0b14
name: CYFIRMA - Medium severity TOR Node Network Indicators - Monitor Recommended Rule
description: |
"This KQL query identifies network-based indicators from CYFIRMA intelligence that are associated with the role 'TOR'.
These indicators may include IP addresses, domains, and URLs related to Tor network activity.
Threat actors often use Tor for anonymous communication, command and control, data exfiltration, and evasion of network defenses."
version: 1.0.1
kind: Scheduled
severity: Medium
enabled: false
requiredDataConnectors:
- connectorId: CyfirmaCyberIntelligenceDC
dataTypes:
- CyfirmaIndicators_CL
query: |
//TOR Node Network Indicators - Monitor Recommended
let timeFrame= 5m;
CyfirmaIndicators_CL
| where (ConfidenceScore < 80 and ConfidenceScore >= 50)
and TimeGenerated between (ago(timeFrame) .. now())
and pattern !contains 'file:hashes' and RecommendedActions has 'Monitor' and Roles has 'TOR'
| extend IPv4 = extract(@"ipv4-addr:value\s*=\s*'([^']+)'", 1, pattern)
| extend IPv6 = extract(@"ipv6-addr:value\s*=\s*'([^']+)'", 1, pattern)
| extend URL = extract(@"url:value\s*=\s*'([^']+)'", 1, pattern)
| extend Domain = extract(@"domain-name:value\s*=\s*'([^']+)'", 1, pattern)
| extend parsed = parse_json(extensions)
| extend extensionKeys = bag_keys(parsed)
| mv-expand extensionKeys
| extend extensionKeyStr = tostring(extensionKeys)
| extend ext = parsed[extensionKeyStr]
| extend props = ext.properties
| extend
extension_id = extensionKeyStr,
ASN_Owner = props.asn_owner,
ASN = props.asn,
ProviderName = 'CYFIRMA',
ProductName = 'DeCYFIR/DeTCT'
| project
IPv4,
IPv6,
URL,
Domain,
ThreatActors,
RecommendedActions,
Sources,
Roles,
Country,
IPAbuse,
name,
Description,
ConfidenceScore,
IndicatorID,
created,
modified,
valid_from,
Tags,
ThreatType,
TimeGenerated,
SecurityVendors,
ProductName,
ProviderName
queryFrequency: 5m
queryPeriod: 5m
triggerOperator: GreaterThan
triggerThreshold: 0
suppressionDuration: 5m
suppressionEnabled: true
tactics:
- CommandAndControl
- Exfiltration
- InitialAccess
- Persistence
- Reconnaissance
relevantTechniques:
- T1090
- T1572
- T1048
- T1071
- T1189
- T1505
- T1595
- T1090.003
- T1048.002
- T1071.001
- T1505.003
- T1595.002
alertDetailsOverride:
alertDisplayNameFormat: "High-Confidence TOR Node Network Indicators - Monitor Recommended - {{name}} "
alertDescriptionFormat: "{{Description}} - {{name}} "
alertDynamicProperties:
- alertProperty: ProductName
value: ProductName
- alertProperty: ProviderName
value: ProviderName
customDetails:
ThreatActors: ThreatActors
Sources: Sources
RecommendedActions: RecommendedActions
Roles: Roles
Country: Country
Description: Description
ConfidenceScore: ConfidenceScore
SecurityVendors: SecurityVendors
IndicatorID: IndicatorID
Created: created
Modified: modified
ValidFrom: valid_from
Tags: Tags
ThreatType: ThreatType
TimeGenerated: TimeGenerated
IPAbuse: IPAbuse
entityMappings:
- entityType: IP
fieldMappings:
- identifier: Address
columnName: IPv4
- entityType: IP
fieldMappings:
- identifier: Address
columnName: IPv6
- entityType: DNS
fieldMappings:
- identifier: DomainName
columnName: Domain
- entityType: URL
fieldMappings:
- identifier: Url
columnName: URL
incidentConfiguration:
createIncident: true
groupingConfiguration:
enabled: false
reopenClosedIncident: false
lookbackDuration: PT5H
matchingMethod: AllEntities
eventGroupingSettings:
aggregationKind: AlertPerResult
Stages and Predicates
Parameters
let timeFrame = 5m;
Stage 1: source
CyfirmaIndicators_CL
Stage 2: where
| where (ConfidenceScore < 80 and ConfidenceScore >= 50)
and TimeGenerated between (ago(timeFrame) .. now())
and pattern !contains 'file:hashes' and RecommendedActions has 'Monitor' and Roles has 'TOR'
Stage 3: extend (6 consecutive steps)
| extend IPv4 = extract(@"ipv4-addr:value\s*=\s*'([^']+)'", 1, pattern)
| extend IPv6 = extract(@"ipv6-addr:value\s*=\s*'([^']+)'", 1, pattern)
| extend URL = extract(@"url:value\s*=\s*'([^']+)'", 1, pattern)
| extend Domain = extract(@"domain-name:value\s*=\s*'([^']+)'", 1, pattern)
| extend parsed = parse_json(extensions)
| extend extensionKeys = bag_keys(parsed)
Stage 4: mv-expand
| mv-expand extensionKeys
Stage 5: extend (4 consecutive steps)
| extend extensionKeyStr = tostring(extensionKeys)
| extend ext = parsed[extensionKeyStr]
| extend props = ext.properties
| extend
extension_id = extensionKeyStr,
ASN_Owner = props.asn_owner,
ASN = props.asn,
ProviderName = 'CYFIRMA',
ProductName = 'DeCYFIR/DeTCT'
Stage 6: project
| project
IPv4,
IPv6,
URL,
Domain,
ThreatActors,
RecommendedActions,
Sources,
Roles,
Country,
IPAbuse,
name,
Description,
ConfidenceScore,
IndicatorID,
created,
modified,
valid_from,
Tags,
ThreatType,
TimeGenerated,
SecurityVendors,
ProductName,
ProviderName
Exclusions
Top-level NOT(...) conjuncts: predicates this rule actively suppresses.
| Field | Kind | Excluded values |
|---|---|---|
pattern | contains | file:hashes |
Indicators
Each row is a field, operator, and value that the rule matches. The corpus column counts how many other rules in the catalog look for the same combination: high numbers point to widely-used, community-vetted indicators. Blank or 1 shows that the indicator is specific to this rule.
| Field | Kind | Values |
|---|---|---|
ConfidenceScore | ge |
|
ConfidenceScore | lt |
|
RecommendedActions | match |
|
Roles | match |
|
Output fields
Fields the rule emits when it matches. Chronicle authors list these in the outcome block; they appear on the detection and $risk_score drives alerting. Sentinel / Defender XDR rules build them up through project / summarize / extend stages. Sentinel maps these into alert fields via entityMappings and customDetails; Defender XDR custom detections surface them as alert fields directly.
| Field | Source |
|---|---|
ConfidenceScore | project |
Country | project |
Description | project |
Domain | project |
IPAbuse | project |
IPv4 | project |
IPv6 | project |
IndicatorID | project |
ProductName | project |
ProviderName | project |
RecommendedActions | project |
Roles | project |
SecurityVendors | project |
Sources | project |
Tags | project |
ThreatActors | project |
ThreatType | project |
TimeGenerated | project |
URL | project |
created | project |
modified | project |
name | project |
valid_from | project |