Script dicom-store-fuzzer
Script types:
portrule
Categories:
fuzzer, intrusive
Download: https://svn.nmap.org/nmap/scripts/dicom-store-fuzzer.nse
Script Summary
DICOM C-STORE fuzzer for post-association PACS vulnerability testing.
Reads a fuzz corpus generated by dicom_fuzzgen.py and transmits each malformed DICOM file to the target PACS via C-STORE (DIMSE), monitoring for crashes, hangs, unexpected responses, and anomalous behaviour.
The attack surface is post-association but pre-authentication in any application-layer sense -- most PACS accept C-STORE from any associated SCU without further authentication checks.
Test coverage: * Tag value overflow / boundary violations * VR type confusion and mismatch * Sequence nesting attacks (stack overflow, OOM) * Pixel data mutations (buffer size, bit depth, encapsulation) * Transfer syntax abuse (deflate bombs, JPEG corruption, encoding mismatch) * Private and unknown tag injection * File Meta Information attacks * String encoding and character set attacks * DICOM-specific logic bombs * CVE-specific payloads (multiple vendors)
Anomaly classification: SUCCESS -- C-STORE-RSP Status 0x0000 (notable if input was heavily malformed) FAILURE -- C-STORE-RSP Status != 0x0000 (expected for malformed input) REJECT -- A-ASSOCIATE-RJ (SOP class not supported) ABORT -- A-ABORT from target (potential parser panic) TIMEOUT -- No response within timeout (potential crash or infinite loop) RESET -- TCP RST (process likely crashed) CONN_REFUSED -- Cannot connect (target service down / crashed) CORRUPT_RSP -- Response not a valid DICOM PDU (memory corruption indicator)
Health checks run automatically after each configurable interval and after any TIMEOUT or RESET. Three consecutive health-check failures constitute a CRITICAL CRASH; fuzzing halts and the triggering case is reported.
WARNING: This is an intrusive script. It WILL send malformed DICOM data to the target PACS and MAY cause crashes, hangs, data corruption, or exhaustion of service resources. Only use against systems for which you have explicit written authorisation. Medical imaging systems are life-critical infrastructure.
Requires the dicom.lua library (place in nselib/ or same directory).
Script Arguments
- dicom-store-fuzzer.output
Output verbosity: "summary","verbose","debug" (default: "summary")
- dicom-store-fuzzer.categories
Comma-separated categories to send: "all","cat01","cat03,cat04" (default: "all")
- dicom-store-fuzzer.results_file
Write JSON results to this path (default: /tmp/dicom-store-fuzzer-<ip>.json)
- dicom-store-fuzzer.delay
Delay between cases in milliseconds (default: 200)
- dicom-store-fuzzer.corpus
Path to fuzz_corpus directory containing manifest.json (REQUIRED)
- dicom-store-fuzzer.cases
Specific case IDs: "TC0001,TC0042" (default: all)
- dicom-store-fuzzer.max_pdu
Max PDU Length to propose in bytes (default: 16384)
- dicom-store-fuzzer.called_ae
Target AE Title (default: "ORTHANC")
- dicom-store-fuzzer.resume
Resume from this case ID after a previous crash (default: none)
- dicom-store-fuzzer.baseline
Send baseline before fuzzing to verify C-STORE works (default: true)
- dicom-store-fuzzer.fallback_sc
Use Secondary Capture fallback if SOP class rejected (default: true)
- dicom-store-fuzzer.calling_ae
Our AE Title (default: "NMAP-FUZZ")
- dicom-store-fuzzer.timeout
C-STORE response timeout in seconds (default: 10)
- dicom-store-fuzzer.health_interval
Health check every N cases (default: 10)
- dicom-store-fuzzer.batch
Cases per association; 1 = per-case isolation (default: 1)
- dicom.called_aet, dicom.calling_aet
See the documentation for the dicom library.
Example Usage
nmap -p 104,11112 --script dicom-store-fuzzer \ --script-args 'dicom-store-fuzzer.corpus=/path/to/fuzz_corpus_v5,dicom-store-fuzzer.called_ae=ORTHANC' <target>
nmap -p 11112 --script dicom-store-fuzzer \ --script-args 'dicom-store-fuzzer.corpus=./fuzz_corpus_v5,dicom-store-fuzzer.categories=cat03,cat04,dicom-store-fuzzer.timeout=15' <target>
nmap -p 104 --script dicom-store-fuzzer \ --script-args 'dicom-store-fuzzer.corpus=./fuzz_corpus_v5,dicom-store-fuzzer.cases=TC0001,TC0042,TC0300,dicom-store-fuzzer.output=verbose' <target>
Script Output
PORT STATE SERVICE 104/tcp open dicom | dicom-store-fuzzer: | Target AE: ORTHANC Calling AE: NMAP-FUZZ | Corpus: /path/to/fuzz_corpus_v5 (1357 cases queued) | Baseline: SUCCESS (C-STORE accepted) | Cases Sent: 1357 / 1357 | Results: SUCCESS=898 FAILURE=384 TIMEOUT=4 RESET=2 REJECT=18 ABORT=6 CORRUPT=0 | CRITICAL FINDINGS: | [CRASH] TC0215 cat03_sequence_nesting/TC0215_depth_500.dcm | Sequence depth 500 - TCP RST, target unresponsive for 8s | [TIMEOUT] TC0401 cat05_transfer_syntax/TC0401_deflate_bomb.dcm | Deflate bomb - No response after 10s, target recovered | [ACCEPT] TC0507 cat06_private_tags/TC0507_inject_shell_dollar.dcm | Shell injection in PatientName - Stored successfully | Results file: /tmp/dicom-store-fuzzer-192.168.1.50.json |_
Requires
Author:
License: Same as Nmap -- See https://nmap.org/book/man-legal.html
action
- action (host, port)
-
MAIN ACTION
Parameters
- host
- port
