Script dicom-store-inject

Script types: portrule
Categories: vuln, intrusive
Download: https://svn.nmap.org/nmap/scripts/dicom-store-inject.nse

Script Summary

Tests whether a DICOM archive accepts an unauthenticated C-STORE -- i.e. whether any client that can associate can write a new image (SOP Instance) into the PACS/VNA.

Most DICOM Storage SCPs authorise storage by AE Title alone, or not at all, so an attacker who can reach the DIMSE port can often inject arbitrary instances: a decoy study attached to a real patient, a tampered image, or a payload that exercises a downstream viewer. This is the native-protocol counterpart to dicomweb-enum's STOW-RS surface and the DICOM analogue of hl7-inject.

The script negotiates a Storage presentation context (as an SCU), builds one clearly-synthetic Secondary Capture image -- an obviously fake patient (ZZZTEST), a "SAFE TO DELETE" study description, a tiny 4x4 black frame, and UIDs under a rootless 2.25 arc -- and issues a single C-STORE. It reports whether the archive accepted the store (C-STORE-RSP 0x0000 / a warning status), refused it, or refused the association outright, and prints the UIDs of the stored instance so an operator can locate and delete it.

This is a HIGHLY INTRUSIVE, WRITING test: on success it creates a real (though clearly-marked) object in the target archive. Run it only against systems you are explicitly authorised to test, and clean up the injected instance afterwards using the UIDs it reports.

Script Arguments

dicom-store-inject.sop_class

Storage SOP Class UID to propose. Default: Secondary Capture

dicom-store-inject.patient_id

PatientID (0010,0020) to write. Default: "NMAP-STOREINJECT"

dicom.tls

Force transport for the DICOM suite: "true" (TLS), "false" (plaintext), unset = plaintext.

dicom-store-inject.max_pdu

Max PDU length. Default: 16384

dicom-store-inject.patient_name

PatientName (0010,0010) to write. Default: "ZZZTEST^NMAP^STORE^INJECT"

dicom-store-inject.calling_ae

Calling AE Title. Default: "NMAP-STORE"

dicom-store-inject.timeout

Association/response timeout (seconds). Default: 10

dicom-store-inject.uid_root

Root for generated UIDs. Default: "2.25" (rootless UUID arc)

dicom-store-inject.called_ae

Called AE Title. Default: "ANY-SCP"

dicom.called_aet, dicom.calling_aet

See the documentation for the dicom library.

Example Usage

  • nmap -p104,4242,11112 --script dicom-store-inject <target>
    
  • nmap -p4242 --script dicom-store-inject \
      --script-args 'dicom-store-inject.called_ae=ORTHANC' <target>
    
  • nmap -p2762 --script dicom-store-inject \
      --script-args 'dicom.tls=true' <target>
    

Script Output

PORT     STATE SERVICE
4242/tcp open  dicom
| dicom-store-inject:
|   Association: accepted
|   Transfer syntax: 1.2.840.10008.1.2.1 (Explicit VR Little Endian)
|   C-STORE status: 0x0000 (Success)
|   Result: ACCEPTED - the archive stored the injected instance
|   Injected instance (delete these to clean up):
|     SOP Instance UID:   2.25.184467...3.1.1.1
|     Study Instance UID: 2.25.184467...3.1
|     PatientID:          NMAP-STOREINJECT
|     PatientName:        ZZZTEST^NMAP^STORE^INJECT
|   VULNERABILITY: Unauthenticated DICOM C-STORE accepted
|_    An attacker who can associate can write arbitrary images

Requires


Author:

  • Paulino Calderon <paulino@calderonpale.com>

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