ZDI-CAN-367: Apple CUPS 1.3.7 (HP-GL/2 filter) Remote Code Execution Vulnerability #2911

Closed
michaelrsweet opened this Issue Aug 19, 2008 · 3 comments

Comments

Projects
None yet
1 participant
Collaborator

michaelrsweet commented Aug 19, 2008

Version: 1.3-current
CUPS.org User: mike

-- ABSTRACT ------------------------------------------------------------

TippingPoint has identified a vulnerability affecting the following
products:

Apple OS X

-- VULNERABILITY DETAILS -----------------------------------------------

This vulnerability allows remote attackers to execute arbitrary code on
vulnerable installations of Apple CUPS. Authentication is not required
to exploit this vulnerability.

The specific flaw exists in the Hewlett-Packard Graphics Language
filter. Inadequate bounds checking on the pen width and pen color
opcodes result in an arbitrary memory overwrite allowing for the
execution of arbitrary code as the "hgltops" process uid.

From filter/hpgltops.h:

   typedef struct
   {
     float rgb[3]; /* Pen color */
     float width;  /* Pen width */
   } pen_t;

   VAR pen_t Pens[1024]; /* State of each pen */

From filter/hpgl-attr.c:PW_pen_width():

   float w;
   ...

[323] w = (float)hypot(PlotSize[0], PlotSize[1]) / 1016.0f * 72.0f;

   if (num_params == 0)
     w *= 0.01f;
   else

[328] w *= params[0].value.number;
...
pen = (int)params[1].value.number;

[335] Pens[pen].width = w;

There is a lack of a check on user provided index value at line [355].
An attacker may control values of PlotSize[0] and PlotSize[1]. By
selecting the opcode PS and pen width to 1.0 and provide appropriate
multiplier later at line [328] an attacker can overwrite memory address
with arbitrary data.

From filter/hpgl-attr.c:PC_pen_color():

   i = (int)params[0].value.number;
   ...
   Pens[i].rgb[0] = (params[1].value.number - ColorRange[0][0]) /
                    (ColorRange[0][1] - ColorRange[0][0]);
   Pens[i].rgb[1] = (params[2].value.number - ColorRange[1][0]) /
                    (ColorRange[1][1] - ColorRange[1][0]);
   Pens[i].rgb[2] = (params[3].value.number - ColorRange[2][0]) /
                    (ColorRange[2][1] - ColorRange[2][0]);

The same flaw exists here with the CR opcode.

-- CREDIT --------------------------------------------------------------

This vulnerability was discovered by:
* regenrecht

-- FURTHER DETAILS -----------------------------------------------------

If you have any questions, comments, concerns or require additional
details please feel free to contact me via the following:

Cameron Hotchkies
Security Response Lead
TippingPoint
chotchkies@tippingpoint.com
Office: 512.681.8172

Additionally, you may contact the manager of security response at:

Terri Forslof
Manager of Security Response
TippingPoint
tforslof@tippingpoint.com
Office: 206.618.7112

We can alternatively be reached via e-mail at:

zdi-disclosures@tippingpoint.com

Our PGP key is available from:

http://www.zerodayinitiative.com/documents/disclosures-pgp-key.asc

-- INFORMATION ABOUT THE ZDI -------------------------------------------

Established by TippingPoint, The Zero Day Initiative (ZDI) represents
a best-of-breed model for rewarding security researchers for responsibly
disclosing discovered vulnerabilities.

The ZDI is unique in how the acquired vulnerability information is
used. TippingPoint does not re-sell the vulnerability details or any
exploit code. Instead, upon notifying the affected product vendor,
TippingPoint provides its customers with zero day protection through
its intrusion prevention technology. Explicit details regarding the
specifics of the vulnerability are not exposed to any parties until
an official vendor patch is publicly available. Furthermore, with the
altruistic aim of helping to secure a broader user base, TippingPoint
provides this vulnerability information confidentially to security
vendors (including competitors) who have a vulnerability protection or
mitigation product.

Please contact us for further information or refer to:

http://www.zerodayinitiative.com

-- DISCLOSURE POLICY ---------------------------------------------------

Our vulnerability disclosure policy is available online at:

http://www.zerodayinitiative.com/advisories/disclosure_policy/
Collaborator

michaelrsweet commented Aug 20, 2008

CUPS.org User: mike

Patch attached with fix...

Collaborator

michaelrsweet commented Oct 9, 2008

CUPS.org User: mike

Fixed in Subversion repository.

Collaborator

michaelrsweet commented Oct 9, 2008

"str2911.patch":

Index: filter/hpgl-attr.c

--- filter/hpgl-attr.c (revision 914)
+++ filter/hpgl-attr.c (working copy)
@@ -197,8 +197,18 @@

