Script dicom-slowloris

Script types: portrule
Categories: dos, intrusive
Download: https://svn.nmap.org/nmap/scripts/dicom-slowloris.nse

Script Summary

DICOM association-exhaustion (slowloris-style) denial-of-service probe.

Tests whether a DICOM SCP can be driven into association-pool exhaustion, a slowloris-like attack adapted to the DICOM Upper Layer protocol (PS3.8). A DICOM server must keep state for every established association until it is released (A-RELEASE) or aborted (A-ABORT), and most PACS / VNA / modality software caps concurrent associations (commonly 10-50). A client that opens associations and holds them -- idle, drip-fed, or half-open -- can fill that pool and lock out legitimate SCUs (modalities, workstations, gateways).

Attack modes: * "idle" (default) complete the A-ASSOCIATE handshake and hold it open with no DIMSE traffic (PS3.8 has no mandatory idle timeout). * "echo" complete the handshake and send a periodic C-ECHO keep-alive to defeat ARTIM / proprietary idle timers. * "partial" open TCP and send only the first bytes of an A-ASSOCIATE-RQ, so the server's ARTIM timer holds the socket while it waits for the rest -- exhaustion before a single association even completes.

Rather than flipping on one failed probe, the script: * measures a baseline association latency first, and rejects the run if the server already refuses this calling AE (AE whitelist) or is down; * fills the pool in waves, and after each wave records the probe latency and counts how many held associations are still alive (so a server that quietly drops half-open sockets is detected, not mistaken for a full pool); * requires several consecutive unavailable probes before declaring exhaustion, and classifies the failure (TCP refused vs accepted-but- unanswered) to point at the limit that broke; * reports a graded verdict -- VULNERABLE (full exhaustion), DEGRADED (latency rose sharply but never fully failed), or NOT VULNERABLE -- plus the recovery time after release.

WARNING: this is a denial-of-service test. A successful run disrupts clinical DICOM traffic (store, query, retrieve). Run it only against systems you are explicitly authorised to test, in a controlled window.

Requires the dicom.lua library (place in nselib/ or same directory).

Script Arguments

dicom-slowloris.mode

"idle", "echo" or "partial". Default: "idle"

dicom-slowloris.baseline_samples

Probes used to set the baseline. Default: 3

dicom.tls

Force transport: "true"/"false"/unset.

dicom-slowloris.vary_ae

Vary calling AE per connection. Default: false

dicom-slowloris.echo_interval

Seconds between C-ECHO keep-alives (echo mode). Default: 5

dicom-slowloris.wave_delay

Seconds between waves. Default: 1

dicom-slowloris.degrade_factor

Latency multiple over baseline that counts as degraded. Default: 10

dicom-slowloris.confirm

Consecutive failed probes required to confirm exhaustion. Default: 2

dicom-slowloris.calling_ae

Our AE Title. Default: "NMAP-SLOW"

dicom-slowloris.connections

Max connections to open. Default: 50

dicom-slowloris.wave_size

Connections per wave. Default: 10

dicom-slowloris.partial_bytes

Bytes to send in partial mode. Default: 32

dicom-slowloris.called_ae

Target AE Title. Default: "ANY-SCP"

dicom-slowloris.max_pdu

Max PDU length. Default: 16384

dicom-slowloris.timeout

Connection/DIMSE timeout. Default: 10

dicom-slowloris.hold_time

Seconds to hold after exhaustion. Default: 10

dicom.called_aet, dicom.calling_aet

See the documentation for the dicom library.

Example Usage

  • nmap -p4242 --script dicom-slowloris \
      --script-args 'dicom-slowloris.called_ae=ORTHANC' <target>
    
  • nmap -p4242 --script dicom-slowloris \
      --script-args 'dicom-slowloris.mode=echo,dicom-slowloris.connections=200' \
      <target>
    
  • nmap -p2762 --script dicom-slowloris --script-args 'dicom.tls=true' <target>
    

Script Output

PORT     STATE SERVICE
4242/tcp open  dicom
| dicom-slowloris:
|   Mode: idle   Target AE: ORTHANC   Calling AE: NMAP-SLOW
|   Baseline association latency: 6 ms
|   Phase 1 - Filling association pool:
|     Wave 1: +10 opened (10 held, 10 alive, 0 failed) probe ok 7 ms
|     Wave 2: +10 opened (20 held, 20 alive, 0 failed) probe ok 41 ms
|     Wave 3: +8 opened, 2 refused (28 held, 28 alive) probe timeout
|     Exhaustion confirmed at 28 associations (2 consecutive failures)
|   Failure mode: connections accepted but unanswered (pool saturation)
|   Latency under load: 6 ms baseline -> 41 ms peak before failure
|   Phase 2 - Holding (10s): held 28, still alive 28 at end
|   Phase 3 - Release and recovery: server available 1.2s after release
|   Results:
|     VULNERABLE: association-pool exhaustion confirmed
|     Exhaustion threshold: 28 concurrent associations
|     Recovery: 1.2s after release
|_    Mitigation: ARTIM/idle timeout, per-source limits, rate limiting

Requires


Author:

  • Paulino Calderon <paulino@calderonpale.com>

License: Same as Nmap -- See https://nmap.org/book/man-legal.html