EXPLORE
← Back to Explore
crowdstrike_cqlHunting

Connections to Tor Exit Nodes

Detects network connections to or from known Tor exit nodes by matching endpoint telemetry against a curated lookup file of Tor exit node IPs.

MITRE ATT&CK

command-and-control

Detection Query

#event_simpleName=NetworkConnectIP4
| match(file="tor-exit-nodes.csv", field=RemoteAddressIP4, column=ip, strict=true)
| groupBy(
    [aid, ComputerName],
    function=[
        count(aid, as=ConnectionCount),
        count(aid, distinct=true, as=UniqueIPs),
        collect([RemoteAddressIP4, RemotePort]),
        min(@timestamp, as=FirstSeen),
        max(@timestamp, as=LastSeen)
    ]
  )
| FirstSeen := formatTime(format="%Y-%m-%d %H:%M:%S", field=FirstSeen)
| LastSeen  := formatTime(format="%Y-%m-%d %H:%M:%S", field=LastSeen)
| sort(ConnectionCount, order=desc)

Author

ByteRay GmbH

Data Sources

Endpoint

Platforms

windowslinux

Tags

Huntingcs_module:Insight
Raw Content
# --- Query Metadata ---
# Human-readable name for the query. Will be displayed as the title.
name: Connections to Tor Exit Nodes

# MITRE ATT&CK technique IDs
mitre_ids:
  - T1090.003

# Description of what the query does and its purpose.
description: |
  Detects network connections to or from known Tor exit nodes by matching endpoint telemetry against a curated lookup file of Tor exit node IPs.

# The author or team that created the query.
author: ByteRay GmbH

# The required log sources to run this query successfully in Next-Gen SIEM.
log_sources:
  - Endpoint

# The CrowdStrike modules required to run this query.
cs_required_modules:
  - Insight

# Tags for filtering and categorization.
tags:
  - Hunting

# --- Query Content ---
# The actual CrowdStrike Query Language (CQL) code.
# Using the YAML block scalar `|` allows for multi-line strings.
cql: |
  #event_simpleName=NetworkConnectIP4
  | match(file="tor-exit-nodes.csv", field=RemoteAddressIP4, column=ip, strict=true)
  | groupBy(
      [aid, ComputerName],
      function=[
          count(aid, as=ConnectionCount),
          count(aid, distinct=true, as=UniqueIPs),
          collect([RemoteAddressIP4, RemotePort]),
          min(@timestamp, as=FirstSeen),
          max(@timestamp, as=LastSeen)
      ]
    )
  | FirstSeen := formatTime(format="%Y-%m-%d %H:%M:%S", field=FirstSeen)
  | LastSeen  := formatTime(format="%Y-%m-%d %H:%M:%S", field=LastSeen)
  | sort(ConnectionCount, order=desc)