Port sweep from source

Severity mediumNetworkThresholdstablenetwork.discovery.port_sweep_from_source · v1.0.0

One source address was denied against many DIFFERENT destination ports in a short window — the shape of a port scan or service sweep.

What it detects

One source address was denied against many DIFFERENT destination ports in a short window — the shape of a port scan or service sweep. This is the reconnaissance that precedes exploitation: the attacker is mapping what is listening before choosing a way in.

Counts DISTINCT destination ports, not events, because that is what separates a scan from ordinary blocked traffic. One misconfigured client retrying the same blocked port a thousand times is noise; twenty different ports from one address is someone looking around.

MITRE ATT&CK mapping

  • T1046Network Service Discovery· Discovery

False positives and triage

Vulnerability scanners, asset-discovery tools and monitoring systems do exactly this, legitimately and on a schedule — confirm the source is not your own scanner before escalating. A NAT/proxy address aggregating many clients can also spread across ports; check whether the source is a shared egress point.

Scoped to DENIED traffic on purpose. A scan against ports that are actually open is accepted, not denied, and will not fire here; catching that without drowning in ordinary traffic needs a baseline of normal per-source port fan-out rather than a fixed threshold. Stated rather than silently missed.

The rule

Declarative YAML read by the detection engine — data, never executed. Confidence 65%. Source: rules/network/port_sweep_from_source.yaml, licensed under the Apache License 2.0.

id: network.discovery.port_sweep_from_source
version: 1.0.0
status: stable
severity: medium
confidence: 0.65
platforms: [network]
mitre_techniques: [T1046]
description: |
  One source address was denied against many DIFFERENT destination ports in a short
  window — the shape of a port scan or service sweep. This is the reconnaissance
  that precedes exploitation: the attacker is mapping what is listening before
  choosing a way in.

  Counts DISTINCT destination ports, not events, because that is what separates a
  scan from ordinary blocked traffic. One misconfigured client retrying the same
  blocked port a thousand times is noise; twenty different ports from one address
  is someone looking around.
match:
  event_category: network
  # A firewall denial. The parser deliberately reports a blocked packet as
  # outcome=success with the verdict in the action (the control did its job), so
  # the verdict is what the rule keys on.
  event_action_any:
    - deny
    - dropped
    - blocked
    - client-rst
    - server-rst
threshold:
  distinct: destination_port
  count: 20
  window_seconds: 300
  group_by: [source_ip]
correlation_keys: [source_ip]
false_positive_guidance: |
  Vulnerability scanners, asset-discovery tools and monitoring systems do exactly
  this, legitimately and on a schedule — confirm the source is not your own scanner
  before escalating. A NAT/proxy address aggregating many clients can also spread
  across ports; check whether the source is a shared egress point.

  Scoped to DENIED traffic on purpose. A scan against ports that are actually open
  is accepted, not denied, and will not fire here; catching that without drowning in
  ordinary traffic needs a baseline of normal per-source port fan-out rather than a
  fixed threshold. Stated rather than silently missed.

Run this rule on your own logs — offline

KIROSEC runs this rule and the rest of the library over Windows, Linux, macOS and cloud audit logs on the analyst's own machine. Every alert links to the events that raised it, and nothing leaves the device.

Browse all detections