Bugtraq mailing list archives

Re: about zlib vulnerability - Microsoft products


From: "Forrest J Cavalier III" <forrest () mibsoftware com>
Date: Fri, 15 Mar 2002 23:16:30 -0500


Microsoft is also using zlib in a couple of products.  MS Office, IE, Front
Page, DirectX (dunno what versions yet), MSN Messenger, and the next gen GDI
on XP.  Vulnerability? : "Microsoft representatives said that the software
giant's security response team is investigating the zlib flaw and that some
Microsoft applications use code from that compression library. However, the
team hasn't yet determined which applications use the library and whether
those applications are vulnerable." (From Cnet's News.Com article -
http://news.com.com/2100-1001-860328.html )


The following C program scans files for the cplens table (used for
inflate.)  

I expect the code below is portable.  It was tested on Windows.

It might run faster than the perl script posted earlier.  (I
suppose it risks more false positives too.)  

Caveats: 
-------
The appearance of the pattern is not proof of zlib
and even if it is zlib, the malloc implementation
may prevent exploits.

Preliminary Results on Windows
------------------------------
When run on Windows SYSTEMDIR programs and DLLs on my
machine, it reports a match in a number of items I expected
(installers, uninstallers, png DLLs,) and some I did not
expect (like URLMON.DLL, version.dll)  

QuickTime.qts also reports a match.  (Makes sense there
is an inflation routine in QuickTime)  The file extension
indicates that searching only .dll and .exe may not be
adequate.

Forrest Cavalier
Mib Software


/* NO WARRANTY.  Forrest Cavalier is the original author. (c) 2002
   Permission granted for copying, modification, and use,
   with or without fee, provided that this notice is preserved.
 */
#include <stdio.h>
#include <memory.h>

/*  This table appears in zlib/inftrees.c, we search for
    just the pattern 17, 19, 23.  Code below should work for
    big and little endian platforms 16, 32, and 64 bit
    integer sizes.
 */
const int cplens[31] = { /* Copy lengths for literal codes 257..285 */
        3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
        35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};

int main(int argc, char **argv)
{
#define CBPATTERN 64
  FILE *f;
  char buf[8192+CBPATTERN];
  int cnt;
  const char *ptr;
  int ind;
  int wsize;

  if (argc != 2) {
      exit(1);
  }

  f = fopen(argv[1],"rb");
  if (!f) {
      exit(1);
  }

  while(1) {
      cnt = fread(buf+CBPATTERN,1,sizeof(buf)-CBPATTERN,f);
      if (cnt <= 0) {
          break;
      }
      ptr = buf;
      while(1) {
          ptr = memchr(ptr,'\x11',buf+cnt+CBPATTERN-ptr);
          if (!ptr || (ptr+CBPATTERN > buf+cnt+CBPATTERN)) {
              /* Not found, or tests will pass end of buffer */
              break;
          }
          /* Look for pattern from middle of table */
          for(wsize = 2;wsize <= 8;wsize *= 2) {
            if (ptr &&
                (ptr[wsize] == '\x13')&&
                (ptr[wsize*2] == '\x17')&&
                (ptr[wsize*3] == '\x1b')) {
                break;
            }
          }
          if (wsize <= 8) {
              ind = 1;
              while(ind < wsize) { /* Ensure intervening bytes are zero */
                  if (ptr[ind]||
                      ptr[wsize+ind]||
                      ptr[wsize*2+ind]||
                      ptr[wsize*3+ind]) {
                      break; /* Non-zero. */
                  }
                  ind++;
              }
              if (ind == wsize) {
                  printf("Found cplens pattern in %s\n",argv[1]);
              }
          }
          ptr++;
      }
      /* Copy end of buffer down, to catch patterns which
         go over a read boundary
       */
      memmove(buf,buf+cnt,CBPATTERN);
  }
  fclose(f);
  return 0;
}


Current thread: