A professional-grade DICOM fuzzing tool for healthcare security testing
Project description
DICOM Fuzzer
Mutation-based fuzzer for robustness testing of DICOM medical imaging viewers and parsers. Generates malformed DICOM files and feeds them into target applications to find crashes and vulnerabilities.
Installation
For end users (run the CLI)
Install from PyPI as an isolated tool so dicom-fuzzer is on your PATH everywhere, without polluting your system Python:
# Recommended: uv (fast, modern)
uv tool install dicom-fuzzer
# Alternative: pipx (same idea, different manager)
pipx install dicom-fuzzer
# Alternative: pip into the active environment
pip install dicom-fuzzer
After installation:
dicom-fuzzer --help
Optional extras are needed only for specific features (target process monitoring, Windows crash dump parsing, HTML reports, GUI automation):
uv tool install "dicom-fuzzer[all]"
# or, if you only need specific extras:
pip install dicom-fuzzer psutil minidump tqdm rich matplotlib jinja2 pywinauto
For contributors (develop the code)
git clone https://github.com/Dashtid/DICOM-Fuzzer.git
cd DICOM-Fuzzer
uv sync
source .venv/Scripts/activate # Windows/Git Bash
# source .venv/bin/activate # macOS/Linux
To run your local checkout as a global CLI while developing:
uv tool install --editable .
Source edits take effect immediately with no reinstall.
Quick Start
# Generate 100 fuzzed DICOM files
dicom-fuzzer input.dcm -c 100 -o ./artifacts/output
# Fuzz and test against a target viewer
dicom-fuzzer input.dcm -c 1000 -t ./viewer.exe --timeout 10
# Generate seed corpus for AFL/WinAFL
dicom-fuzzer generate-seeds input.dcm -c 500 -o ./seeds/
Features
Fuzzing
- Format fuzzing (production): 24 single-file mutation strategies targeting VR types, pixel data, sequences, encoding, and modality-specific tags
- Modality-specific fuzzers: CT/MR calibration, NM, PET, RT Dose, RT Structure Set, Segmentation, Secondary Capture, Encapsulated PDF, Pixel Reencoding
- Target scope filtering (
--target-type viewer|web|pacs) - Multiframe fuzzing (WIP): 10 strategies for enhanced imaging objects -- functional groups, frame counts, dimension indices
- Series/study fuzzing (WIP): cross-series geometry, temporal ordering, patient consistency
- Network protocol fuzzing (WIP): PDU construction, DIMSE commands, state machine, TLS
Supported SOP classes
Seed corpus plus dedicated fuzzer coverage (mutations are only meaningful when both exist):
| Modality | SOP Class UID | Modality fuzzer |
|---|---|---|
| CT Image | 1.2.840.10008.5.1.4.1.1.2 | calibration |
| MR Image | 1.2.840.10008.5.1.4.1.1.4 | calibration |
| NM Image | 1.2.840.10008.5.1.4.1.1.20 | nuclear_medicine |
| PET Image | 1.2.840.10008.5.1.4.1.1.128 | pet |
| RT Dose | 1.2.840.10008.5.1.4.1.1.481.2 | rt_dose |
| RT Structure Set | 1.2.840.10008.5.1.4.1.1.481.3 | rt_structure_set |
| Segmentation | 1.2.840.10008.5.1.4.1.1.66.4 | segmentation |
| Secondary Capture | 1.2.840.10008.5.1.4.1.1.7 | secondary_capture |
| Encapsulated PDF | 1.2.840.10008.5.1.4.1.1.104.1 | encapsulated_pdf |
Generic fuzzers (structure, metadata, header, preamble,
sequence, dictionary, etc.) run across all modalities.
Analysis
- Automatic crash detection and deduplication
- Crash triaging with severity and exploitability scoring
- Test case minimization
- Corpus management
- Markdown campaign reports with per-strategy hit rates
Integration
- CLI with 14 subcommands
- Python API for custom workflows
- Docker container for isolated execution
- CI/CD compatible
CLI Reference
dicom-fuzzer --help # Main fuzzing campaign
dicom-fuzzer target --help # Target testing
dicom-fuzzer generate-seeds --help # Seed corpus generation
dicom-fuzzer sanitize --help # Strip PHI from seed files
dicom-fuzzer replay --help # Decompose fuzzed files
dicom-fuzzer report --help # Report generation
dicom-fuzzer triage --help # Crash triaging
dicom-fuzzer corpus --help # Corpus management
Run dicom-fuzzer --help (and dicom-fuzzer <subcommand> --help) for the authoritative command reference.
Python API
from dicom_fuzzer.core.mutation.mutator import DicomMutator
import pydicom
mutator = DicomMutator()
dataset = pydicom.dcmread("input.dcm")
for i in range(100):
fuzzed = mutator.apply_mutations(dataset)
fuzzed.save_as(f"artifacts/output/fuzz_{i:04d}.dcm")
Project Structure
dicom-fuzzer/
├── dicom_fuzzer/ # Main package (installed by `pip install dicom-fuzzer`)
│ ├── attacks/ # Attack modules (format, series, network, multiframe)
│ ├── cli/ # Command-line interface (14 subcommands)
│ ├── core/ # Engine, mutation, corpus, crash analysis, harness, reporting
│ └── utils/ # Logging, hashing, identifiers
├── tests/ # Test suite
├── docs/ # Documentation
├── examples/ # Reference targets + maintainer tooling (not installed)
└── artifacts/ # Runtime output (gitignored)
examples/ holds the fo-dicom network harness (DIMSE SCP the network fuzzer points at) and the pydicom smoke analyzer (post-campaign corpus QA). See examples/README.md.
Documentation
Security
This tool is for authorized security testing only. See SECURITY.md.
License
MIT - see LICENSE
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file dicom_fuzzer-1.12.0.tar.gz.
File metadata
- Download URL: dicom_fuzzer-1.12.0.tar.gz
- Upload date:
- Size: 1.1 MB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e1f92e28b5ca77b7d62beb06a546d36c2dda151ea8183f2ac7df47be05483a48
|
|
| MD5 |
ac487ecd997449f9291d2a4b7c1b3090
|
|
| BLAKE2b-256 |
434803a16fb2060f993f94fe832b99a66f79d0e076665050e999f1c367ec191e
|
Provenance
The following attestation bundles were made for dicom_fuzzer-1.12.0.tar.gz:
Publisher:
release.yml on Dashtid/dicom-fuzzer
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
dicom_fuzzer-1.12.0.tar.gz -
Subject digest:
e1f92e28b5ca77b7d62beb06a546d36c2dda151ea8183f2ac7df47be05483a48 - Sigstore transparency entry: 1402285744
- Sigstore integration time:
-
Permalink:
Dashtid/dicom-fuzzer@5cf5194ac57c85f4d2d4c8d93c417901e8f6a458 -
Branch / Tag:
refs/tags/v1.12.0 - Owner: https://github.com/Dashtid
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@5cf5194ac57c85f4d2d4c8d93c417901e8f6a458 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file dicom_fuzzer-1.12.0-py3-none-any.whl.
File metadata
- Download URL: dicom_fuzzer-1.12.0-py3-none-any.whl
- Upload date:
- Size: 444.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
62ce5c75c7fac4a83740b2a71d041a52690bf66347f7c986c58e3c2ea1495217
|
|
| MD5 |
1cbb73ead010b7887cd6ebdcd563e83d
|
|
| BLAKE2b-256 |
6ec25f8e4c2f204c72b01fd199e93d9e2eadc08dc917d10eb5aece2f97a55bdc
|
Provenance
The following attestation bundles were made for dicom_fuzzer-1.12.0-py3-none-any.whl:
Publisher:
release.yml on Dashtid/dicom-fuzzer
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
dicom_fuzzer-1.12.0-py3-none-any.whl -
Subject digest:
62ce5c75c7fac4a83740b2a71d041a52690bf66347f7c986c58e3c2ea1495217 - Sigstore transparency entry: 1402285859
- Sigstore integration time:
-
Permalink:
Dashtid/dicom-fuzzer@5cf5194ac57c85f4d2d4c8d93c417901e8f6a458 -
Branch / Tag:
refs/tags/v1.12.0 - Owner: https://github.com/Dashtid
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@5cf5194ac57c85f4d2d4c8d93c417901e8f6a458 -
Trigger Event:
workflow_dispatch
-
Statement type: