Skip to content

Various invalid memory accesses in ImageMagick (WPG, DDS, DCM)

Further fuzzing of ImageMagick uncovered some more issues.

An out of bounds memory read in the VerticalFilter() function can be triggered by a malformed DDS file.
Sample file
Git commit / fix
This was fixed in versions 7.0.1-4 and 6.9.4-3.

Several bugs in the WPG parser could lead to a heap overflow and random invalid memory writes. These bugs only seem to appear when a memory limit is set.
Sample for heap write overflow in SetPixelIndex
Sample for unclear invalid write in ScaleCharToQuantum
Sample for unclear invalid write in SetPixelIndex
Git commit / fix 1
Git commit / fix 2
These issues were fixed in versions 7.0.1-4 and 6.9.4-3.

Null pointer accesses and unclear segfaults can happen in the DCM parser.
Sample for null pointer access in ReadDCMImage
Sample for null pointer access in ReadDCMImage (different code)
Sample for unclear segfault in ReadDCMImage
Git commit / fix
These issues were fixed in versions 7.0.1-7 and 6.9.4-5.

ImageMagick heap overflow and out of bounds read

Recently the ImageTragick vulnerability shed some light on the security status of ImageMagick.

This made me wonder how resilient to fuzzing ImageMagick is these days. It's pretty much a posterchild example for a good fuzzing target: Lots of supported complex binary file formats.

I already did some fuzzing on ImageMagick, but as far as I remember that was before I used american fuzzy lop and was done with zzuf. I was also aware that others did some more thorough fuzzing on ImageMagick.

What I did now was relatively simple: I took a trivial, few pixels PNG and used ImageMagick's "convert" tool to convert it into all file formats that have both read and write support in ImageMagick. I used that to run a fuzzing job with afl and asan. By design ImageMagick will sometimes do huge memory allocations, these can be prevented by setting limits for the width, height and memory usage in the policy.xml file.

I discovered one heap buffer overflow in the PICT parser and one heap out of bounds read in the PSD parser. Given how big the attack surface is this is not terrible, but it shows that despite previous efforts there's still potential to fuzz ImageMagick.

Sample file for heap buffer overflow in WritePixelCachePixels() (PICT format)
Git commit / fix

Sample file for heap out of bounds read in PushShortPixel() (PSD format)
Git commit / fix

Both issues have been fixed in the versions 6.9.4-0 and 7.0.1-2. In the meantime new versions (6.9.4-1, 7.0.1-3) came out that, as far as I understand the ChangeLog, remove another potential vector for the ImageTragick vulnerabilities, so you should preferrably update to those.

dosfstools / fsck.vfat: Several invalid memory accesses

I lately fuzzed various filesystem check tools. This uncovered a number of issues in dosfstools / fsck.fat that have now been fixed in the new version 4.0. All issues were found with american fuzzy lop and address sanitizer.

Global out of bounds read file_stat() / check_dir()
Git commit / fix

Unclear invalid memory access in get_fat()
Git commit / fix

Heap overflow in read_fat()
Heap out of bounds read in get_fat()
Git commit / fix for both issues

These bugs can pose a security risk if a system automatically checks attached storage media with fsck or in situations where filesystems on untrusted devices get checked. The new version dosfstools 4.0 fixes all four bugs.

PHP EXIF parser out of bounds reads (CVE-2016-4542, CVE-2016-4543, CVE-2016-4544) and a note on custom memory allocators

PHP recently released the security updates 7.0.6, 5.6.21 and 5.5.35 that fix - among a couple of other security issues - a couple of out of bounds issues in the EXIF parser I reported.

Sample file (CVE-2016-4542)
Sample file (CVE-2016-4543)
Sample file (also CVE-2016-4543)
Sample file (CVE-2016-4544)
Bug report
Git commit

These bugs are not exceptionally interesting, but there is something to know when fuzzing PHP and the same applies also to a number of other applications: It uses a custom memory allocator that can sometimes mask issues from memory safety tools like Address Sanitizer. It is therefore good to know about them and disable them during fuzz testing.

With PHP this can be circumvented by setting the environment variable USE_ZEND_ALLOC=0 while fuzzing. This disables the Zend allocator from PHP and uses normal libc memory allocation calls.

I started documenting such issues and workarounds.

Old OpenSSL bug turns out to be a security issue (CVE-2016-2108)

Today OpenSSL released a security advisory. To my surprise one of the high severity issues involved a bug I had reported about a year ago.

