Skip to content

Latest commit

 

History

History
109 lines (73 loc) · 9.31 KB

CaseStudies.md

File metadata and controls

109 lines (73 loc) · 9.31 KB

Introspector report: link

A previous blog post by Project Zero details a vulnerability exploited by NSO to hack iOS users in xpdf. This vulnerability is in the JBIG2Stream::readTextRegionSeg function in xpdf.

xpdf is integrated into OSS-Fuzz, but the existing fuzzing did not cover JBIG2Stream::readTextRegionSeg. As shown in Figure 1, in the "Optimal target analysis" section of Fuzz Introspector report for xpdf, the second function suggested is JBIG2Stream::reset().

The main function called by JBIG2Stream::reset() is JBIG2Stream::readSegments. readSegments actually calls the vulnerable function readTextRegionSeg.

So the call tree for this fuzz target would be:

JBIG2Stream::reset()
	readSegments()
		readTextRegionSeg() // vulnerable function.

image3

Figure 1: List of suggested targets for xpdf

Based on this suggestion, we wrote a new fuzzer to target JBIG2Stream::reset(). As visible in the latest coverage reports, OSS-Fuzz is now exercising the vulnerable function JBIG2stream::readTextRegionSeg(). This proves the usefulness of Fuzz Introspector in identifying and suggesting interesting new fuzz targets.

Introspector report: link

Fuzz Introspector provides a call-tree overview for each fuzz target (Figure 2). This overview shows the fuzz target coverage by color coding the call instructions. The red shaded areas are where the target fails to cover. As Figure 2 shows, jsonnet fuzz target fails to cover a big chunk of code.

image2

Figure 2: Fuzz target coverage for jsonnet before adding new targets

Looking at the Fuzz blocker table (Figure 3), the top blocker is in the jsonnet_evaluate_snippet_aux() funcion, where a switch statement branches on an argument of type EvalKind.

image3

Figure 3: Top fuzz blockers for jsonnet

Looking into the fuzz target call tree reveals that the argument of type EvalKind is always set to a static value (REGULAR in this case). It means that the existing fuzz target has no way to explore other cases of the switch statement.

To improve the fuzzing coverage, one could quickly conclude that we need fuzz targets to make a call to jsonnet_evaluate_snippet_aux() with other possible values of Evalkind. To this end we wrote two new fuzz targets to do this via the provided interfaces jsonnet_evaluate_snippet_multi() and jsonnet_evaluate_snippet_stream(). This way we were able to unblock the jsonnet fuzzer and increase the call tree coverage dramatically (Figure 4).

image4

Figure 4: Fuzz target coverage for jsonnet after adding new targets

Introspector report: link

MWDB uses file on malware samples, which is worrying to say the least.

After sending a couple of pull requests to tackle the low-hanging fruits, the Remaining optimal interesting functions section showed that an awful lot of functions in the readelf.c file weren't touched at all by the fuzzers.

Looking at the Fuzz blockers, file_tryelf was likely the functions that should be called, and by checking out the coverage of the relevant file, the culprit was that file needs to be passed data via a proper file descriptor to exercise its elf-related codepath, and thus a file-based fuzzer was promptly added, bumping the coverage close to 90%.

Introspector report: link

Bzip2's fuzz drivers hit 60% of the functions of the project by calling the compression and decompression functions with 2 fuzz drivers. The calltrees of bzip2_compress_target and bzip2_decompress_target do not show any significant fuzz blockers.

The file handling code is not being addressed, as seen in the Project functions overview and by the suggestions in the remaining optimal interesting functions.

functions

Based on these hints, a single new file-based fuzzer was added to hit these recommended functions. The resulting fuzzer creates a temporary file, calls BZ2_bzdopen, then BZ2_bzwrite, followed by BZ2_bzread to read what was just written, then BZ2_bzclose, hitting all of the optimal interesting functions.

calltree

The addition of this fuzz driver increases the project's statically reachable coverage to 80%. This new report shows no recommended optimal interesting functions remain, however the Project Functions overview when sorted by functions not reached by fuzz drivers shows that a number of file handling functions are still being skipped.

Examining all of these missed functions show that two optimizations remain. Calling functions higher in the control flow graph will result in greater coverage. An example of this is substituting BZ2_bzReadOpen with BZ2_bzopen.

The other observation is that there are filename and FD versions of the file handling code. The fuzzer is split into two separate drivers to handle these 2 variations, with a few extra references to additional functions such as BZ2_bzReadGetUnused.

BZIP2 now has 100% of all functions statically reachable by the fuzz drivers.