if (num_params == 0)
PenCount = 8;

  • else if (num_params == 1 && params[0].value.number <= 1024)
  • PenCount = (int)params[0].value.number;
  • else if (num_params == 1)
  • {
  • if (params[0].value.number < 1 || params[0].value.number > MAX_PENS)
  • {
  •  fprintf(stderr,
    
  •     "DEBUG: HP-GL/2 \'NP\' command with invalid number of "
    
  •     "pens (%d)!\n", (int)params[0].value.number);
    
  •  PenCount = 8;
    
  • }
  • else
  •  PenCount = (int)params[0].value.number;
    
  • }
    else
    fprintf(stderr,
    "DEBUG: HP-GL/2 'NP' command with invalid number of "
    @@ -235,7 +245,7 @@

if (num_params == 0)
{

  • for (i = 0; i <= PenCount; i ++)
  • for (i = 0; i < PenCount; i ++)
    if (i < 8)
    {
    Pens[i].rgb[0] = standard_colors[i][0];
    @@ -256,8 +266,15 @@
    }
    else if (num_params == 1 || num_params == 4)
    {
  • i = (int)params[0].value.number;
  • i = (int)params[0].value.number - 1;
  • if (i < 0 || i >= PenCount)
  • {
  •  fprintf(stderr,
    
  •          "DEBUG: HP-GL/2 \'PC\' command with invalid pen (%d)!\n", i + 1);
    
  •  return;
    
  • }

if (num_params == 1)
{
Pens[i].rgb[0] = standard_colors[i & 7][0];
@@ -330,8 +347,16 @@

if (num_params == 2)
{

  • pen = (int)params[1].value.number;
  • pen = (int)params[1].value.number - 1;
  • if (pen < 0 || pen >= PenCount)
  • {
  •  fprintf(stderr,
    
  •          "DEBUG: HP-GL/2 \'PW\' command with invalid pen (%d)!\n",
    
  •     pen + 1);
    
  •  return;
    
  • }

Pens[pen].width = w;

if (PageDirty && pen == PenNumber)
@@ -345,7 +370,7 @@

  • Set width for all pens...
    */
  • for (pen = 0; pen <= PenCount; pen ++)
  • for (pen = 0; pen < PenCount; pen ++)
    Pens[pen].width = w;

if (PageDirty)
@@ -399,14 +424,16 @@
param_t params) / I - Parameters */
{
if (num_params == 0)

  • PenNumber = 1;
  • else if (params[0].value.number <= PenCount)
  • PenNumber = (int)params[0].value.number;
  • else
  • PenNumber = 0;
  • else if (num_params > 1)
    fprintf(stderr,
  •        "DEBUG: HP-GL/2 \'SP\' command with invalid number or value "
    
  •   "of parameters (%d, %d)!\n", num_params,
    
  •        "DEBUG: HP-GL/2 \'SP\' command with invalid number of parameters "
    
  •   "(%d)!\n", num_params);
    
  • else if (params[0].value.number <= 0 || params[0].value.number >= PenCount)
  • fprintf(stderr, "DEBUG: HP-GL/2 'SP' command with invalid pen (%d)!\n",
    (int)params[0].value.number);
  • else
  • PenNumber = (int)params[0].value.number - 1;

if (PageDirty)
printf("%.3f %.3f %.3f %.2f SP\n", Pens[PenNumber].rgb[0],

Index: filter/hpgltops.h

--- filter/hpgltops.h (revision 914)
+++ filter/hpgltops.h (working copy)
@@ -26,7 +26,15 @@

define M_PI 3.14159265358979323846

#endif /* M_PI */

/*

  • * Maximum number of pens we emulate...
  • /
    +
    +#define MAX_PENS 1024
    +
    +
    +/
    • Parameter value structure...
      */

@@ -108,10 +116,10 @@
/* Current pen position /
PenScaling VALUE(1.0f), /
Pen width scaling factor /
PenWidth VALUE(1.0f); /
Default pen width /
-VAR pen_t Pens[1024]; /
State of each pen /
+VAR pen_t Pens[MAX_PENS]; /
State of each pen /
VAR int PenMotion VALUE(0), /
0 = absolute, 1 = relative /
PenValid VALUE(0), /
1 = valid position, 0 = undefined */

  •   PenNumber   VALUE(1),   /\* Current pen number */
    
  •   PenNumber   VALUE(0),   /\* Current pen number _/
    PenCount    VALUE(8),   /_ Number of pens _/
    PenDown     VALUE(0),   /_ 0 = pen up, 1 = pen down _/
    PolygonMode VALUE(0),   /_ Drawing polygons? */
    

michaelrsweet added this to the Stable milestone Mar 17, 2016

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment