Lucene search

K
binamuseFeliam ([email protected])BINAMUSE:583CC7EB3E354FF46BCE222F3B7FA8BE
HistoryMay 31, 2013 - 2:36 p.m.

Multiple vulnerabilities on sketchup

2013-05-3114:36:00
blog.binamuse.com
653

9.3 High

CVSS2

Access Vector

NETWORK

Access Complexity

MEDIUM

Authentication

NONE

Confidentiality Impact

COMPLETE

Integrity Impact

COMPLETE

Availability Impact

COMPLETE

AV:N/AC:M/Au:N/C:C/I:C/A:C

0.745 High

EPSS

Percentile

97.8%

SketchUp is a 3D modeling program marketed by Trimble Navigation Limited(previously Google) and designed for architectural, civil, and mechanical engineers as well as filmmakers, game developers, and related professions.

SketchUp fails to validate the input when parsing different types of embedded textures. Exploitation of this issues will lead to the execution of arbitrary code on the client machine with the privileges of the user running the Sketchup. This vulnerabilities can be triggered when a malicious .skp file is open in SketchUp or previewed in Windows Explorer.

CVE Title Fixed in version
CVE-2013-3662 MAC Pict Material Stack Corruption 8M2
CVE-2013-3663 BMP RLE8 Heap Overflow 8M3
CVE-2013-3664 MAC Pict Material Stack Corruption 2 2013
CVE-2013-3664 BMP RLE4 Heap Overflow 2013
The native SketchUp fileformat can handle textured 3D content. Sketchup can create realistic materials taken from image files such as .jpg pictures taken with a digital camera. A number of this images can be embedded into the main .skp file and loaded every time the 3D scene is open. As the same image library is used for in any case the issues addressed here can also be triggered when Windows Explorer reads the embedded thumbnail in a .skp file. Arbitrary code execution is proved possible in 4 different ways after an .skp file with a malicious texture or thumbnail or background image is opened.

Sketchup MAC Pict Material Palette Stack Corruption

Sketchup fails to validate the input when parsing an embedded MAC Pict texture, leading to an arbitrary stack offset overwrite and finally to an arbitrary code execution. The issue arises when SketchUp tries to load the color palette table of a MAC Pict material (or embedded image). A Mac Pict file can hold palettes of up to 64k colors. It is encoded so the number of colours to read from the file is the firsts 16bit unsigned value of the encoded palette.

                        '>H'  numColors  

Then it follows a list of up to numColors palette entries.

                        [  
                         '>H'  color index   
                         'BBB' RGB  
                        ] * numColors  

Each entry is a pair of index and RGB color and the entries can be put in any order. The only constraint is that each index must be less or equal than numColor. SketchUp reads this potentially 64k entries length table in a 256 entries length stack buffer.

> In Windows this buffer is guarded by a /GS cookie but this protection is rendered useless because of the arbitrary color index. An attacker could select the indexes passed on the encoded palette so the cookie is never altered.

So an arbitrary RGB color can be placed at an arbitrary position in the range of the 64k entries from the beginning of the original stack buffer. The only problem is that an RGB color is 3 bytes sized and there is room allocated for a 4th byte in each color entry, probably for an alpha channel. This 4th byte (the most significant byte of the resultant 32bit word) is forced to 00.

Thus, is fair to say that an almost arbitrary offset of the stack can be written with an almost arbitrary value. Playing with the stacked local values of the calling functions it is possible to capture the execution flow and execute arbitrary code.

Exploitation of the above problem will lead to the execution of arbitrary code on the client machine with the privileges of the user running the SketchUp.

In the exploit, as it is possible to embed several materials two different exploiting primitives are devised.

  1. write a zero byte followed by 3 controlled bytes to any low memory address.
  2. control the program counter via a memory deference

So each time a MAC Pict image is parsed by Google SketchUp either of these things can be done. This exploit needs less than 24 texture images to control the program behavior.

In Windows the writable memory at address 0x100000 is used as a pivot. The stack is switched to it and a ROP like chain is mastered to bypass DEP. Yes there are fixed executable memory maps loaded at the same addres in W7/XP(0x100000) where to search for ROP gadgets. This dll being fixed at 0x100000 is the only source of unreliability of the exploit.

Debug

