7z and other archive formats support
Danny
danny at tweegy.nl
Sun Aug 9 11:39:22 UTC 2015
Op 1-8-2015 om 4:09 schreef Jerry Benton:
> I’d have to look into it. I personally have not tested it.
>
> -
> Jerry Benton
> www.mailborder.com
>
>
>
>> On Jul 31, 2015, at 6:20 PM, Danny <danny at tweegy.nl> wrote:
>>
>> Hello,
>>
>> I was wondering if MailScanner has 7z (binary) support or are the devs working on this or is it on the roadmap?
>> It would be nice to be able to look inside 7z, arj, cpio etc.
>>
>> Regards,
>> Danny
>>
>>
>>
>> --
>> MailScanner mailing list
>> mailscanner at lists.mailscanner.info
>> http://lists.mailscanner.info/listinfo/mailscanner
>>
>
>
>
Hello Jerry and others,
I don't know whether this is the place to post any patches, but I wrote
a patch adding 7z and other archives support by using the 7z binary,
which is included in most distributions. Also I added support to scan
pdf's for suspicious content by using PDFid. (also external tool)
Language and subject modification support for pdf scanning isn't
included (yet).
2 patch files attached to the message, one for MailScanner.conf and one
for the modules, ConfigDefs.pl, Message.pm and SweepContent.pm
I found the patches useful for my setup, feel free to use them.
Regards,
Danny
-------------- next part --------------
diff -ur MailScanner.orig/ConfigDefs.pl MailScanner/ConfigDefs.pl
--- MailScanner.orig/ConfigDefs.pl 2015-05-03 16:04:05.000000000 +0200
+++ MailScanner/ConfigDefs.pl 2015-08-09 11:17:49.133813987 +0200
@@ -350,6 +350,8 @@
MCPSpamAssassinTimeout 10
TNEFTimeout 120
UnrarTimeout 50
+Un7zipTimeout 50
+PDFiDTimeout 50
WhitelistMaxRecips 20
# For Qmail users
qmailhashdirectorynumber 23
@@ -405,6 +407,8 @@
MCPSpamAssassinInstallPrefix /etc/MailScanner/mcp
TNEFExpander /usr/bin/tnef --maxsize=100000000
UnrarCommand /usr/bin/unrar
+Un7zipCommand /usr/bin/7z
+PDFiDCommand /usr/local/bin/pdfid.py
VirusScanners auto # Space-separated list
WorkUser
WorkGroup
@@ -490,6 +494,9 @@
WarnSizeSenders 0 no 0 yes 1
WarnOtherSenders 1 no 0 yes 1
# JKF 19/12/2007 WarnPasswordSenders 1 no 0 yes 1
+ScanPDF 1 no 0 yes 1
+DeliverSuspiciousPDF 0 no 0 yes 1
+SuspiciousPDFModifySubject start no 0 yes 1 start start end end
[First,File]
DeletedContentMessage /etc/MailScanner/reports/en/deleted.content.message.txt
@@ -603,6 +610,7 @@
SizeSubjectText {Size}
unzipmembers *.txt *.ini *.log *.csv
unzipmimetype text/plain
+SuspiciousPDFSubjectText {Suspicious PDF?}
[All,YesNo]
AddEnvFrom 1 no 0 yes 1
diff -ur MailScanner.orig/Message.pm MailScanner/Message.pm
--- MailScanner.orig/Message.pm 2015-05-03 16:04:05.000000000 +0200
+++ MailScanner/Message.pm 2015-08-09 12:20:39.949883649 +0200
@@ -2660,8 +2660,9 @@
my($size, $level, $ziperror, $tarerror, $silentviruses, $noisyviruses);
my($allziperrors, $alltarerrors, $textlevel, $failisokay);
my($linenum, $foundheader, $prevline, $line, $position, $prevpos, $nextpos);
- my($cyclecounter, $rarerror, $create0files, $oleerror);
-
+ my($cyclecounter, $rarerror, $create0files, $oleerror, $sevenzerror);
+ my($filecommand, $PipeTimeOut, $memb, $use_unpacker);
+
$dir = new DirHandle;
$file = new FileHandle;
$level = 0; #-1;
@@ -2669,6 +2670,7 @@
$cyclecounter = 0;
$ziperror = 0;
$tarerror = 0;
+ $sevenzerror = 0;
# Do they only want encryption checking and nothing else?
my $onlycheckencryption;
@@ -2803,6 +2805,28 @@
#$level++;
next if $level > $maxlevels;
+ # Do a file (magic) on every file we run into and appoint an unpacker
+ $PipeTimeOut = MailScanner::Config::Value('filetimeout');
+ $filecommand = MailScanner::Config::Value('filecommand');
+ $use_unpacker = '';
+ if ($filecommand && -x $filecommand) { # check if we got support
+ $memb = SafePipe("$filecommand -b '$explodeinto/$part' 2>&1",
+ $PipeTimeOut);
+
+ if ($memb =~ /ERROR/) {
+ MailScanner::Log::WarnLog("File magic error (%s)", $memb);
+ } elsif ( ($memb =~ /^Zip archive/i) ) { # use zip unpacker
+ $use_unpacker = "zip";
+ } elsif ( ($memb =~ /^RAR archive/i) ) { # use (official) rar unpacker
+ $use_unpacker = "rar";
+ } elsif ( ($memb =~ /^(7-zip|arj|cpio|lha(.*)|xar|GNU tar|POSIX tar|ASCII cpio) archive/i) || # use 7zip unpacker
+ ($memb =~ /^(lzh|lzma|bzip2|gzip|xz) compressed/i) ||
+ ($memb =~ /^(RPM|Delta-RPM|Windows imaging|\# ISO|ISO)/i) ) {
+ $use_unpacker = "7z";
+ }
+ }
+ #MailScanner::Log::WarnLog("Unpack-engine (%s) file (%s)", $use_unpacker, $part);
+
# Find all the zip files
#print STDERR "Looking at $explodeinto/$part\n";
#next if MailScanner::Config::Value('filecommand', $this) eq "";
@@ -2828,7 +2852,8 @@
$failisokay;
#print STDERR "Found a zip or rar file\n" ;
$file->close, next unless MailScanner::Config::Value('findarchivesbycontent', $this) ||
- $part =~ /\.(tar\.g?z|taz|tgz|tz|zip|exe|rar|uu|uue|doc|xls|ppt|dot|xlt|pps)$/i;
+ $part =~ /\.(tar\.g?z|taz|tgz|tz|zip|exe|rar|uu|uue|doc|docx|xls|xlsx|ppt|pptx|dot|dotx|xlt|xltx|pps|ppsx)$/i;
+# $part =~ /\.(tar\.g?z|taz|tgz|tz|zip|exe|rar|uu|uue|doc|xls|ppt|dot|xlt|pps)$/i;
$foundnewfiles = 1;
#print STDERR "Unpacking $part at level $level\n";
@@ -2848,10 +2873,11 @@
$ziperror = $this->UnpackZip($part, $explodeinto, $allowpasswords,
$insistpasswords,
$onlycheckencryption, $create0files);
+ #MailScanner::Log::WarnLog("UnpackZip (%s) file (%s)", $ziperror, $part);
#print STDERR "* * * * * * * Unpackzip $part returned $ziperror\n";
# If unpacking as a zip failed, try it as a rar
$rarerror = "";
- if ($part =~ /\.rar$/i || $buffer eq "Rar!" or $buffer =~ /^MZ[P]?/) {
+ if ($part =~ /\.rar$/i || $use_unpacker eq "rar" || $buffer eq "Rar!") {
$rarerror = $this->UnpackRar($part, $explodeinto, $allowpasswords,
$insistpasswords,
$onlycheckencryption, $create0files);
@@ -2872,7 +2898,17 @@
$tarerror = 0 # $this->UnpackTar($part, $explodeinto, $allowpasswords)
if $ziperror || $part =~ /(tar\.g?z|tgz)$/i;
#print STDERR "In inner: \"$part\"\n";
- if ($ziperror eq "nonpassword" || $rarerror eq "nonpassword") {
+
+ if (
+ ($use_unpacker eq "7z") ||
+ ($part =~ /\.(001|7z|arj|bz2|bzip2|cab|cpio|deb|dmg|fat|gz|gzip|hfs|iso|jar|lha|lzh|lzma)$/) ||
+ ($part =~ /\.(ntfs|rpm|squashfs|swm|tar|taz|tbz|tbz2|tgz|tpz|txz|vhd|wim|xar|xz|z)$/) ) {
+ $sevenzerror = $this->Unpack7zip($part, $explodeinto, $allowpasswords,
+ $insistpasswords,
+ $onlycheckencryption, $create0files);
+ }
+
+ if ($ziperror eq "nonpassword" || $rarerror eq "nonpassword" || $sevenzerror eq "nonpassword" ) {
# Trim off leading type indicator character for logging.
my $f = substr($part,1);
MailScanner::Log::WarnLog("Non-password-protected archive (%s) in %s",
@@ -2886,7 +2922,7 @@
$this->{cantdisinfect} = 1; # Don't even think about disinfecting this!
$this->{silent}=1 if $silentviruses =~ / Zip-NonPassword | All-Viruses /i;
$this->{noisy} =1 if $noisyviruses =~ / Zip-NonPassword /i;
- } elsif ($ziperror eq "password" || $rarerror eq "password") {
+ } elsif ($ziperror eq "password" || $rarerror eq "password" || $sevenzerror eq "password") {
# Trim off leading type indicator character for logging.
my $f = substr($part,1);
MailScanner::Log::WarnLog("Password-protected archive (%s) in %s",
@@ -2900,7 +2936,7 @@
$this->{cantdisinfect} = 1; # Don't even think about disinfecting this!
$this->{silent}=1 if $silentviruses =~ / Zip-Password | All-Viruses /i;
$this->{noisy} =1 if $noisyviruses =~ / Zip-Password /i;
- } elsif ($ziperror && $tarerror && $rarerror && !$failisokay) {
+ } elsif ($ziperror && ($tarerror || $rarerror || $sevenzerror) && !$failisokay) {
# Trim off leading type indicator character for logging.
my $f = substr($part,1);
MailScanner::Log::WarnLog("Unreadable archive (%s) in %s",
@@ -3248,6 +3284,7 @@
while(<$Kid>) {
$Str .= $_;
#print STDERR "SafePipe : Processing line \"$_\"\n";
+ #MailScanner::Log::WarnLog("SafePipe : Processing line \"$_\" \n");
}
#MailScanner::Log::DebugLog("SafePipe : Completed $Cmd");
@@ -3325,6 +3362,217 @@
}
+# Unpack a 7za file into the named directory.
+# Return 1 if an error occurred, else 0.
+# Return 0 on success.
+# Return "password" if a member was password-protected.
+# Very much like UnpackZip except it uses the external "7z" command.
+sub Unpack7zip {
+ my($this, $zipname, $explodeinto, $allowpasswords, $insistpasswords, $onlycheckencryption, $touchfiles) = @_;
+
+ my($zip, @members, $member, $name, $fh, $safename, $memb, $check, $junk,
+ $unzip, $unrar, $IsEncrypted, $PipeTimeOut, $PipeReturn,$NameTwo, $HasErrors,
+ $member2, $Stuff, $BeginInfo, $EndInfo, $ParseLine, $what, $nopathname);
+
+ # Timeout value for unrar is currently the same as that of the file
+ # command + 20. Julian, when you add the filetimeout to the config file
+ # perhaps you should think about adding a maxcommandexecutetime setting
+ # as well
+ $PipeTimeOut = MailScanner::Config::Value('un7ziptimeout');
+ $unzip = MailScanner::Config::Value('un7zipcommand');
+ return 1 unless $unzip && -x $unzip;
+
+ #MailScanner::Log::WarnLog("7ZipUnpacker: %s", $zipname);
+
+ # This part lists the archive contents and makes the list of
+ # file names within. "This is a list verbose option"
+ #$memb = SafePipe("$unrar v -p- '$explodeinto/$zipname' 2>&1",
+ # $PipeTimeOut);
+ $memb = SafePipe("$unzip l '$explodeinto/$zipname' 2>&1",
+ $PipeTimeOut);
+
+ if ($memb =~ /^error/i) {
+ MailScanner::Log::WarnLog("7ZipUnpacker: (%s)", $memb);
+ $HasErrors = 1;
+ }
+ #MailScanner::Log::WarnLog("7z output: %s", $memb);
+
+ $junk = "";
+ $Stuff = "";
+ $BeginInfo = 0;
+ $EndInfo = 0;
+ $ParseLine = 1;
+ $memb =~ s/\r//gs;
+ my @test = split /\n/, $memb;
+ $memb = '';
+
+ # Have to parse the output from the 'v' command and parse the information
+ # between the ----------------------------- lines
+ foreach $what (@test) {
+ #print STDERR "Processing \"$what\"\n";
+ #MailScanner::Log::WarnLog("7z what: %s", $what);
+
+ # Have we already hit the beginng and now find another ------ string?
+ # If so then we are at the end
+ $EndInfo = 1 if $what =~ /-{18,}$/ && $BeginInfo;
+
+ # if we are after the begning but haven't reached the end,
+ # then process this line
+ if ($BeginInfo && !$EndInfo) {
+ # MailScanner::Log::WarnLog("7z what: %s", $what);
+ # If we are on line one then it's the file name with full path
+ # otherwise we are on the info line containing the attributes
+ $what =~ s/ +/ /g;
+ my (@Zarray ) = split /\s/, $what;
+ my $Zname = pop @Zarray; # this is the most important value, other values are nice to have but this one we must have
+ my $Zdate = $Zarray[0];
+ my $Ztime = $Zarray[1];
+ my $Zattr = $Zarray[2];
+ #my $Zsize = $Zarray[3];
+ #my $ZCsize = $Zarray[4];
+
+ #MailScanner::Log::WarnLog("7z-members: [%s] [%s] [%s] [%s] [%s] [%s]", $Zdate, $Ztime, $Zattr, $Zsize, $ZCsize, $Zname);
+
+ $memb .= "$Zname\n" if $Zattr !~ /^d|^D/;
+ }
+
+ # If we have a line full of ---- and $BeginInfo is not set then
+ # we are at the first and we need to set $BeginInfo so next pass
+ # begins processing file information
+ if ($what =~ /-{18,}$/ && ! $BeginInfo) {
+ $BeginInfo = 1;
+ }
+ }
+
+
+ # Remove returns from the output string, exit if the archive is empty
+ # or the output is empty
+
+ $memb =~ s/\r//gs;
+ return 1 if $memb ne '' &&
+ $memb =~ /(No files to extract|^COMMAND_TIMED_OUT$)/si;
+
+ return 0 if $memb eq '';
+ #MailScanner::Log::DebugLog("Unrar : Archive Testing Completed On : %s",
+ # $memb);
+
+ @members = split /\n/, $memb;
+ $fh = new FileHandle;
+
+ foreach $member2 (@members) {
+ $IsEncrypted = 0;
+ $HasErrors = 0;
+ #MailScanner::Log::InfoLog("Checking member %s",$member2);
+ # Test the current file name to see if it's password protected
+ # and capture the output. If the command times out, then return
+
+ next if $member2 eq "";
+ $member = quotemeta $member2;
+ #print STDERR "Member is ***$member***\n";
+ #MailScanner::Log::WarnLog("Un7zip: member %s",$member );
+
+ $check = SafePipe(
+ "$unzip -y t '$explodeinto/$zipname' $member 2>&1",
+ $PipeTimeOut);
+ #print STDERR "Point 1\n";
+ return 1 if $check =~ /^COMMAND_TIMED_OUT$/;
+
+ # Check for any error with this file. Format is FileName - Error string
+ if ($check =~ /$member\s+-\s/i){
+ MailScanner::Log::WarnLog("Un7zip Error in file: %s -> %s",
+ $zipname,$member);
+ $HasErrors = 1;
+ }
+
+ $check =~ s/\n/:/gsi;
+ #MailScanner::Log::WarnLog("Got : %s", $check);
+
+ # If we get the string Encrypted then we have found a password
+ # protected archive and we handle it the same as zips are handled
+
+ if ($check =~ /\bEnter password(.*)\bWrong password/s) {
+ $IsEncrypted = 1;
+ MailScanner::Log::WarnLog("Password Protected archive Found");
+ #print STDERR "Checking member " . $member . "\n";
+ #print STDERR "******** Encryption = " . $IsEncrypted . "\n";
+ return "password" if !$allowpasswords && $IsEncrypted;
+ } else {
+ if ($insistpasswords) {
+ MailScanner::Log::WarnLog("Non-Password Protected archive Found");
+ return "nonpassword";
+ }
+ }
+
+
+ # If they don't want to extract, but only check for encryption,
+ # then skip the rest of this as we don't actually want the files
+ # checked against the file name/type rules
+
+ next if $onlycheckencryption;
+
+ $name = $member2;
+ #print STDERR "UnPackRar : Making Safe Name from $name\n";
+
+ # There is no facility to change the output name for a rar file
+ # but we can rename rename the files inside the archive
+ # prefer to use $NameTwo because there is no path attached
+ # $safename is guaranteed not to exist, but NameTwo gives us the
+ # filename without any directory information, which we use later.
+ $nopathname = $name;
+ $nopathname =~ s/^.*\///;
+ $safename = $this->MakeNameSafe('r'.$nopathname,$explodeinto);
+ $NameTwo = $safename;
+ $NameTwo = $1 if $NameTwo =~ /([^\/]+)$/;
+ #MailScanner::Log::InfoLog("UnPackRar: Member : %s", $member);
+ #print STDERR "UnPackRar : Safe Name is $safename\n";
+
+ #MailScanner::Log::InfoLog("UnPackRar: SafeName : %s", $safename);
+ $this->{file2parent}{$name} = $zipname;
+ $this->{file2parent}{$safename} = $zipname;
+ $this->{file2safefile}{$name} = $safename;
+ $this->{safefile2file}{$safename} = $name;
+ #print STDERR "Archive member \"$name\" is now \"$safename\"\n";
+
+ #$this->{file2entity}{$name} = $this->{entity};
+ # JKF 20090505 Don't do this: $this->{file2safefile}{$name} = $zipname;
+ #$this->{safefile2file}{$safename} = $zipname;
+
+ $safename = "$explodeinto/$safename";
+
+ $PipeReturn = '';
+ $? = 0;
+ if (!$IsEncrypted && !$HasErrors) {
+ #print STDERR "Expanding ***$member***\ninto ***$NameTwo***\n";
+ $PipeReturn = SafePipe(
+ "$unzip e -y -so '$explodeinto/$zipname' $member > \"$NameTwo\"",
+ $PipeTimeOut);
+ unless ("$?" == 0 && $PipeReturn ne 'COMMAND_TIMED_OUT'){
+ # The rename operation failed!, so skip the extraction of a
+ # potentially bad file name.
+ # JKF Temporary testing code
+ #MailScanner::Log::WarnLog("UnPackRar: RC: %s PipeReturn : ",$?,$PipeReturn);
+ MailScanner::Log::WarnLog("7zipUnpacker: Could not rename or use " .
+ "safe name in Extract, NOT Unpacking file %s", $safename);
+ next;
+ }
+ #MailScanner::Log::InfoLog("7zipUnacker: Done...., got %d and %s for %s", $?, $PipeReturn, $safename);
+ }
+ #MailScanner::Log::WarnLog("RC = %s : Encrypt = %s : PipeReturn = %s",
+ # $?,$IsEncrypted,$PipeReturn );
+ unless ("$?" == 0 && !$HasErrors && !$IsEncrypted &&
+ $PipeReturn ne 'COMMAND_TIMED_OUT') {
+
+ # If we got an error, or this file is encrypted create a zero-length
+ # file so the filename tests will still work.
+ MailScanner::Log::WarnLog("7zipUnpacker : Encrypted Or Extract Error Creating" .
+ " 0 length %s",$NameTwo);
+ $touchfiles && $fh->open(">$safename") && $fh->close();
+ }
+ }
+ return 0;
+}
+
+
# Unpack a zip file into the named directory.
# Return 1 if an error occurred, else 0.
# Return 0 on success.
diff -ur MailScanner.orig/SweepContent.pm MailScanner/SweepContent.pm
--- MailScanner.orig/SweepContent.pm 2015-05-03 16:04:05.000000000 +0200
+++ MailScanner/SweepContent.pm 2015-08-09 12:14:33.641879518 +0200
@@ -140,6 +140,10 @@
# Check all the files for the attachment-size limit
$counter += CheckAttachmentSizes($message, $id);
+ # Check PDF's for any suspicious content
+ if (MailScanner::Config::Value('scanpdf')) {
+ $counter += CheckPDF($message, $id);
+ }
# Search for Microsoft-specific attacks
# Disallow both by default. Allow them only if all addresses agree.
my $iframevalue = MailScanner::Config::Value('allowiframetags', $message);
@@ -336,6 +340,98 @@
return $counter;
}
+# Danny: added scanning of PDF's for suspicious content using PDFiD
+# more information at http://blog.didierstevens.com/programs/pdf-tools/
+sub CheckPDF {
+ my($message, $id) = @_;
+
+ my($BaseDir, $basefh, $safename, $maxsize, $attachsize, $tnefname);
+ my($unsafename, $counter, $minsize, $attachentity);
+
+ my ($PDFiDPipeTimeOut, $PDFiDcommand, $FilePipeTimeOut, $filecommand, $memb);
+
+ # return if we don't want pdf scanning
+ return 0 unless (MailScanner::Config::Value('scanpdf'));
+
+ $PDFiDPipeTimeOut = MailScanner::Config::Value('pdfidtimeout');
+ $PDFiDcommand = MailScanner::Config::Value('pdfidcommand');
+
+ # return if pdfif.py doesn't exists or it isn't executable
+ return 1 unless ($PDFiDcommand && -x $PDFiDcommand);
+
+ $FilePipeTimeOut = MailScanner::Config::Value('filetimeout');
+ $filecommand = MailScanner::Config::Value('filecommand');
+
+ # Get into the directory containing all the attachments
+ $BaseDir = $global::MS->{work}->{dir} . "/$id";
+ chdir $BaseDir or die "Cannot chdir to $BaseDir for file size checking, $!";
+
+ $basefh = new DirHandle;
+ $basefh->open('.')
+ or MailScanner::Log::DieLog("Could not open attachment dir %s, %s",
+ $BaseDir, $!);
+ $counter = 0;
+ while ($safename = $basefh->read()) {
+ next if $safename eq '.' || $safename eq '..';
+
+ #MailScanner::Log::WarnLog("Looping attachment (%s/%s)", $BaseDir, $safename);
+
+ if ($filecommand && -x $filecommand) {
+ $memb = MailScanner::Message::SafePipe("$filecommand -b '$BaseDir/$safename' 2>&1", # re-use SafePipe from Message.pm
+ $FilePipeTimeOut);
+
+ if ($memb =~ /ERROR/) {
+ MailScanner::Log::WarnLog("File magic error (%s)", $memb);
+ } elsif ( ($memb =~ /^PDF document/i || $safename =~ /\.pdf$/i) ) {
+ MailScanner::Log::WarnLog("Checking PDF for malicious content (%s/%s)", $BaseDir, $safename);
+
+ if ($PDFiDcommand && -x $PDFiDcommand) {
+ $memb = MailScanner::Message::SafePipe("$PDFiDcommand -s '$BaseDir/$safename' 2>&1", # re-use SafePipe from Message.pm
+ $PDFiDPipeTimeOut);
+ my $orig_memb = $memb;
+ $memb =~ s/\r//g;
+ $memb =~ s/\n/ /g;
+ my $remove = 0;
+ if ($memb =~ /Traceback|Not a PDF/i) {
+ MailScanner::Log::WarnLog("PDFiD scan error (%s)", $memb);
+
+ } elsif ( $memb =~ /PDF Header/i ) {
+ #MailScanner::Log::WarnLog("PDFiD: result (%s)", $orig_memb);
+ my $score = 0;
+ my (@string_array) = split /\n/,$orig_memb;
+ shift @string_array; # remove fullpath/filename
+ foreach my $string (@string_array)
+ {
+ $string =~ s/ +/ /g;
+ my ($dummy, $code, $number) = split / /,$string;
+ if ( (($code =~ /JS|JavaScript|AA|OpenAction|RichMedia|Launch/) && ($number !~ /0/)) || ($number =~ /\(.*\)/) ) {
+ $score += 10; # if any string matches and value is != 0 or we got some obfuscation add 10 to score
+ } elsif (($code =~ /EmbeddedFile|Encrypt|ObjStm|JBIG2Decode|XFA|Colors/) && ($number !~ /0/) ){
+ $score++; # if any string matches and value is != 0 add 1 to score
+ }
+ }
+ if ($score >= 2) {
+ $remove = 1;
+ }
+ } else {
+ MailScanner::Log::WarnLog("PDFiD: unknown and therefor suspicous result (%s)", $memb);
+ $remove = 1;
+ }
+ if ($remove && MailScanner::Config::Value('deliversuspiciouspdf', $message) eq 0) {
+ $message->{otherreports}{$safename} .=
+ "A PDF with suspicous content was found, these are often used by malware to exploit system vulnerabilities\n";
+ #MailScanner::Config::LanguageValue($message,'foundpdf') . "\n"; # todo add to language conf
+ $message->{othertypes}{$safename} .= "c";
+ $counter++;
+ $message->{otherinfected}++;
+ }
+ }
+ }
+ }
+ }
+ return $counter;
+}
+
# Walk the entire tree of a message, looking for any
-------------- next part --------------
--- MailScanner.conf.orig 2015-08-09 11:58:15.341860815 +0200
+++ MailScanner.conf 2015-08-09 12:03:17.273867373 +0200
@@ -457,6 +457,31 @@
# RAR archive (in seconds)
Unrar Timeout = 50
+# Used as unpacking engine for multiple archive formats
+Un7zip Command = /usr/bin/7z
+#
+Un7zip Timeout = 50
+
+
+# Used for string scanning a pdf for possible malicious content
+# http://blog.didierstevens.com/programs/pdf-tools/#pdfid
+PDFiD Command = /usr/local/bin/pdfid.py
+
+#
+PDFiD Timeout = 50
+
+# Enable pdf scanning using PDFiD
+Scan PDF = yes
+
+# Block and replace pdf if possible malicious content is detected
+Deliver Suspicious PDF = no
+
+# Todo: allow PDF but change Subject
+# Subject change only possible when Delivery of Suspicious PDFs is Yes
+#Suspicious PDF Modify Subject = start
+#Suspicious PDF Subject Text = {Suspicious PDF?}
+
+
# A few viruses store their infected data in UU-encoded files, to try to
# catch out virus scanners. This rarely succeeds at all.
# Setting this option to yes means that you can apply filename and filetype
More information about the MailScanner
mailing list