The high level procedure is as follows:
- Select a target binary
- Select or generate a small set of testcases
- Run afl-fuzz for a day or so on $(($(nproc) - 1)) cores
- Run afl-cov
- Review coverage output for gaps
- Goto 2
Targeting dcmdump
.
I'm starting out with a small set of testcases from go-dicom. I plan to try out some files from TCIA. I also plan to write some tools to generate my own files that include particular Value Representations and encoding schemes.
- Remove
PixelData
andOverlayData
tags. We don't care about how third-party libraries parse imaging data - we just want to hit the parser. This also significantly reduces the size of the testcases.
dcmodify -ea PixelData -ea OverlayData $INPUT_TESTCASES/*.dcm
- Minimize
afl-cmin -i $INPUT_TESTCASES -o $OUTPUT_TESTCASES -- /usr/local/bin/dcmdump @@
TODO: Use afl-tmin
to further reduce the size of the testcases.
- Fuzz
afl-fuzz -i $TESTCASES_DIR -o $FINDINGS_DIR -x dicom.dict /usr/local/bin/dcmdump @@
dicom.dict
is included in this repository - it includes the definitions of all known Value Representations. I could include a tag dictionary as well but idk if it will be all that useful.
o.O
Still triaging this one - there is some hardcoded autocorrection that causes DCMTK to repeatedly remove bytes from a Directory Record. It's not clear if this has security implications.
Targeting several binaries - probably storescp
and storescu
to start.
TBD - will need to do some weird instrumentation to get this to work with afl-fuzz.
Make a copy of the dcmtk
sources and compile with profiling enabled. After the
project
entry in CMakeLists.txt add the following:
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fprofile-arcs -ftest-coverage")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fprofile-arcs -ftest-coverage")
FIXME: I don't think you need -ftest-coverage
in the linker
Run afl-cov as follows:
python2 $AFL_COV_BIN -d $FINDINGS_DIR --code-dir $DCMTK_SRC --coverage-cmd $DCMTK_SRC/$BUILDDIR/bin/dcmdump AFL_FILE --lcov-web-all --overwrite
FIXME: This takes a LONG TIME holy moly. Multiprocessing support??? Python3???