Talos Vulnerability Report

TALOS-2018-0530

NASA CFITSIO `ffgkyn` Stack Overflow Code Execution Vulnerability

April 12, 2018
CVE Number

CVE-2018-3847

Summary

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.

Tested Versions

NASA CFITSIO 3.42

Product URLs

https://heasarc.gsfc.nasa.gov/fitsio/fitsio.html

CVSSv3 Score

8.8 - CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H

CWE

CWE-121: Stack-based Buffer Overflow

Details

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.

Timeline

2018-02-23 - Vendor Disclosure
2018-03-21 - Vendor Patched
2018-04-12 - Public Release

Credit

Discovered by Tyler Bohan of Cisco Talos.