procmail
[Top] [All Lists]

Change extensions of Files

2000-11-21 10:39:14
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

<Prev in Thread] Current Thread [Next in Thread>