The function that reads the MAC Pict material color pallete is at 0x017449b0. The .skp file can contain up to 24 preseted materials possibly replaced by PICT images; so a breakpoint there can happen up to 24 times with this settings. A copy of the vulnerable function dissemble is here.

Summary and exploit

SketchUp BMP RLE8 Heap Overflow

Sketchup fails to validate the input when parsing an embedded BMP RLE8 compressed texture, leading to an arbitrary stack offset overwrite and finally to arbitrary code execution.

The code parsing BMP/RLE images seem to be taken from a discontinued open source project, paintlib. The problematic function looks like this:

void PLBmpDecoder::decodeRLE8  
    ( PLDataSource * pDataSrc,  
      PLBmpBase * pBmp  
    )  
            // Decodes a compressed 256-color-bitmap  
{  
  int y;                    // Current row  
  
  PLBYTE * pDest;           // Current destination  
  PLBYTE * pSrc;            // Current position in file  
  PLBYTE   RunLength;       // Length of current run  
  bool   bEOL;              // true if end of line reached  
  bool   bEOF=false;        // true if end of file reached  
  PLBYTE ** pLineArray = pBmp->GetLineArray();  
                            // Pointers to dest lines  
  
  Trace (2, "Decoding RLE8-compressed bitmap.\n");  
  
  for (y=0; y<pBmp->GetHeight() && !bEOF; y++)  
  {                         // For each line...  
    pDest = pLineArray[pBmp->GetHeight()-y-1];  
    bEOL=false;  
    while (!bEOL)  
    {                       // For each packet do  
      pSrc = pDataSrc->Read1Byte();  
      RunLength = *pSrc;  
      if (RunLength==0)  
      { // Literal or escape.  
        pSrc = pDataSrc->Read1Byte();  
        RunLength = *pSrc;  
        switch (RunLength)  
        {  
          case 0:           // End of line escape  
            bEOL = true;  
            break;  
          case 1:           // End of file escape  
            bEOF = true;  
            bEOL = true;  
            break;  
          case 2:           // Delta escape.  
            // I have never seen a file using this  
            raiseError (PL_ERRFORMAT_NOT_SUPPORTED,  
                        "Encountered delta escape.");  
            bEOL = true;  
            bEOF = true;  
            break;  
          default:  
                            // Literal packet  
            pSrc = pDataSrc->ReadNBytes(RunLength);  
            memcpy (pDest, pSrc, RunLength);  
            pDest += RunLength;  
            // Word alignment at end of literal packet.  
            if (RunLength & 1) pDataSrc->Skip(1);  
        }  
      }  
      else  
      {                     // Encoded packet:  
                            // RunLength pixels,   
                                // all with the same value  
        pSrc = pDataSrc->Read1Byte();  
        memset (pDest, *pSrc, RunLength);  
        pDest += RunLength;  
      }  
    }  
  }  
}  

Note that the ‘while’ statement ends only when it reaches an EOF token (or similar condition) on the input. It decodes RLE packets into the previously allocated buffer “pLineArray”. The pLineArray is supposed to by a bitmap. Its size (height*width) is controlled by the input. So we can allocate any buffer size and then write and overflow it with whatever content we want.

Exploitation of the above problem will lead to the execution of arbitrary code on the client machine with the privileges of the user running the Sketchup.

Sumary and exploit

MAC Pict Material Stack Corruption 2

Similarly to the previous PICT bug this is triggered when SketchUp loads the color palette table of a MAC Pict material (or embedded image). We found another way to reach the vulnerable code, which was still there.

Sumary and exploit

BMP RLE4 Heap Overflow

Similarly to the previous BMP bug this bug is triggered when SketchUp loads BMP material with RLE4 compression.

The code parsing BMP/RLE4 images seem to be taken from a discontinued open source project, paintlib. The problematic function looks like this:

