Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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
Labels
Milestone

Comments

@michaelrsweet
Copy link
Collaborator

@michaelrsweet 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/
@michaelrsweet

This comment has been minimized.

Copy link
Collaborator Author

@michaelrsweet michaelrsweet commented Aug 20, 2008

CUPS.org User: mike

Patch attached with fix...

@michaelrsweet

This comment has been minimized.

Copy link
Collaborator Author

@michaelrsweet michaelrsweet commented Oct 9, 2008

CUPS.org User: mike

Fixed in Subversion repository.

@michaelrsweet

This comment has been minimized.

Copy link
Collaborator Author

@michaelrsweet 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? */
    
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
1 participant
You can’t perform that action at this time.