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:
License: Same as Nmap -- See https://nmap.org/book/man-legal.html
