CVE-2018-3847
Multiple exploitable buffer overflow vulnerabilities exist in image parsing functionality of the CFITSIO library version 3.42. Specially crafted images parsed via the library, can cause a stack-based buffer overflow overwriting arbitrary data. An attacker can deliver an FIT image to trigger this vulnerability and potentially gain code execution.
NASA CFITSIO 3.42
https://heasarc.gsfc.nasa.gov/fitsio/fitsio.html
8.8 - CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H
CWE-121: Stack-based Buffer Overflow
CFITSIO is a library written in C, for reading and writing data files in FITS data format. This format is the standard astronomical data format endorsed by both NASA and the IAU. FITS is primarily designed to store scientific data sets consisting of multi-dimensional arrays and 2-dimensional tables containing rows and columns of data. This software is used extensively and is the primary library used when writing an application to handle the FITS format. Among other things CFITSIO is widely used in ground-based observatories as well as orbiting astronomical observatories in their ground data processing pipeline systems. For more users see, https://heasarc.gsfc.nasa.gov/docs/software/fitsio/major_users.html.
The vulnerability is present in the ffgkyn
function responsible for reading a key value pair from a FITS image. This functions main purpose is to read a keyword returning the name value and comment from the image. The error is present when an illegal character is found.
#define FLEN_CARD 81 [0]
#define FLEN_KEYWORD 72
int ffgkyn( fitsfile *fptr,
int nkey,
char *keyname,
char *value,
char *comm,
int *status)
{
char card[FLEN_CARD], sbuff[FLEN_CARD]; [1]
int namelen;
if (fits_read_record(fptr, nkey, card, status) > 0 ) /* get the 80-byte card */ [2]
return(*status);
fits_get_keyname(card, keyname, &namelen, status); /* get the keyword name */ [3]
if (fits_test_record(keyname, status) > 0) /* test keyword name; catches no END */
{
sprintf(sbuff,"Name of keyword no. %d contains illegal character(s): %s", [4]
nkey, keyname);
ffpmsg(sbuff);
}
return(*status);
}
At location 0, the defines used throughout the function are given to help better understand the sizes being used. Likewise at 1, the local variables that will be used for the function are defined.
At 2, we see the function read in the keyword directly from the image record. The value is then tested to ensure it does not contain any illegal characters. By passing in a specially crafted image the attacker can cause this check to fail. There is then a vulnerable call to the function sprintf at 4. Looking at the sprintf manual page it states,
The sprintf() functions are easily misused in a manner which enables malicious users to arbitrarily change a running program’s functionality through a buffer overflow attack. Because sprintf() assume an infinitely long string, callers must be careful not to overflow the actual space; this is often hard to assure. For safety, programmers should use the snprintf() interface instead.
Due to the lack of bounds checking as stated above this call will cause a buffer overflow. The keyname
parameter is taken directly from the image and although restricted in size to 72 bytes due to the define at 0, the added error message makes it longer than the 81 bytes of available space in the buffer, defined at location 1. This causes an exploitable stack based buffer overflow.
2018-02-23 - Vendor Disclosure
2018-03-21 - Vendor Patched
2018-04-12 - Public Release
Discovered by Tyler Bohan of Cisco Talos.