Script dicom-web-enum

Script types: portrule
Categories: discovery, safe
Download: https://svn.nmap.org/nmap/scripts/dicom-web-enum.nse

Script Summary

Discovers and enumerates DICOMweb services -- the HTTP/REST face of DICOM (PS3.18): QIDO-RS (query), WADO-RS (retrieve) and STOW-RS (store).

Modern PACS, VNAs and cloud imaging archives (Orthanc, dcm4chee-arc, and the cloud healthcare APIs) expose imaging over HTTP alongside, or instead of, the classic DIMSE port. Nmap has rich DIMSE coverage (dicom-info, dicom-cfind-ls, ...) but nothing for the web tier, which is often where exposure actually lives -- a QIDO-RS "/studies" endpoint reachable without authentication leaks the same study- and patient-level metadata as an unauthenticated C-FIND, and a STOW-RS "/studies" endpoint reachable without authentication is an image-injection surface.

The script: * probes a list of common DICOMweb roots (or a caller-supplied one) for a QIDO-RS "/studies" endpoint; * classifies the endpoint as open (returns application/dicom+json), authentication-required (401/403) or absent (404); * on an open endpoint, reports the study count and a sample of the study-level metadata returned (patient name/ID, study date, description, modalities) -- i.e. the PHI an unauthenticated client can read; * checks WADO-RS retrieval (study metadata) and STOW-RS store-endpoint presence, the latter via OPTIONS / an empty multipart probe that does NOT create any object; * flags unauthenticated QIDO/STOW access and PHI carried over plaintext HTTP.

It is read-only: it issues GET, OPTIONS and (for STOW detection only) an empty POST that cannot store an instance. It does not upload images or modify data.

The three DICOMweb transactions tested, and the resources they expose: * QIDO-RS (Query based on ID for DICOM Objects, PS3.18 Section 10.6) -- the "/studies", "/series" and "/instances" search resources. The study-level reply is a DICOM+JSON array (PS3.18 Annex F) of attribute objects keyed by 8-hex-digit tag; it carries PatientName (0010,0010), PatientID (0010,0020), StudyDate (0008,0020), StudyDescription (0008,1030), ModalitiesInStudy (0008,0061) and the study UID (0020,000D). * WADO-RS (Web Access to DICOM Objects by RESTful services, PS3.18 Section 10.4) -- "/studies/{uid}/metadata" and the bulk instance/frame retrieval resources. Metadata retrievability without auth means the full images are retrievable too. * STOW-RS (Store Over the Web, PS3.18 Section 10.5) -- the "/studies" POST resource, the HTTP equivalent of a C-STORE. An open STOW endpoint is an unauthenticated image-write surface (see dicom-store-inject for the DIMSE equivalent).

References: * DICOM PS3.18, Web Services: https://dicom.nema.org/medical/dicom/current/output/html/part18.html * QIDO-RS (Search transaction): PS3.18 Section 10.6 * WADO-RS (Retrieve transaction): PS3.18 Section 10.4 * STOW-RS (Store transaction): PS3.18 Section 10.5 * DICOM JSON Model: PS3.18 Annex F * Orthanc DICOMweb plugin: https://orthanc.uclouvain.be/book/plugins/dicomweb.html * dcm4chee-arc-light (DICOMweb archive): https://github.com/dcm4che/dcm4chee-arc-light

See also:

Script Arguments

dicom-web-enum.scheme

"http" or "https". Default: inferred from the port (https for ssl/443/8443, else http, with a fallback to the other scheme).

dicom-web-enum.timeout

HTTP timeout in seconds. Default: 10.

dicom-web-enum.samples

Number of studies to sample from QIDO-RS for metadata reporting. Default: 3. 0 disables metadata sampling (endpoint detection only).

dicom-web-enum.root

DICOMweb base path to test (e.g. "/dicom-web"). If unset, a built-in candidate list is probed.

slaxml.debug

See the documentation for the slaxml library.

http.host, http.max-body-size, http.max-cache-size, http.max-pipeline, http.pipeline, http.truncated-ok, http.useragent

See the documentation for the http library.

smbdomain, smbhash, smbnoguest, smbpassword, smbtype, smbusername

See the documentation for the smbauth library.

Example Usage

  • nmap -p 8042 --script dicom-web-enum <target>
    
  • nmap -p 443 --script dicom-web-enum \
      --script-args 'dicom-web-enum.root=/dicom-web,dicom-web-enum.scheme=https'\
      <target>
    
  • nmap -p 8042 --script dicom-web-enum \
      --script-args 'dicom-web-enum.samples=5' <target>
    

Script Output

PORT     STATE SERVICE
8042/tcp open  http
| dicom-web-enum:
|   Base URL: http://10.0.0.5:8042/dicom-web
|   Server: Orthanc 1.12.4
|   Transport: HTTP (plaintext)
|   QIDO-RS (query): OPEN - no authentication required
|     Studies visible: 128
|     Sample studies:
|       DOE^JOHN | ID=PAT001 | 20240115 | CT CHEST | CT | series=4
|       ROE^JANE | ID=PAT002 | 20240116 | MR BRAIN | MR | series=6
|   WADO-RS (retrieve): OPEN - study metadata retrievable
|   STOW-RS (store): OPEN - store endpoint accepts unauthenticated POST
|   VULNERABILITY: Unauthenticated DICOMweb access exposes PHI and an
|     image-injection (STOW-RS) surface
|_    PHI is served over plaintext HTTP (no TLS)

Requires


Author:

  • Paulino Calderon <paulino@calderonpale.com>

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