Like many clamav users, I have found clamav to not be effective against the latest crop of password zip viruses.
I have made a rudimentary patch (clean patch) against clamav 0.67 to mark all zip files containing password-protected (and hence unscannable) files as a virus type "SuspectEncrypted.Zip." This way I can simply quarantine all such passworded zip files, along with normal viruses. I know of no other way for clamav to catch this virus currently. (In fact it didn't even catch one of them using fingerprinters.) I see this patch as a stop-gap measure until ClamAV has a workable mechanism for dealing with viruses passing themselves around as passworded zip files. Anyone who is interested can apply this patch. Hopefully clamav will have an official method of dealing with this new pest. The patch is very short and simple. It merely patches zzlib to pass the header flags field out, and then scanners.c then looks at bits 0 and 6 to check the encrypted file status (per file) and if they are set, then the zip file is marked as "SuspectedEncrypted.Zip" and you can deal with it accordingly. I hope it is useful to some people. Apply it to the base of the clamav source code tree: cat /path/to/clamav-pwdzip-0.67.patch | patch -p1 Michael -- Michael L Torrie <[EMAIL PROTECTED]>
--- clamav-0.67.orig/libclamav/scanners.c 2004-02-15 05:10:34.000000000 -0700 +++ clamav-0.67/libclamav/scanners.c 2004-03-03 11:43:49.045475480 -0700 @@ -317,7 +317,7 @@ break; } - cli_dbgmsg("Zip -> %s, compressed: %d, normal: %d.\n", zdirent.d_name, zdirent.d_csize, zdirent.st_size); + cli_dbgmsg("Zip -> %s, compressed: %d, normal: %d, encrypted flag: %d.\n", zdirent.d_name, zdirent.d_csize, zdirent.st_size,zdirent.d_flags); if(limits && limits->maxratio > 0 && source.st_size && (zdirent.st_size / source.st_size) >= limits->maxratio) { *virname = "Oversized.Zip"; @@ -341,6 +341,13 @@ break; } + if(zdirent.d_flags & (1 | 2^6) ) { + cli_dbgmsg("Encrypted files found in Zip archive.\n"); + *virname = "SuspectedEncrypted.Zip"; + ret = CL_VIRUS; + break; + } + if(limits) { if(limits->maxfilesize && (zdirent.st_size > limits->maxfilesize)) { cli_dbgmsg("Zip -> %s: Size exceeded (%d, max: %d)\n", zdirent.d_name, zdirent.st_size, limits->maxfilesize); --- clamav-0.67.orig/libclamav/zziplib/zzip-dir.c 2004-02-15 04:44:12.000000000 -0700 +++ clamav-0.67/libclamav/zziplib/zzip-dir.c 2004-03-03 11:34:01.462801624 -0700 @@ -89,6 +89,7 @@ return -1; dir->dirent.d_csize = dir->dirent.st_size = st.st_size; + dir->dirent.d_flags = 0; if (st.st_mode) { @@ -140,6 +141,8 @@ dir->dirent.d_csize = dir->hdr->d_csize; dir->dirent.st_size = dir->hdr->d_usize; + dir->dirent.d_flags = dir->hdr->d_flags; + if (! dir->hdr->d_reclen) dir->hdr = 0; else dir->hdr = (struct zzip_dir_hdr *) ((char *)dir->hdr + dir->hdr->d_reclen); --- clamav-0.67.orig/libclamav/zziplib/zzip.h 2004-02-15 04:44:12.000000000 -0700 +++ clamav-0.67/libclamav/zziplib/zzip.h 2004-03-03 11:34:53.082954168 -0700 @@ -34,6 +34,7 @@ uint16_t d_reclen; /* next dir_hdr structure offset */ uint16_t d_namlen; /* explicit namelen of d_name */ uint8_t d_compr; /* the compression type, 0 = store, 8 = inflate */ + uint16_t d_flags; /* general purpose flags */ char d_name[1]; /* the actual name of the entry, may contain DIRSEPs */ }; #define _ZZIP_DIRENT_HAVE_D_NAMLEN --- clamav-0.67.orig/libclamav/zziplib/zziplib.h 2004-02-15 04:44:12.000000000 -0700 +++ clamav-0.67/libclamav/zziplib/zziplib.h 2004-03-03 09:01:54.962240600 -0700 @@ -91,6 +91,7 @@ int d_compr; /* compression method */ int d_csize; /* compressed size */ int st_size; /* file size / decompressed size */ + unsigned short d_flags; /* general purpose flags */ char * d_name; /* file name / strdupped name */ }; --- clamav-0.67.orig/libclamav/zziplib/zzip-zip.c 2004-02-15 04:44:12.000000000 -0700 +++ clamav-0.67/libclamav/zziplib/zzip-zip.c 2004-03-03 11:34:43.491412304 -0700 @@ -365,6 +365,7 @@ { register struct zzip_root_dirent * d; uint16_t u_extras, u_comment, u_namlen; + uint16_t u_flags; if (fd_map) { d = (void*)(fd_map+fd_gap+offset); } /* fd_map+fd_gap==u_rootseek */ @@ -387,6 +388,7 @@ u_extras = ZZIP_GET16(d->z_extras); u_comment = ZZIP_GET16(d->z_comment); u_namlen = ZZIP_GET16(d->z_namlen); + u_flags = ZZIP_GET16(d->z_flags); //HINT5("offset=0x%lx, size %ld, dirent *%p, hdr %p\n", // offset+u_rootseek, (long)u_rootsize, d, hdr); @@ -402,6 +404,8 @@ hdr->d_usize = ZZIP_GET32(d->z_usize); hdr->d_off = ZZIP_GET32(d->z_off); hdr->d_compr = (uint8_t)ZZIP_GET16(d->z_compr); + hdr->d_flags = u_flags; + /* bull: hdr->d_compr is uint8_t * if (hdr->d_compr > 255) hdr->d_compr = 255; */ @@ -702,6 +706,7 @@ d->d_csize = dir->hdr->d_csize; d->st_size = dir->hdr->d_usize; d->d_name = dir->hdr->d_name; + d->d_flags = dir->hdr->d_flags; if (! dir->hdr->d_reclen) { dir->hdr = 0; }