The OpenSSL team didn't consider it to be a security issue - and neither did I. What I did back then was to find all possible inputs of the openssl command line tool and test them with american fuzzy lop, including those that very likely wouldn't have any security impact.

The feature I tested while finding this bug is part of the asn1 parser. It's actually not very well documented, but with openssl asn1parse -genconf [input] you can give OpenSSL a text file in a specific format that will then generate an ASN.1 structure. However it seems highly implausible that in any context one would use such a feature with attacker controlled input - therefore the bugs were fixed, but considered to be not security relevant.

But actually, the bug was not in the parser for that format itself. It was in an ASN.1 encoding function. Therefore applications that take ASN.1 encoded data and reencode it may trigger this code.

The bottom line is probably that we should be careful in claims that certain issues are not security relevant. The good news is that OpenSSL fixed this issue anyway, so all versions since June 2015 are safe.

Bugs found with Address Sanitizer in syslog-ng, monit, cmake

Lately a couple of updates have fixed issues that I discovered while testing software with Address Sanitizer (ASAN). I'll publish these combined. Once again these show that a lot of software hasn't been tested with ASAN and what kind of bugs it can uncover.

In syslog-ng a function returns an error -1 that gets stored in an unsigned variable. This cannot be stored and a subsequent check for the error value fails, this later leads to a heap out of bounds memory read. This was fixed in syslog-ng 3.7.3.
Upstream bug report
Pull request / patch
syslog-ng 3.7.3 release notes

In the monit system monitoring tool a heap overflow was discovered. A call to sscanf would write a string of length 256 into a 256 byte long buffer. However this fails to consider the trailing zero byte of that string, therefore causing a one byte heap overflow. This was fixed in monit 5.16.
Commit / fix

In the compilation tool cmake a use after free error was found. This happened becaused a variable was used in a comparison and was free'd during that comparison operation. This was fixed in cmake 3.5.0.
Upstream bug report
Commit / fix

Several out of bounds reads in ProFTPD

The latest releases of ProFTPD 1.3.5a and 1.3.6rc2 fix several out of bounds read issues. I discovered these issues by running the test suite with Address Sanitizer enabled.

An invalid off by one read can happen in the function pr_fs_dircat(). This affects both 1.3.5a and 1.3.6rc1 and earlier.
Upstream bug report
Git commit / fix

An invalid off by one read can happen in the string handling function pr_ascii_ftp_to_crlf(). This code is not present in the stable 1.3.5 release series and only affects 1.3.6 release candidates before rc2.
Upstream bug report
Git commit / fix

A missing null termination of a string causes an out of bounds memory read in a test. This does not affect the ProFTPD code itself, it's just an issue in the test suite.
Upstream bug report
Git commit / fix

Independent of these memory access issues I discovered an issue in ProFTPD regarding Diffie Hellman parameters. The server will choose risky 1024 bit parameters and ignore a user-supplied parameter file.

Heap use after free in Pidgin-OTR plugin (CVE-2015-8833)

The pidgin-otr plugin version 4.0.2 fixes a heap use after free error. The bug is triggered when a user tries to authenticate a buddy and happens in the function create_smp_dialog.

The bug was discovered with Address Sanitizer. This is yet another example why all C/C++ code should be tested with Address Sanitizer enabled.

This bug was already independently discovered and reported by Stefan Sperling in the otr bug tracker.

Independend of this bug another more severe bug in Libotr itself was also disclosed today, please make sure you update both libotr (4.1.1) and the pidgin-otr plugin (4.0.2).

Upstream bug report (contains Address Sanitizer stack trace)
Commit / fix

Miscomputations of elliptic curve scalar multiplications in Nettle

The Nettle library is a library for basic cryptographic functions. Its most prominent user is GnuTLS.

Through fuzzing of elliptic curve scalar multiplications (multiplying a point on an elliptic curve with a scalar number) I discovered two carry propagation bugs that would lead the cauculations to produce wrong results. They affect the NIST P-256 and P-384 curves. The P-256 bug is in the C code and affects multiple architectures. The P-384 bug is in the assembly code and only affects 64 bit x86. Both bugs were found with the help of american fuzzy lop.

While analyzing these bugs Nettle developer Niels Möller discovered another carry propagation bug in P-256 that was fixed in the same commit (CVE-2015-8805). Nettle 3.2 fixes all three bugs.

The impact is currently unclear, but miscalculations in cryptographic functions should generally be considered security issues. I'd like to encourage cryptographers to try to analyze whether these bugs can lead to cryptographic breaks.

