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>) {