#!/usr/bin/perl ### Copyright (C) 2004 Yves Agostini ### This program is free software; you can redistribute it and/or modify ### it under the terms of the GNU General Public License as published by ### the Free Software Foundation; either version 2 of the License, or ### (at your option) any later version. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### Contact the copyright holder for commercial licensing terms ### if you wish to incorporate this code into non-GPL software. ### # # # $Id: testzip.pl, v1.01 2004-03-10 # # Perl plugin for "the great" John D. Hardin impsec sanitizer # http://www.impsec.org/email-tools/procmail-security.html # # List files in zip attachement, return DISCARD if one file is include in # $POISONED_EXECUTABLES or return MANGLE if there is only files like # *.exe, *.scr, ... # # CHANGES # v1.0 : First release # V1.01 : Only changes in procmailrc # - add "$MANGLE_EXTENSIONS|zip" # - remove attachement test # # NOTES # Requires perl, mktemp, MIME::Explode, unzip # # INVOCATION # # With a procmail rule insert before # INCLUDERC=/etc/procmail/html-trap.procmail # # Procmail rule : # ----------uncomment-and--cut----------- # :0 # * < 600000 # * ^Content-Type:.*multipart/mixed; # { # RES= # # :0 B # * ^Content-Transfer-Encoding: base64 # * 9876543210^1 ^Content-(Type|Disposition):.*name *= *"?[-_0-9A-Za-z]+\.zip"? # { # :0 HB W # RES=|/etc/procmail/testzip.pl # # :0 hfi # * RES ?? ^DISCARD$ # | formail -A "X-Content-Security: [$HOST] NOTIFY" \ # -A "X-Content-Security: [$HOST] DISCARD" \ # -A "X-Content-Security: [$HOST] REPORT: Trapped poisoned document in zip attachement" # # :0 # * RES ?? ^MANGLE$ # { # MANGLE_EXTENSIONS="$MANGLE_EXTENSIONS|zip" # } # # } #} # -------------cut-------------- # # Use CPAN to install MIME::Explode # perl -MCPAN -e 'install MIME::Explode' # apt-get install unzip (for debian) #use strict; use MIME::Explode; my $destd = `mktemp -d /tmp/zipmailchk.XXXXXX`; chomp($destd); my $explode = MIME::Explode->new( output_dir => $destd, mkdir => 0755, decode_subject => 0, check_content_type => 0, exclude_types => ["image/gif", "image/jpeg", "image/png","text/plain","text/html"], ); my $headers = $explode->parse(\*STDIN); my @res=`cd $destd; ls *.zip 2>/dev/null`; my @files; foreach my $l (@res) { my @unzip=`unzip -l $destd/$l`; foreach my $lunzip (@unzip){ my ($a,$b,$c,$d,$e,$f)=split(' ',$lunzip); push (@files,"$d$e$f") if ($d && $d=~/\.(\w+)$/g); } } #print @files; `/bin/rm -rf $destd`; my $RET; foreach my $filen (@files) { if (open(POISONED, $ENV{"POISONED_EXECUTABLES"})) { my $psn_spec=""; warn " Checking document \"$filen\" in zip attachement for poisoning.\n"; while (chomp($psn_spec = )) { $psn_spec =~ s/^\s+//g; $psn_spec =~ s/\s.*$//g; next unless $psn_spec; $psn_spec =~ s/([^\\])\./$1\\./g; $psn_spec =~ s/\*/.*/g; $psn_spec =~ s/([^\(])\?/$1./g; $psn_spec .= "(\\?=)?\$" unless $psn_spec =~ /\$/; warn " Checking against \"$psn_spec\"\n" if $ENV{"DEBUG"}; if ($filen =~ /^${psn_spec}/i && $psn_spec!~/^\?\\\.exe/) { warn " Trapped poisoned document \"$filen\" in zip attachement.\n"; $RET= ($psn_spec=~/^\.\*\\\.\w/g) ? "MANGLE":"DISCARD"; last if ($RET eq "DISCARD"); } } close(POISONED); } } print "$RET";