Hi list,
I instaled the procmail-sanitizer.tar.gz.. It's work very well and I am
blocking email with attach archives *.exe. So it's change the extensions of
another files like *.doc and put *$xxx-doc. How can Do to the procmail not
change the extensions of this files.
Thanks
my htm-trap.procmail
# Size LINEBUF dynamically to deal with excessively large headers
:0 H
* 20480^0
* 1^1 .
{
LINEBUF="$="
}
#---------------------------------------------------------------------------
# Grab some info for logging
#
NL="
"
SUBJ=""
FROM="unknown"
:0
* ^Subject[ ]*:[ ]+\/.+
{
SUBJ=" in \"$MATCH\""
}
:0
* ^From[ ]*:[ ]+\/.+
{
FROM="$MATCH"
SUBJ="$SUBJ from $FROM"
}
TO=$LOGNAME
:0
* LOGNAME ?? ^suporte$
{
# If $LOGNAME is root, we're probably running as a gateway filter:
# get the "real" to name(s) out of the message headers.
:0
* ^To: +\/.*
{
TO="$MATCH"
}
}
:0
* ^Message-ID:.*\/<[^>]+>
{
MSGID="$MATCH"
TO="$TO msgid=$MSGID"
}
SUBJ="$SUBJ to $TO
"
#---------------------------------------------------------------------------
# trap some excessively long RFC-822 headers
#
:0
* 1^1
^\/(Mime-Version|Date|Resent-Date|Message-ID|Return-Path|From|Status|X-Statu
s|X-Keywords):
............................................................................
............................................................................
............................................................................
............................................................................
............................................................................
............................................................................
..............................................*
{
LOG="Trapped excessively long header$SUBJ"
STATUS="STATUS: Message bounced."
:0
* SECURITY_QUARANTINE ?? [^ ]
{
STATUS="STATUS: Message quarantined in $SECURITY_QUARANTINE, not
delivered to recipient."
}
SECURITY_NOTIFY=${SECURITY_NOTIFY:-"postmaster"}
:0
* SECURITY_NOTIFY ?? [^ ]
* !$ ^X-Loop: EMAIL SECURITY WARNING $HOST $SECRET
{
LOG="${NL}NOTIFY $SECURITY_NOTIFY${NL}"
:0 h ci
| ( \
echo "To: $SECURITY_NOTIFY";\
echo 'From: "Procmail Security daemon" <postmaster>';\
echo 'Subject: SECURITY WARNING - possible email attack';\
echo "X-Loop: EMAIL SECURITY WARNING $HOST $SECRET"; \
echo ;\
echo 'Trapped excessively long header:' ;\
echo $MATCH;\
echo ;\
echo $STATUS;\
echo ;\
echo 'Headers from message:';\
echo ;\
sed -e 's/^/> /' ;\
) | $SENDMAIL -U $SECURITY_NOTIFY
}
:0
* SECURITY_QUARANTINE ?? [^ ]
{
:0
$SECURITY_QUARANTINE
:0 e
{
# Argh! Quarantine failed!
# notify administrator
LOG="${NL}QUARANTINE FAILED!${NL}"
# bounce it.
EXITCODE=65
:0 h
* SECURITY_NOTIFY ?? [^ ]
* !$ ^X-Loop: EMAIL SECURITY WARNING $HOST $SECRET
| ( \
echo "To: $SECURITY_NOTIFY";\
echo 'From: "Procmail Security daemon" <postmaster>';\
echo 'Subject: SECURITY WARNING - quarantine failed!';\
echo "X-Loop: EMAIL SECURITY WARNING $HOST $SECRET"; \
echo ;\
echo 'Attempt to quarantine the following message in
$SECURITY_QUARANTINE failed.';\
echo 'Message has been bounced.';\
echo 'Verify file access permissions:';\
ls -l $SECURITY_QUARANTINE 2>&1 ;\
echo ;\
echo 'Headers from message:';\
echo ;\
sed -e 's/^/> /' ;\
) | $SENDMAIL -U $SECURITY_NOTIFY
}
}
# bounce it.
EXITCODE=65
# zap it.
:0
/dev/null
}
#---------------------------------------------------------------------------
# Not all MIME can be sanitized...
#
:0
* ^Content-Type[ ]*:.*multipart/((signed)|(encrypted));
{
LOG="WARN: Cannot sanitize message due to signing or encryption$SUBJ"
}
#---------------------------------------------------------------------------
# Defang HTML active-content tags
#
# NB: In case you think the regexes should be /<[ ]*TAG/, I suggest
# you *try* such tags in your browser first...
#
# Unfortunately the "on*" (e.g. "onload=") syntax is such that we can't
# reliably look for /onload="/ - there may be whitespace around the =.
# This isn't intended to be a full HTML parser, so we'll err on the side of
# safety by defanging everything, even though it may be outside of an HTML
# context.
#
# This keeps getting uglier as more and more holes are discovered.
#
# This will be folded into a better sanitizer Real Soon Now...
#
:0
* ! ^Content-Type[ ]*:.*multipart/((signed)|(encrypted));
{
#----------- ALL OF THIS IS SKIPPED FOR SIGNED/ENCRYPTED MESSAGES
# "perl -e" has problems when run as root...
DROPPRIVS=YES
:0
* DEBUG_VERBOSE ?? [^ ]
{
VERBOSE=YES
}
:0 B
* 1^1 \<(html|title|body|meta|app|script|object|embed|i?frame|style|img)
* 1^1 =(3d)?[ ]*["'](&{|([a-z]+script|mocha):)
{
LOG="Defanging active HTML content$SUBJ"
:0 fw
| perl -p -e ' #\
if (/</) { #\
s/<(META|APP|SCRIPT|OBJECT|EMBED|FRAME|IFRAME)/<DEFANGED_$1/gi; #\
s/<STYLE/ <!-- <DEFANGED_STYLE/gi; #\
s/<\/STYLE/ --> <\/DEFANGED_STYLE/gi; #\
s/<IMG/<DEFANGED_IMG/gi if ($ENV{"DEFANG_WEBBUGS"}); #\
s/\sSTYLE\s*=/ DEFANGED_STYLE=/gi; #\
s/\sOn(Abort|Blur|Change|Click|DblClick|DragDrop|Error|Focus|KeyDown|KeyPres
s|KeyUp|Load|MouseDown|MouseMove|MouseOut|MouseOver|MouseUp|Move|Reset|Resiz
e|Select|Submit|Unload)/ DEFANGED_On$1/gi; #\
} #\
s/^\s*On(Abort|Blur|Change|Click|DblClick|DragDrop|Error|Focus|KeyDown|KeyPr
ess|KeyUp|Load|MouseDown|MouseMove|MouseOut|MouseOver|MouseUp|Move|Reset|Res
ize|Select|Submit|Unload)/DEFANGED_On$1/gi; #\
if (/["\047][^"\047\s]*&#x?[1-9][0-9a-f]/i) { #\
while
(/["\047][^"\047\s]*&#((4[6-9]|5[0-8]|6[4-9]|[78][0-9]|9[07-9]|1[0-1][0-9]|1
2[0-2]))/) { #\
$char = chr($1); #\
s/&#$1;?/$char/g; #\
} #\
while
(/["\047][^"\047\s]*&#(x(2[ef]|3[0-9a]|4[0-9a-f]|5[0-9a]|6[1-9a-f]|7[0-9a]))
/i) { #\
$char = chr(hex("0$1")); #\
s/&#$1;?/$char/gi; #\
} #\
} #\
if (/["\047][^"\047\s]*%[2-7][0-9a-f]/i) { #\
while
(/["\047][^"\047\s]*%((2[ef]|3[0-9a]|4[0-9a-f]|5[0-9a]|6[1-9a-f]|7[0-9a]))/i
) { #\
$char = chr(hex("0x$1")); #\
s/%$1/$char/gi; #\
} #\
} #\
s/(["\047])([a-z]+script|mocha):/${1}DEFANGED_$2:/gi; #\
s/(["\047])&{/${1}DEFANGED_&{/g; #\
'
}
#---------------------------------------------------------------------------
# Mangle HTML and executable attachment filenames enough that they won't
# automatically execute, and limit the length of extremely long attachment
# filenames and MIME headers to prevent buffer overflows and client
# crashes (sigh). Adding ${$} to the mangling inserts a bit of randomness
# so that an active-HTML or BO exploit can't just look for an attachment
# named EXPLOIT.DEFANGED-EXE to get around the defanging.
#
# NOTE: the [ ] has a tab embedded in it - DO NOT remove it...
#
:0
* ! MANGLE_EXTENSIONS ?? [^ ]
{
MANGLE_EXTENSIONS='html?|exe|com|cmd|bat|pif|sc[rt]|lnk|dll|ocx|do[ct]|xl[sw
t]|p[po]t|rtf|vb[se]?|hta|p[lm]|sh[bs]|hlp|chm|eml|ws[cfh]|ad[ep]|jse?|md[ab
ew]|ms[ip]|reg|asd|cil|pps'
}
# UUE attachments
:0 B
* ^begin[ ]+([0-9]+)?[ ]+[^ ]+
{
:0 B
*
^begin[ ]+([0-9]+)?[ ]+\/[^ ]...............................................
.....................................................+$
{
LOG="Truncating extremely long attachment filename $MATCH$SUBJ"
:0 fw
| perl -p -e 'if (/^begin\s+[0-9]*\s/i) { #\
($mode, $filen) = /^begin\s+([0-9]*)\s+(.{64}).*$/i; #\
$mode = "644" unless $mode; #\
s/^.*$/begin $mode $filen.../ if $filen; #\
}'
}
:0 B
* $ ^begin[ ]+([0-9]+)?[ ]+.+\.(${MANGLE_EXTENSIONS})[ ]*$
{
LOG="Sanitizing executable UUE attachments$SUBJ"
:0 fw
| perl -p -e ' #\
if (($junk,$filen) =
/^begin\s+([0-9]+\s+)?((\\.|[^"])+\.($ENV{"MANGLE_EXTENSIONS"}))\s*$/io) {
#\
if ($specf = $ENV{"POISONED_EXECUTABLES"}) { #\
if (open(POISONED,$specf)) { #\
while (chomp($poisoned_spec = <POISONED>)) { #\
$poisoned_spec =~ s/^\s+//g; #\
$poisoned_spec =~ s/\s+$//g; #\
next unless $poisoned_spec; #\
$poisoned_spec =~ s/([^\\])\./$1\\./g; #\
$poisoned_spec =~ s/\*/.*/g; #\
$poisoned_spec =~ s/\?/./g; #\
warn "Checking against \"$poisoned_spec\"\n" if $ENV{"DEBUG"};
#\
if ($filen =~ /^${poisoned_spec}$/i) { #\
warn " Trapped poisoned attachment \"$filen\".\n"; #\
print "X-Content-Security: NOTIFY\n" if
$ENV{"SECURITY_NOTIFY"} || $ENV{"SECURITY_NOTIFY_VERBOSE"}; #\
print "X-Content-Security: REPORT: Trapped poisoned
attachment \"$filen\"\n" if $ENV{"SECURITY_NOTIFY"} ||
$ENV{"SECURITY_NOTIFY_VERBOSE"}; #\
print "X-Content-Security: QUARANTINE\n" if
$ENV{"SECURITY_QUARANTINE"}; #\
print "\n"; #\
print "SECURITY WARNING!\n"; #\
print "The mail system has detected that the following\n";
#\
print "attachment may contain hazardous executable code,\n";
#\
print "is a suspicious file type or has a suspicious file
name.\n"; #\
print "Contact your system administrator immediately!\n\n";
#\
print "SUSPICIOUS ATTACHMENT: "; #\
last; #\
} #\
} #\
close(POISONED); #\
} else { #\
warn " Unable to open poisoned-executables file \"$specf\".\n";
#\
} #\
} #\
warn " Mangling executable filename \"$filen\".\n"; #\
$filen =~ s/\.([a-z]+)$/.${$}DEFANGED-$1/i; #\
print "begin 666 $filen\n"; #\
$_ = ""; #\
} #\
' 2>> $LOGFILE
}
}
# MIME attachments
:0
* 1^0 ^Content-Type[ ]*:.*(application|multipart)/[^ ]*;
* 1^0 ^Content-Disposition[ ]*:.*attachment
{
LOG="Sanitizing MIME attachment headers$SUBJ"
# Due to procmail not unwrapping MIME attachment headers,
# (they're in the message body) this perl script has to run against
# *every* message with MIME attachments to ensure security. Sorry.
# NOTE: I don't use the CPAN MIME module in order to keep this as simple
# as possible and to keep it self-contained (i.e. everything is *right
here*).
# (Attachment scanning breaks this. Which is worse - mimencode or
Mime::Base64?)
# Make sure $LOGFILE exists so the shell doesn't barf
LOGFILE=${LOGFILE:-"/dev/null"}
# If you get "Out of memory" errors in your procmail log, try changing to
# the following:
# :0 fw
# | ulimit -d 15000; perl -p -e ' #\
POISONED_SCORE=${POISONED_SCORE:-25}
:0 fw
| perl -p -e ' #\
$pasthdr = 1 if /^\s*$/; #\
unless ($pasthdr) { #\
if (($type) = /^Content-Type\s*:\s.*(application|multipart)\/\S+;/i)
{ #\
$wanthdr = 1; #\
print "X-Security: MIME headers sanitized on ", $ENV{"HOST"},
"\n"; #\
print "\tSee
http://www.impsec.org/email-tools/procmail-security.html\n"; #\
print "\tfor details. \$Revision: 1.123 $x\$Date: 2000-11-11
07:27:27-08 $x\n"; #\
if ($type =~ /application/i) { #\
$inmimehdr = 1; #\
} #\
} elsif (/^\S/) { #\
$wanthdr = 0; #\
} #\
if ($wanthdr) { #\
if (($mimeboundary) = /boundary\s*=\s*(("")|(".+")|([^"]\S+))/i)
{ #\
$mimeboundary =~ s/(^"|"$)//g; #\
$rawboundary = $mimeboundary; #\
$gotboundary = 1; #\
$boundarytoolong = $nullboundary = 0; #\
if ($boundarytoolong = (length($mimeboundary) > 80)) { #\
warn " Truncating long MIME body-part boundary string.\n"; #\
$newboundary = substr($mimeboundary,0,64); #\
$mimeboundary = quotemeta($mimeboundary); #\
s/${mimeboundary}/${newboundary}/; #\
$rawboundary =~ s/${mimeboundary}/${newboundary}/; #\
} elsif ($nullboundary = (length($mimeboundary) < 1)) { #\
warn " Replacing null MIME body-part boundary string.\n"; #\
$newboundary = "==NULL_MIME_BOUNDARY_ATTACK_SANITIZED-${$}==";
#\
s/boundary\s*=\s*""/boundary = "${newboundary}"/i; #\
} else { #\
$mimeboundary = quotemeta($mimeboundary); #\
} #\
} #\
} #\
} #\
if ($mimeboundary || ($gotboundary && $nullboundary) || $inmimehdr)
{ #\
if (/^\s*$/) { #\
$inmimehdr = 0; #\
} elsif (/^--${mimeboundary}(--)?$/o) { #\
$inmimehdr = 1; #\
$check_attachment = 0; #\
s/${mimeboundary}/${newboundary}/ if $boundarytoolong; #\
s/^--/--${newboundary}/ if $nullboundary; #\
} elsif (!$inmimehdr && $check_attachment) { #\
$check_attachment = 0; #\
if ($destf = `mktemp /tmp/mailchk.XXXXXX`) { #\
chomp($destf); #\
if (open(DECODE,"|mimencode -u -o $destf")) { #\
do { #\
print $_; #\
print DECODE $_; #\
$_ = <>; #\
$lastline = $_; #\
} until (/^\s*$/ || /^--/); #\
close(DECODE); #\
# Run virus-checker here. #\
open(ATTCH,"< $destf"); #\
$msapp = $score = 0; #\
while (<ATTCH>) { #\
if ($msapp) { #\
$score+= 99 if /\000VirusProtection/i; #\
$score+= 99 if /\000select\s[^\000]*shell\s*\(/i; #\
$score+= 9 if /\000regedit/i; #\
$score+= 9 if /\000SaveNormalPrompt/i; #\
$score+= 9 if /\000Outlook.Application\000/i; #\
$score+= 4 if /\000ID="{[-0-9A-F]+$/i; #\
$score+= 4 if /\000CreateObject/i; #\
$score+= 4 if
/(\000|\004)([a-z0-9_]\.)*(Autoexec|Workbook_(Open|BeforeClose)|Document_(Op
en|New|Close))/i; #\
$score+= 4 if
/(\000|\004)(Logon|AddressLists|AddressEntries|Recipients|Subject|Body|Attac
hments|Logoff)/i; #\
$score+= 2 if /\000Shell/i; #\
$score+= 2 if /\000Options[^\w\s]/i; #\
$score+= 2 if /\000CodeModule/i; #\
$score+= 2 if /\000([a-z]+\.)?Application\000/i; #\
$score+= 2 if /(\000|\004)stdole/i; #\
$score+= 2 if /(\000|\004)NormalTemplate/i; #\
$score+= 1 if /\000ThisWorkbook\000/i; #\
$score+= 1 if /\000PrivateProfileString/i; #\
$score+= 1 if /\000ID="{[-0-9A-F]+}"/i; #\
$score+= 1 if /(\000|\004)(ActiveDocument|ThisDocument)/i;
#\
$score+= 1 if
/\000\[?HKEY_(CLASSES_ROOT|CURRENT_USER|LOCAL_MACHINE)/; #\
} else { #\
if (/\000(Microsoft (Word Document|Excel
Worksheet|Excel|PowerPoint)|MSWordDoc|Word\.Document\.[0-9]+|Excel\.Sheet\.[
0-9]+)\000/) { #\
$msapp = 1; #\
seek(ATTCH,0,0); #\
} #\
} #\
} #\
close(ATTCH); #\
unlink($destf); #\
if ($histfile = $ENV{"SCORE_HISTORY"}) { #\
if (open(HIST,">>$histfile")) { #\
print HIST "score=$score msgid=".$ENV{"MSGID"}."
from=".$ENV{"FROM"}."\n"; #\
close HIST; #\
} #\
} #\
$poison_score = $ENV{"POISONED_SCORE"}; #\
$poison_score = 5 if $poison_score < 5; #\
if ($score > $poison_score && !$ENV{"SCORE_ONLY"}) { #\
warn " POSSIBLE MACRO EXPLOIT: Score=$score\n"; #\
print "\n\n--$rawboundary\n"; #\
print "Content-Type: TEXT/PLAIN;\n"; #\
print "X-Content-Security: NOTIFY\n" if
$ENV{"SECURITY_NOTIFY"} || $ENV{"SECURITY_NOTIFY_VERBOSE"}; #\
print "X-Content-Security: REPORT: Trapped poisoned
Microsoft attachment\n" if $ENV{"SECURITY_NOTIFY"} ||
$ENV{"SECURITY_NOTIFY_VERBOSE"}; #\
print "X-Content-Security: QUARANTINE\n" if
$ENV{"SECURITY_QUARANTINE"}; #\
print "Content-Description: SECURITY WARNING\n\n"; #\
print "SECURITY WARNING!\n"; #\
print "The mail delivery system has detected that the
preceding\n"; #\
print "document attachment appears to contain hazardous
macro code.\n"; #\
print "Macro Scanner score: $score\n"; #\
print "Contact your system administrator immediately!\n\n";
#\
} #\
if ($lastline =~ /^--${mimeboundary}(--)?$/o) { #\
$inmimehdr = 1; #\
$check_attachment = 0; #\
$lastline =~ s/${mimeboundary}/${newboundary}/ if
$boundarytoolong; #\
} #\
print $lastline; #\
} else { #\
warn " Cannot decode attachment: $! - is mimencode
installed?\n"; #\
} #\
} else { #\
warn " Cannot extract attachment: $! - is mktemp
installed?\n"; #\
} #\
} #\
if ($inmimehdr || $hdrcnt) { #\
if (/^(\s+\S|(file)?name)/) { #\
s/^\s*/ /; #\
s/^\s*// if $hdrtxt =~ /"[^"]*[^;]$/; #\
s/\s*\n$//; #\
$hdrtxt .= $_; #\
$_ = ""; #\
} else { #\
if ($hdrtxt) { #\
$hdrtxt =~ s/([^\\])\\"/\1\\ÿ/g; #\
if ($hdrtxt =~ /`\s*`/) { #\
warn " Fixing double backquotes.\n"; #\
$hdrtxt =~ s/`\s*`/\\"/g; #\
} #\
if ($hdrtxt =~ /^[-\w]+\s*:.*name\s*=\s*"[^"]+$/i) { #\
warn " Fixing missing close quote on filename.\n"; #\
$hdrtxt .= "\""; #\
} #\
while (($hdr, $val) = $hdrtxt =~
/^([-\w]+)\s*:.*\s(\S+)\s*=\s*""/i) { #\
warn " Null $val in $hdr header.\n"; #\
$sval = quotemeta($val); #\
$hdrtxt =~ s/\s$sval\s*=\s*""/ X-$val="{null value
sanitized}"/; #\
} #\
while (($junk,$filen) = $hdrtxt =~
/^Content-[-\w]+\s*:[^"]*("[^"]*"[^"]+)*name\s*=\s*([^"\s][^;]+)/i) { #\
warn " Fixing unquoted filename \"$filen\".\n"; #\
$newfilen = $filen; #\
$newfilen =~ s/\"/\\"/g; #\
if ($newfilen =~ /\([^)]*\)/) { #\
warn " Filename contains embedded RFC822 comment -
removing.\n"; #\
$newfilen =~ s/\([^)]*\)//g; #\
} #\
$filen = quotemeta($filen); #\
$hdrtxt =~ s/name\s*=\s*${filen}/name="$newfilen"/ig; #\
} #\
while (($filen) = $hdrtxt =~
/^Content-[-\w]+\s*:.*name\s*=\s*"([^"]{64})[^"]{16,}"/i) { #\
warn " Truncating long filename \"$filen...\".\n"; #\
$filen .= "..."; #\
$filen .= "?=" if $filen =~ /^=\?/; #\
$hdrtxt =~ s/name\s*=\s*"[^"]{80,}"/name="$filen"/i; #\
} #\
if (($filen) = $hdrtxt =~
/^Content-[-\w]+\s*:.*name\s*=\s*"([^"]+\.(do[ct]|xl[swt]|p[po]t|rtf|pps)(\?
=)?)"/i) { #\
warn " Scanning \"$filen\".\n"; #\
if (!$poisoned && ($specf = $ENV{"POISONED_EXECUTABLES"}))
{ #\
if (open(POISONED,$specf)) { #\
while (chomp($poisoned_spec = <POISONED>)) { #\
$poisoned_spec =~ s/^\s+//g; #\
$poisoned_spec =~ s/\s+$//g; #\
next unless $poisoned_spec; #\
$poisoned_spec =~ s/([^\\])\./$1\\./g; #\
$poisoned_spec =~ s/\*/.*/g; #\
$poisoned_spec =~ s/\?/./g; #\
$poisoned_spec .= "(\\?=)?"; #\
warn "Checking against \"$poisoned_spec\"\n" if
$ENV{"DEBUG"}; #\
if ($filen =~ /^${poisoned_spec}$/i) { #\
warn " Trapped poisoned document \"$filen\".\n"; #\
$poisoned = 1; #\
print "Content-Type: TEXT/PLAIN;\n"; #\
print "X-Content-Security: NOTIFY\n" if
$ENV{"SECURITY_NOTIFY"} || $ENV{"SECURITY_NOTIFY_VERBOSE"}; #\
print "X-Content-Security: REPORT: Trapped poisoned
Microsoft attachment \"$filen\"\n" if $ENV{"SECURITY_NOTIFY"} ||
$ENV{"SECURITY_NOTIFY_VERBOSE"}; #\
print "X-Content-Security: QUARANTINE\n" if
$ENV{"SECURITY_QUARANTINE"}; #\
print "Content-Description: SECURITY WARNING\n\n";
#\
print "SECURITY WARNING!\n"; #\
print "The mail system has detected that the
following\n"; #\
print "attachment may contain hazardous macro
code,\n"; #\
print "is a suspicious file type or has a suspicious
file name.\n"; #\
print "Contact your system administrator
immediately!\n"; #\
print "Macro Scanner score: 0 (not scanned due to
poisoning policy)\n\n"; #\
last; #\
} #\
} #\
close(POISONED); #\
} else { #\
warn " Unable to open poisoned-executables file
\"$specf\".\n"; #\
} #\
} #\
$check_attachment = 1 unless $ENV{"DISABLE_MACRO_CHECK"}; #\
} #\
$mangle_mime_type = 0; #\
while (($filen) = $hdrtxt =~
/^Content-[-\w]+\s*:.*name\s*=\s*"([^"]+\.($ENV{"MANGLE_EXTENSIONS"})(\?=)?)
"/io) { #\
if (!$poisoned && ($specf = $ENV{"POISONED_EXECUTABLES"}))
{ #\
if (open(POISONED,$specf)) { #\
while (chomp($poisoned_spec = <POISONED>)) { #\
$poisoned_spec =~ s/^\s+//g; #\
$poisoned_spec =~ s/\s+$//g; #\
next unless $poisoned_spec; #\
$poisoned_spec =~ s/([^\\])\./$1\\./g; #\
$poisoned_spec =~ s/\*/.*/g; #\
$poisoned_spec =~ s/\?/./g; #\
$poisoned_spec .= "(\\?=)?"; #\
warn "Checking against \"$poisoned_spec\"\n" if
$ENV{"DEBUG"}; #\
if ($filen =~ /^${poisoned_spec}$/i) { #\
warn " Trapped poisoned executable \"$filen\".\n";
#\
$poisoned = 1; #\
print "Content-Type: TEXT/PLAIN;\n"; #\
print "X-Content-Security: NOTIFY\n" if
$ENV{"SECURITY_NOTIFY"} || $ENV{"SECURITY_NOTIFY_VERBOSE"}; #\
print "X-Content-Security: REPORT: Trapped poisoned
executable \"$filen\"\n" if $ENV{"SECURITY_NOTIFY"} ||
$ENV{"SECURITY_NOTIFY_VERBOSE"}; #\
print "X-Content-Security: QUARANTINE\n" if
$ENV{"SECURITY_QUARANTINE"}; #\
print "Content-Description: SECURITY WARNING\n\n";
#\
print "SECURITY WARNING!\n"; #\
print "The mail system has detected that the
following\n"; #\
print "attachment may contain hazardous executable
code,\n"; #\
print "is a suspicious file type or has a suspicious
file name.\n"; #\
print "Contact your system administrator
immediately!\n\n"; #\
last; #\
} #\
} #\
close(POISONED); #\
} else { #\
warn " Unable to open poisoned-executables file
\"$specf\".\n"; #\
} #\
} #\
warn " Mangling executable filename \"$filen\".\n"; #\
$newfilen = $filen; #\
$newfilen =~ s/\.([a-z0-9]+(\?=)?)$/.${$}DEFANGED-$1/i; #\
$filen = quotemeta($filen); #\
$hdrtxt =~ s/name\s*=\s*"?${filen}"?/name="$newfilen"/ig; #\
$mangle_mime_type = 1; #\
} #\
if ($mangle_mime_type && $hdrtxt =~ /^Content-Type:\s/i) { #\
($oct) = $hdrtxt =~ /^Content-Type:.*\s(\S+\/\S+;?)/i; #\
unless ($oct =~ /application\/octet-stream;/i) { #\
print "X-Content-Security: original Content-Type was
$oct\n"; #\
$oct = quotemeta($oct); #\
$hdrtxt =~ s/${oct}/application\/octet-stream;/i; #\
} #\
} #\
if ($mangle_mime_type && $hdrtxt =~ /\sx-mac-\S+/i) { #\
$eudora = ""; #\
while (($eh) = $hdrtxt =~ /(\sx-mac-\S+\s*=\s*\S+;?)/i) { #\
$eudora .= $eh; #\
$eh = quotemeta($eh); #\
$hdrtxt =~ s/${eh}//i; #\
} #\
print "X-Content-Security: removed$eudora\n"; #\
} #\
if (($junk) = $hdrtxt =~
/^Content-Type\s*:\s+(.{128}).{100,}$/i) { #\
warn " Truncating long Content-Type header.\n"; #\
$junk =~ s/"/\\"/g; #\
$hdrtxt = "Content-Type: X-BOGUS\/X-BOGUS;
originally=\"$junk...\""; #\
} elsif (($junk) = $hdrtxt =~
/^Content-Description\s*:\s+(.{128}).{100,}$/i) { #\
warn " Truncating long Content-Description header.\n"; #\
$hdrtxt = "Content-Description: $junk..."; #\
} elsif (($junk) = $hdrtxt =~
/^Content-[-\w]+\s*:\s+(.{128}).{100,}$/i) { #\
warn " Truncating long MIME header.\n"; #\
$junk =~ s/"/\\"/g; #\
$hdrtxt =~ s/^Content-([-\w]+)\s*:.*$/X-Overflow:
Content-$1; originally="$junk..."/i; #\
} #\
#if ($hdrtxt =~ /^Content-Transfer-Encoding\s*:\s+base64/i)
{ #\
# $check_attachment = 1; #\
#} #\
$hdrtxt =~ s/\\ÿ/\\"/g; #\
print $hdrtxt, "\n"; #\
$hdrtxt = ""; #\
} #\
if (/^\S/) { #\
s/\s*\n$//; #\
$hdrtxt = $_; #\
$_ = ""; #\
$hdrcnt++; #\
} else { #\
$hdrcnt = 0; #\
$hdrtxt = ""; #\
} #\
} #\
} else { #\
$poisoned = 0; #\
} #\
} #\
' 2>> $LOGFILE
}
:0 HB
* ^X-Content-Security: (NOTIFY|QUARANTINE)
{
:0
* 1^0 SECURITY_NOTIFY ?? [^ ]
* 1^0 SECURITY_NOTIFY_VERBOSE ?? [^ ]
{
# Notify administration and sender of the attack
STATUS="STATUS: Message delivered to $TO"
STATUS_PUBLIC="STATUS: Message delivered."
REPORT="REPORT: No details available."
SCORE="REPORT: Not a document, or already poisoned by filename. Not
scanned for macros."
:0
* SECURITY_QUARANTINE ?? [^ ]
{
STATUS="STATUS: Message quarantined in $SECURITY_QUARANTINE, not
delivered to recipient."
STATUS_PUBLIC="STATUS: Message quarantined, not delivered to
recipient."
}
:0 B
* ^\/Macro Scanner score: [1-9][0-9]+
{
SCORE="REPORT: $MATCH"
}
:0 HB
* ^X-Content-Security: \/REPORT: .*
{
REPORT="$MATCH"
}
:0
* SECURITY_NOTIFY ?? [^ ]
* !$ ^X-Loop: EMAIL SECURITY WARNING $HOST $SECRET
{
LOG="${NL}NOTIFY $SECURITY_NOTIFY${NL}"
:0 h ci
| ( \
echo "To: $SECURITY_NOTIFY";\
echo 'From: "Procmail Security daemon" <postmaster>';\
echo 'Subject: SECURITY WARNING - possible email attack';\
echo "X-Loop: EMAIL SECURITY WARNING $HOST $SECRET"; \
echo ;\
echo $REPORT;\
echo $SCORE;\
echo $STATUS;\
echo ;\
echo 'Headers from message:';\
echo ;\
sed -e 's/^/> /' ;\
) | $SENDMAIL -U $SECURITY_NOTIFY
}
:0
* SECURITY_NOTIFY_VERBOSE ?? [^ ]
* !$ ^X-Loop: EMAIL SECURITY WARNING $HOST $SECRET
{
LOG="${NL}NOTIFY $SECURITY_NOTIFY_VERBOSE${NL}"
:0 hb ci
| ( \
echo "To: $SECURITY_NOTIFY_VERBOSE";\
echo 'From: "Procmail Security daemon" <postmaster>';\
echo 'Subject: SECURITY WARNING - possible email attack';\
echo "X-Loop: EMAIL SECURITY WARNING $HOST $SECRET"; \
echo ;\
echo $REPORT;\
echo $SCORE;\
echo $STATUS;\
echo ;\
echo 'Message:';\
echo ;\
sed -e 's/^/> /' ;\
) | $SENDMAIL -U $SECURITY_NOTIFY_VERBOSE
}
:0 H
* SECURITY_NOTIFY_SENDER ?? [^ ]
* ! ^FROM_DAEMON
* !$ ^X-Loop: EMAIL SECURITY WARNING $HOST $SECRET
{
LOG="${NL}NOTIFY SENDER${NL}"
PM_CC="X-Placeholder:"
:0
* SECURITY_NOTIFY_SENDER_POSTMASTER ?? [^ ]
{
:0 h c
PM_CC=| formail -r | grep -i '^To: ' | sed -e
's/^.*@/postmaster@/' -e 's/>.*//'
PM_CC="Cc: <$PM_CC>"
}
:0 h ci
| ( \
formail -r \
-I 'From: "Procmail Security daemon" <postmaster>'\
-I "Bcc: $SECURITY_NOTIFY" -I "$PM_CC" \
-I "X-Loop: EMAIL SECURITY WARNING $HOST $SECRET" \
;\
echo ;\
if [ -f "$SECURITY_NOTIFY_SENDER" -a -s
"$SECURITY_NOTIFY_SENDER" -a -r "$SECURITY_NOTIFY_SENDER" ] ;\
then \
echo 'Regarding your message to';\
echo $TO;\
echo ;\
cat $SECURITY_NOTIFY_SENDER; \
else \
echo '*** SECURITY WARNING ***';\
echo 'Our email gateway has detected that your message to';\
echo $TO;\
echo 'may contain hazardous embedded scripting or
attachments.';\
echo 'Please notify your system administrator by phone right
away.';\
echo 'You should make sure your virus signature list';\
echo 'is up-to-date and then rescan your computer.';\
echo ;\
echo 'If the macro scanner score is large yet your virus
scanner reports';\
echo 'that the document is not infected, try saving it using
a different';\
echo 'format that will completely strip out all macros, such
as RTF.';\
fi ;\
echo ;\
echo $REPORT;\
echo $SCORE;\
echo $STATUS_PUBLIC;\
echo ;\
echo '--';\
echo 'Message sanitized on' $HOST;\
echo 'See http://www.impsec.org/email-tools/procmail-security.html
for details.';\
echo ;\
) | $SENDMAIL -oi -t
}
}
:0
* SECURITY_QUARANTINE ?? [^ ]
{
:0
* SECURITY_NOTIFY_RECIPIENT ?? [^ ]
{
LOG="${NL}NOTIFY RECIPIENT${NL}"
# We could stuff this directly into $DEFAULT but then
# we'd have to worry about generating Message-ID and Date headers...
:0 h ci
| ( \
echo "To: <$LOGNAME>";\
echo 'From: "Procmail Security daemon" <postmaster>';\
echo 'Subject: SECURITY WARNING - email quarantined';\
echo ;\
if [ -f "$SECURITY_NOTIFY_RECIPIENT" -a -s
"$SECURITY_NOTIFY_RECIPIENT" -a -r "$SECURITY_NOTIFY_RECIPIENT" ] ;\
then \
cat $SECURITY_NOTIFY_RECIPIENT; \
else \
echo '*** SECURITY WARNING ***';\
echo 'Our email gateway has detected that a message sent to
you';\
echo 'may contain hazardous embedded scripting or
attachments.';\
echo 'The message has been quarantined per site security
policy.';\
echo 'Please contact your system administrator for further
details.';\
echo ;\
fi ;\
echo ;\
echo $REPORT;\
echo $SCORE;\
echo $STATUS_PUBLIC;\
echo ;\
echo '--';\
echo 'Message sanitized on' $HOST;\
echo 'See http://www.impsec.org/email-tools/procmail-security.html
for details.';\
echo ;\
) | $SENDMAIL -oi -t
}
:0 :
$SECURITY_QUARANTINE
:0 e
* ! SECURITY_QUARANTINE_OPTIONAL ?? [^ ]
{
# Argh! Quarantine failed, and not explicitly marked as optional!
# Bounce message, and notify administrator
LOG="${NL}QUARANTINE FAILED!${NL}"
EXITCODE=65
:0 h
* SECURITY_NOTIFY ?? [^ ]
* !$ ^X-Loop: EMAIL SECURITY WARNING $HOST $SECRET
| ( \
echo "To: $SECURITY_NOTIFY";\
echo 'From: "Procmail Security daemon" <postmaster>';\
echo 'Subject: SECURITY WARNING - quarantine failed!';\
echo "X-Loop: EMAIL SECURITY WARNING $HOST $SECRET"; \
echo ;\
echo 'Attempt to quarantine the following message in
$SECURITY_QUARANTINE failed.';\
echo 'Message has been bounced.';\
echo 'Verify file access permissions:';\
ls -l $SECURITY_QUARANTINE ;\
echo ;\
echo $REPORT;\
echo $SCORE;\
echo ;\
echo 'Headers from message:';\
echo ;\
sed -e 's/^/> /' ;\
) | $SENDMAIL -U $SECURITY_NOTIFY
# zap it, just in case
:0
/dev/null
}
}
}
} # ---- END OF SIGNED/ENCRYPTED SKIP
#eof
_______________________________________________
procmail mailing list
procmail(_at_)lists(_dot_)RWTH-Aachen(_dot_)DE
http://MailMan.RWTH-Aachen.DE/mailman/listinfo/procmail