void PLBmpDecoder::decodeRLE4  
    ( PLDataSource * pDataSrc,  
      PLBmpBase * pBmp  
    )  
    // Decodes a compressed 16-color-bitmap.  
{  
  int y;                              // Current row  
  
  PLBYTE * pSrc;  
  PLBYTE * pDest;                       // Current destination.  
  int    XSize = pBmp->GetWidth();  // Width of bitmap in pixels.  
  PLBYTE   SrcByte;                     // Source byte cache.  
  
  PLBYTE   RunLength;    // Length of current run.  
  bool   bOdd;         // true if current run has odd length.  
  
  bool   bEOL;         // true if end of line reached.  
  bool   bEOF=false;   // true if end of file reached.  
  
  PLBYTE * pLineBuf;     // Current line as uncompressed nibbles.  
  PLBYTE * pBuf;         // Current position in pLineBuf.  
  PLBYTE ** pLineArray = pBmp->GetLineArray();  
                                   // Pointers to dest. lines.  
  
  Trace (2, "Decoding RLE4-compressed bitmap.  
");  
  
  // Allocate enough memory for DWORD alignment in original 4 bpp  
  // bitmap.  
  pLineBuf = new PLBYTE [XSize*4+28];  
  
  for (y=0; y<pBmp->GetHeight() && !bEOF; y++)  
  { // For each line...  
    pBuf = pLineBuf;  
    bEOL=false;  
    while (!bEOL)  
    { // For each packet do  
      pSrc = pDataSrc->Read1Byte();  
      RunLength = *pSrc;  
      if (RunLength==0)  
      { // Literal or escape.  
        pSrc = pDataSrc->Read1Byte();  
        RunLength = *pSrc;  
        switch (RunLength)  
        {  
          case 0: // End of line escape  
            bEOL = true;  
            break;  
          case 1: // End of file escape  
            bEOF = true;  
            bEOL = true;  
            break;  
          case 2: // Delta escape.  
            // I have never seen a file using this.  
            delete [] pLineBuf;  
            raiseError (PL_ERRFORMAT_NOT_SUPPORTED,  
                        "Encountered delta escape.");  
            break;  
          default:  
            // Literal packet  
            bOdd = (RunLength & 1);  
            RunLength /= 2; // Convert pixels to bytes.  
            for (int i=0; i<RunLength; i++)  
            { // For each source byte...  
              pSrc = pDataSrc->Read1Byte();  
              decode2Nibbles (pBuf, *pSrc);  
              pBuf += 2;  
            }  
            if (bOdd)  
            { // Odd length packet -> one nibble left over  
              pSrc = pDataSrc->Read1Byte();  
              *pBuf = (*(pSrc))>>4;  
              pBuf++;  
            }  
            // Word alignment at end of literal packet.  
            if ((RunLength + bOdd) & 1) pDataSrc->Skip(1);  
        }  
      }  
      else  
      { // Encoded packet:  
        // RunLength 4 bpp pixels with 2 alternating  
        // values.  
        pSrc = pDataSrc->Read1Byte();  
        SrcByte = *pSrc;  
        for (int i=0; i<RunLength/2; i++)  
        {  
          decode2Nibbles (pBuf, SrcByte);  
          pBuf += 2;  
        }  
        if (RunLength & 1)  
        {  
          *pBuf = (*(pSrc))>>4;  
          pBuf++;  
        }  
      }  
    }  
    pDest = pLineArray[pBmp->GetHeight()-y-1];  
    memcpy (pDest, pLineBuf, XSize);  
  }  
  delete [] pLineBuf;  
}  

Note that the for-loop inside the ‘Encoded packet’ branch decode/copy two nibbles to pBuf every time, executing this RunLength/2 times. And because there is no check about the pBuf’s length before advancing the pointer two positions, a heap overflow (pBuf based) may arise.

The pBuf is initialized to pLineBuf wich is a fresh allocated buffer of size XSize*4+28, being XSize the BMP’s width (controlled value). So we can allocate almost any buffer size and then write and overflow it with words like 0x0X0Y (X,Y controlled nibble values).

Exploitation of the above problem will lead to the execution of arbitrary code on the client machine with the privileges of the user running the Sketchup.

Sumary and exploit

9.3 High

CVSS2

Access Vector

NETWORK

Access Complexity

MEDIUM

Authentication

NONE

Confidentiality Impact

COMPLETE

Integrity Impact

COMPLETE

Availability Impact

COMPLETE

AV:N/AC:M/Au:N/C:C/I:C/A:C

0.745 High

EPSS

Percentile

97.8%

Related for BINAMUSE:583CC7EB3E354FF46BCE222F3B7FA8BE