Hi, Playing with sparse files I noticed it's easy to create a tiny 2 megabytes zip file that would unpack into a whopping 2 gigabytes file.
If your qmail-scanner is configured to unpack the zip files before scanning (force_unzip=1), then unpacking these special zip files will cause heavy disk I/O, CPU usage and might take up all your disk space. Clamav has a builtin protection against these type of archive. So, if you use qmail-scanner with Clamav as the virus scanner, you can disable unzip support in qmail-scanner. But, if you really need to unpack the zip files in qmail-scanner, then here is a patch that allows you to check the compression ratio of the zip files. Any zip file with a compression ratio greater than `$max_zip_compression_ratio' will be placed in quarantine. Regards, Jérôme -- <ESC>:r $HOME/.signature<CR>
--- qmail-scanner-queue.template.orig 2004-08-20 22:09:25.000000000 +0200 +++ qmail-scanner-queue.template 2004-08-21 13:06:13.000000000 +0200 @@ -243,6 +243,11 @@ #McAfee's doesn't! my $force_unzip=FORCE_UNZIP; +# Specify the maximum zip compression ratio (0 to 100). +# This is to prevent potential Denial Of Service with specially crafted zip +# Set it to 0 to disable oversized zip file checking. +my $max_zip_compression_ratio=90 + #Descriptive string to use in generated Email my $destring="virus"; @@ -1994,6 +1999,7 @@ sub unzip_file { my($zipfile)[EMAIL PROTECTED]; my ($MAYBEZIP,$ztmp,$zfile,$zline,$zsize,$zip_status,$passwd_protected_zip); + my ($status_line,$zip_ratio); &debug("u_f: potential zip archive file found ($zipfile)."); &debug ("u_f: it is possibly a zip file, run unzip $unzip_options -t $ENV{'TMPDIR'}/$zipfile"); @@ -2019,6 +2025,22 @@ $description .= "\n---perlscanner results ---\n$destring '$quarantine_description' found in file $ENV{'TMPDIR'}/$zipfile"; } else { if ($force_unzip) { + if ($max_zip_compression_ratio) { + &debug("u_f: run $unzip_binary $unzip_options -lv $ENV{'TMPDIR'}/$zipfile 2>&1"); + open(ZIPPED,"$unzip_binary $unzip_options -lv $ENV{'TMPDIR'}/$zipfile 2>&1|")||&error_condition("u_f: cannot open $ENV{'TMPDIR'}/$zipfile - $!"); + $status_line = $_ while(<ZIPPED>); + close(ZIPPED); + ($zip_ratio) = ($status_line =~ m/(\d+)%/); + if (defined $zip_ratio and $zip_ratio > $max_zip_compression_ratio) { + #Quarantine it! + $quarantine_description="Oversized zip files ($zipfile) - potential denial of service"; + &debug("u_f: $quarantine_description"); + $destring='problem'; + $quarantine_event="Policy:Oversized_ZIP"; + $description .= "\n---perlscanner results ---\n$destring '$quarantine_description' found in file $ENV{'TMPDIR'}/$zipfile"; + return; + } + } &debug("u_f: run $unzip_binary $unzip_options $ENV{'TMPDIR'}/$zipfile 2>&1"); open(ZIPPED,"$unzip_binary $unzip_options $ENV{'TMPDIR'}/$zipfile 2>&1|")||&error_condition("u_f: cannot open $ENV{'TMPDIR'}/$zipfile - $!"); while (<ZIPPED>) {