Re: about zlib vulnerability - Microsoft products

From: Forrest J Cavalier III (forrestat_private)
Date: Fri Mar 15 2002 - 20:16:30 PST

  • Next message: Jonathan A. Zdziarski: "Buffer Overflow in Geck/Netscape 5.0/6.0?"

    > 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;
    }
    



    This archive was generated by hypermail 2b30 : Sun Mar 17 2002 - 09:19:20 PST