LINUX MAGAZINEsubscribeadvertisecustomer serviceback issuesfeedbackcontacts


How To
Power Tools
Guru Guidance
On The Desktop
Best Defense
Developer's Den
Java Matters
Extreme Linux
Compile Time
Perl of Wisdom
Gearheads Only
Project of the Month
Who's Who

Linux Magazine / July 2003 / FEATURES
A Message-Archiving Recipe
<< prev   page 1 2 3 4 5

Personal Post - Supplemental Pages
A Message-Archiving Recipe
by Jerry Peek

The article introduces a procmail recipe that searches message bodies for an encoded virus. When it finds one of these suspicious messages, it archives the message and emails you a notice.

This webpage goes into detail about a similar but more general recipe: one to catch all email messages that contain an executable .exe file for Microsoft Windows -- whether or not the MIME type actually identifies the file correctly. (A favorite technique of these crackers is to embed executable files but declare them as some other type, such as audio .wav files. This recipe won't be fooled... at least, not that way.)

First, here are some lines from the header and body of one of these virus messages:

From: Your friend <>
MIME-Version: 1.0
Content-Type: multipart/mixed;
Subject: Jerry, please check this out!

Content-Type: audio/x-wav; name=Com.bat
Content-Transfer-Encoding: base64
Content-ID: <MsB0jeSy>


And here's the recipe to catch the messages:

:0B :
| gzip >> $EXEFILE ; \
  (echo "  Messages in $EXEFILE file:"; \
  zcat $EXEFILE | grep "^From ") | \
  mail -s "NOTICE: Windows EXE file caught?" $LOGNAME

The first .procmailrc line (which actually isn't part of the recipe; procmail evaluates it before any recipes) sets an environment variable with the name of the virus archive. It's a compressed file in GNU gzip format.

This recipe matches a line from the message files: the first line from the encoded body. Because the file is in the message body, we've added the procmail B flag so procmail won't search only the message header (which is the default).

The recipe needs a lockfile because it's writing to a file (the file caught_exes.gz). Here, a simple colon (:) at the end of the flags line is enough: procmail will use a default lockfile name created from caught_exes.gz (which is the first filename past the redirection character in the shell recipe). If in doubt, give a lockfile pathname after the colon.

The pattern line is a regular expression; ^ means "start of line". Each Windows .exe file starts with the same bytes; this pattern matches the base64-encoded version of those bytes. (You could do a similar thing to catch other encoded file types -- once you know the pattern, that is.) There's some chance that another arbitrary file, somewhere in the universe, could start with these same bytes; that's part of why we archive the message instead of simply discarding it. (You might also actually want to receive a Windows .exe file by email someday?)

The real work here is in the shell command line. These are actually four parts of a single command line, joined by procmail's continuation character \. How does the command line work?

When procmail runs a shell command line, the incoming message is fed to that shell's standard input. The first command that reads its standard input will receive the message. Here, because we don't give gzip a filename to read, it will read its standard input. It compresses the message on-the-fly. We've used the shell's >> operator to append gzip's output to a file where we collect the viruses.  The gzip algorithm has the nice feature that you can append multiple chunks of compressed text to the same file. When you uncompress, the pieces will be uncompressed in the order written. This is handy for all sorts of space-efficient email archiving jobs!

The first line of the shell command ends with a semicolon (;), the shell command separator, as well as a backslash (\) to tell procmail that the command isn't finished. The next two lines run a subshell that collects the output of all commands within the parentheses; the standard output of all those commands is piped to a mail command, which sends a notice that a file has been caught. The subshell runs two commands (separated by the semicolon). The first command, echo, simply outputs the text from its command line. The second command is a pipeline: zcat uncompresses the virus message file on-the-fly and pipes it to grep, which looks for message separator lines (lines starting with From and a space). The mail command uses that MUA to send the resulting message (from its standard input) to the user; procmail should automatically set the LOGNAME variable with the current user's login name, but you could also use any email address here.

Here's a  typical email message that mail might send. Please compare this message to the shell command that made it:

From: Jerry Peek <>
Date: Thu, 26 Jun 2003 08:45:13 -0400 (EDT)
Subject: NOTICE: Windows EXE file caught?

  Messages in caught_exes.gz file:
From  Thu Jun 26 08:22:33 2003
From  Thu Jun 26 08:45:09 2003

This is an example of the kind of thing you can do to filter messages automatically. To come up with others, think about characteristics of the incoming messages (a pattern in the header or body) and what you want to do with those messages (file them, forward them, run a series of commands, etc.) Then test, test, test!

[To return to the place where you left the article, use your browser's "back" button. You can also go to the start of the article.]

<< prev   page 1 2 3 4 5
Linux Magazine / July 2003 / FEATURES

LINUX MAGAZINEsubscribeadvertisecustomer serviceback issuesfeedbackcontacts