I have published a code example on how to fuzz elliptic curve multiplications. It can compare the output of OpenSSL with either Nettle or NSS. It currently works only with prime field curves, but it can probably be adapted to other curves.

P-256 bug:
Mailing list post with code sample
Commit / fix for P-256 bug

P-384 bug:
Mailing list post with code sample
Commit / fix for P-384 bug

Nettle 3.2 release notes

Mozilla NSS: Wrong calculation results in mp_div() and mp_exptmod()

A bug in the NSS library can cause certain cryptographic calculations to produce wrong results. The bug is in the function mp_div(), this function gets used by the function mp_exptmod(), a combination of an exponentiation and a modulo operation. The mp_exptmod() function is used in several cryptographic algorithms, most notably it's the function to sign and encrypt with RSA and to calculate Diffie Hellman key exchanges. The NSS library is used for TLS connections in various Mozilla products.

This bug was found by comparing the results of NSS and OpenSSL bignum calculations and fuzzing the input with american fuzzy lop. A similar bug was also found and fixed in OpenSSL recently.

I first reported both issues separately, not knowing that they were caused by the same bug. In a first analysis both the Mozilla developers and I thought that the impact of the mp_div() bug would be minor, because it wasn't used in the cryptography code of NSS. But we overlooked that it was indirectly used through the mp_exptmod() function.

It is unclear what the exact impact and severity of this bug is. I am not aware of a practical way to exploit it, but as it affects important crypto code it might be possible to find exploitable scenarios.

I have published code examples with test inputs triggering the bug for both functions on Github. This bug is fixed in NSS 3.21 and in Firefox 44.

Mozilla Foundation Security Advisory 2016-07
Commit with the fix
Bug report for mp_div() (still private)
Bug report for mp_exptmod() (still private)
Example for mp_div()
Example for mp_exptmod()

Heap buffer overflow in fgetwln function of libbsd

libbsd is a library to provide common functions from BSD systems on Linux.

libbsd 0.8.1 and earlier contains a buffer overflow in the function fgetwln(). An if checks if it is necessary to reallocate memory in the target buffer. However this check is off by one, therefore an out of bounds write happens.

Upstream has released version 0.8.2 to fix this.

I have checked where this function gets used. I didn't find any code using it, so I assume the impact is limited.

This bug was found with the help of Address Sanitizer.

Bug report
Git commit / fix

Out of bounds heap read in shred / coreutils

The GNU Coreutils project has just released the new version 8.25 which fixes an out of bounds heap read bug in the shred tool that I reported. It is a nice example of the subtle bugs one can find by testing code with address sanitizer.

shred is a tool to overwrite files with random data before deleting them. It generates a random memory pattern and in this pattern generation there was a heap overread. Due to the random pattern generation this bug is not deterministic and one has to run shred with certain parameters (for example -n 20) multiple times to trigger it.

Upstream bug report
Git commit / fix
Coreutils 8.25 release notes

Talk / Session at 32C3

I'm currently at the 32C3. Tomorrow (Day 3, 28th December) I will give a small talk about the Fuzzing Project. This will be hosted by the Free Software Foundation Assembly at the congress.

Where? Room A.1
When? 2015-12-28, 19:00

The talk will give a short introduction to Fuzzing and the motivation of the Fuzzing Project. I'll also cover Address Sanitizer and my current efforts in creating a Gentoo Linux system with Address Sanitizer. And finally I'll talk a bit about fuzzing bignum libraries to find crypto vulnerabilities.

There's also a wiki page for the talk, but the 32c3 wiki is currently down.

Update: I've made the slides available as a PDF and on Slideshare.

I will repeat the talk on January 5th, 7 p.m., in the Hackerspace AFRA in Berlin.

Out of bounds read in OpenVPN

OpenVPN versions before 2.3.9 contain an out of bounds read error. The bug happens in the function resolve_remote() in the file socket.c.

I reported this bug to the OpenVPN security team on December 6th. I was informed that this was already reported to them previously and fixed in the repository. The new release 2.3.9 fixes this. The current git head code of OpenVPN has this code part completely reworked, it is thus not affected.

The reason for this bug is that for both IPv4 and IPv6 connections OpenVPN will read a struct sockaddr_in6, but in the IPv4 case the data structure is smaller than in the IPv6 case. The bug was found by trying to run OpenVPN with Address Sanitizer.

I don't know whether this is in any way exploitable, but as OpenVPN is a security sensitive software I found it worthy to make it public.