SMTP
====
Andrew Mullican <amullican@sourcefire.com>
Thanks to Dan Roelker <droelker@sourcefire.com>,
Marc Norton <mnorton@sourcefire.com>, and Steve Sturges
<ssturges@sourcefire.com> for their help with the design.

-- Overview --
SMTP is an SMTP decoder for user applications.  Given a data buffer,
SMTP will decode the buffer and find SMTP commands and responses.
It will also mark the command, data header data body sections, as well
as TLS data.

SMTP handles stateless and stateful processing.  It saves state
between individual packets.  However maintaining correct state is
dependent on the reassembly of the client side of the stream (ie, a
loss of coherent stream data results in a loss of state).

-- Configuration --
SMTP has the usual configuration items, such as port and inspection_type.
Also, SMTP command lines can be normalized to remove extraneous spaces.
TLS-encrypted traffic can be ignored, which improves performance.  In addition,
regular mail data can be ignored for an additional performance boost.  Since
so few (none in the current snort ruleset) exploits are against mail data,
this is relatively safe to do and can improve the performance of data
inspection.

The configuration options are described below:

* ports { port [port] ... } *
This specifies on what ports to check for SMTP data.  Typically, this will
include 25 and possibly 465, for encrypted SMTP.
Default ports if none are specified are 25, 587 (Message submission - see 
RFC 2476) and 691 (X-LINK2STATE).  If alerting on the X-LINK2STATE vulnerability
is disabled, port 691 will be removed from the default ports.
DEFAULT { 25 587 691 }

* inspection_type stateful|stateless
Indicate whether to operate in stateful or stateless mode.

* normalize all|none|cmds *
This turns on normalization.  Normalization checks for more than one space
character after a command.  Space characters are defined as space (ASCII 0x20)
or tab (ASCII 0x09).
all checks all commands
none turns off normalization for all commands.
cmds just checks commands listed with the "normalize_cmds" parameter.

* ignore_data *
Ignore data section of mail (except for mail headers) when processing rules.

* ignore_tls_data *
Ignore TLS-encrypted data when processing rules.

* max_command_line_len <int> *
Alert if an SMTP command line is longer than this value.  Absence of this
option or a "0" means never alert on command line length.
RFC 2821 recommends 512 as a maximum command line length.

* max_header_line_len <int> *
Alert if an SMTP DATA header line is longer than this value.  Absence of this
option or a "0" means never alert on data header line length.
RFC 2821 recommends 1024 as a maximum data header line length.

* max_response_line_len <int> *
Alert if an SMTP response line is longer than this value.  Absence of this
option or a "0" means never alert on response line length.
RFC 2821 recommends 512 as a maximum response line length.

* alt_max_command_line_len <int> { <cmd> [<cmd>] }
Overrides max_command_line_len for specific commands

* no_alerts *
Turn off all alerts for this preprocessor.

* invalid_cmds { <Space-delimited list of commands> } *
Alert if this command is sent from client side.
DEFAULT empty list

* valid_cmds { <Space-delimited list of commands> } *
List of valid commands.  We do not alert on commands in this list.
DEFAULT empty list, but preprocessor has this list hard-coded:
{ ATRN AUTH BDAT DATA DEBUG EHLO EMAL ESAM ESND ESOM ETRN EVFY EXPN }
{ HELO HELP IDENT MAIL NOOP QUIT RCPT RSET SAML SOML SEND ONEX QUEU }
{ STARTTLS TICK TIME TURN TURNME VERB VRFY X-EXPS X-LINK2STATE }
{ XADR XAUTH XCIR XEXCH50 XGEN XLICENSE XQUE XSTA XTRN XUSR  }

* alert_unknown_cmds *
Alert if we don't recognize command.
DEFAULT off

* normalize_cmds { <Space-delimited list of commands> } *
Normalize this list of commands
DEFAULT { RCPT VRFY EXPN }

* xlink2state { enable/disable [drop] }
See CVE-2005-0560 for a description of the vulnerability.
Enable/disable xlink2state alert
Drop if alerted
DEFAULT { enable }

* print_cmds *
List all commands understood by the preprocessor.  This not normally
printed out with the configuration because it prints so much data.

* disabled *
Disables the SMTP preprocessor in a config. This is useful when specifying
the decoding depths such as b64_decode_depth, qp_decode_depth, uu_decode_depth, 
bitenc_decode_depth or the memcap used for decoding max_mime_mem in default config 
without turning on the SMTP preprocessor.

* b64_decode_depth *
This config option is used to turn off/on or set the base64 decoding depth used to 
decode the base64 encoded MIME attachments. The value ranges from -1 to 65535. 
A value of -1 turns off the base64 decoding of MIME attachments. The value of 0 
sets the decoding of base64 encoded MIME attachments to unlimited. A value other 
than 0 or -1 restricts the decoding of base64 MIME attachments, and applies per attachment. 
A SMTP preprocessor alert with sid 10 is generated (if enabled) when the decoding fails. 

Multiple MIME attachments/data in one packet are pipelined. When stateful inspection 
is turned on the base64 encoded MIME attachments/data across multiple packets are 
decoded too.

The decoded data is available for detection using the rule option file_data. 
See file_data rule option for more details.

This option replaces the deprecated options, enable_mime_decoding and max_mime_depth. 
It is recommended that user inputs a value that is a multiple of 4. When the value 
specified is not a multiple of 4, the SMTP preprocessor will round it up to the next 
multiple of 4.

In case of multiple configs, the value specified in the non-default config cannot 
exceed the value specified in the default config.

* qp_decode_depth *
This config option is used to turn off/on or set the Quoted-Printable decoding depth 
used to decode the Quoted-Printable(QP) encoded MIME attachments. The value ranges 
from -1 to 65535. A value of -1 turns off the QP decoding of MIME attachments. 
The value of 0 sets the decoding of QP encoded MIME attachments to unlimited. A 
value other than 0 or -1 restricts the decoding of QP MIME attachments, and applies 
per attachment. A SMTP preprocessor alert with sid 11 is generated (if enabled) when 
the decoding fails.

Multiple MIME attachments/data in one packet are pipelined. When stateful inspection 
is turned on the QP encoded MIME attachments/data across multiple packets are decoded too.

The decoded data is available for detection using the rule option file_data. 
See file_data rule option for more details.

In case of multiple configs, the value specified in the non-default config cannot exceed 
the value specified in the default config.

* bitenc_decode_depth *
This config option is used to turn off/on or set the non-encoded MIME extraction 
depth used to extract the non-encoded MIME attachments. The value ranges from -1 
to 65535. A value of -1 turns off the extraction of these MIME attachments. 
The value of 0 sets the extraction of these MIME attachments to unlimited. 
A value other than 0 or -1 restricts the extraction of these MIME attachments, and applies 
per attachment.

Multiple MIME attachments/data in one packet are pipelined. When stateful inspection 
is turned on the non-encoded MIME attachments/data across multiple packets are 
extracted too.

The extracted data is available for detection using the rule option file_data. 
See file_data rule option for more details.

In case of multiple configs, the value specified in the non-default config cannot exceed 
the value specified in the default config.

* uu_decode_depth *
This config option is used to turn off/on or set the Unix-to-Unix decoding depth 
used to decode the Unix-to-Unix(UU) encoded attachments. The value ranges 
from -1 to 65535. A value of -1 turns off the UU decoding of SMTP attachments. 
The value of 0 sets the decoding of UU encoded SMTP attachments to unlimited. A 
value other than 0 or -1 restricts the decoding of UU SMTP attachments, and applies per 
attachment. A SMTP preprocessor alert with sid 13 is generated (if enabled) when the decoding fails.

Multiple UU Encoded attachments/data in one packet are pipelined. When stateful inspection 
is turned on the UU encoded attachments/data across multiple packets are decoded too.

The decoded data is available for detection using the rule option file_data. 
See file_data rule option for more details.

In case of multiple configs, the value specified in the non-default config cannot exceed 
the value specified in the default config.

* enable_mime_decoding *
Enables Base64 decoding of Mime attachments/data. Multiple base64 encoded MIME 
attachments/data in one packet are pipelined. When stateful inspection is turned
on the base64 encoded MIME attachments/data across multiple packets are decoded too.
The decoding of base64 encoded attachments/data ends when either the max_mime_depth
or maximum MIME sessions (calculated using max_mime_depth and max_mime_mem) is 
reached or when the encoded data ends. The decoded data is available for detection
using the rule option file_data. See file_data rule option for more details.

Please note, this option is deprecated. Use the option b64_decode_depth to turn off 
or on the base64 decoding instead.

* max_mime_depth <int> *
Specifies the maximum number of base64 encoded data to decode per attachment.
The option take values ranging from 4 to 20480 bytes. The default value for this
in snort in 1460 bytes.

It is recommended that user inputs a value that is a multiple of 4. When the value
specified is not a multiple of 4, the SMTP preprocessor will round it up to the next
multiple of 4.

Please note, this option is deprecated. Use the b64_decode_depth to set the decoding 
depth for base64 decoding instead.

* max_mime_mem <int> *
This option determines (in bytes) the maximum amount of memory the SMTP preprocessor
will use for decoding base64 encoded/quoted-printable/non-encoded MIME attachments/data 
or Unix-to-Unix encoded attachments. This value can be set from 3276 bytes to 100MB. 

This option along with the maximum of the decoding depths will determine the SMTP 
sessions that will be decoded at any given instant. The default value for this option 
is 838860.

Note: It is suggested to set this value such that the max smtp session calculated as
follows is atleast 1.

max smtp session = max_mime_mem /(2 * max of (b64_decode_depth, uu_decode_depth, qp_decode_depth 
					or bitenc_decode_depth))

For example, if b64_decode_depth is 0 (indicates unlimited decoding) and qp_decode_depth is 100, then

max smtp session = max_mime_mem/2*65535 (max value for b64_decode_depth)

In case of multiple configs, the max_mime_mem of the non-default configs will be overwritten by the
default config's value. Hence user needs to define it in the default config with the new keyword
disabled (used to disable SMTP preprocessor in a config).

* log_mailfrom *
This option enables SMTP preprocessor to parse and log the sender's email address extracted 
from the "MAIL FROM" command along with all the generated events for that session. The maximum 
number of bytes logged for this option is 1024.

Please note, this is logged only with the unified2 output and is not logged with console output (-A cmg).
u2spewfoo can be used to read this data from the unified2.

* log_rcptto *
This option enables SMTP preprocessor to parse and log the recipient email addresses 
extracted from the "RCPT TO" command along with all the generated events for that session. 
Multiple recipients are appended with commas. The maximum number of bytes logged for this option is 1024.

Please note, this is loggged only with the unified2 output and is not logged with console output (-A cmg).
U2spewfoo can be used to read this data from the unified2.

* log_filename *
This option enables SMTP preprocessor to parse and log the MIME attachment filenames extracted 
from the Content-Disposition header within the MIME body along with all the generated events 
for that session. Multiple filenames are appended with commas. The maximum number of bytes 
logged for this option is 1024.

Please note,this is logged only with the unified2 output and is not logged with the
console output (-A cmg). u2spewfoo can be used to read this data from the unified2.

* log_email_hdrs *
This option enables SMTP preprocessor to parse and log the SMTP email headers extracted from 
SMTP data along with all generated events for that session. The number of bytes extracted and 
logged depends upon the email_hdrs_log_depth.

Please note, this is logged only with the unified2 output and is not logged with the console output (-A cmg).
u2spewfoo can be used to read this data from the unified2.

* email_hdrs_log_depth <int> *
This option specifies the depth for logging email headers. The allowed range for this option is 
0 - 20480. A value of 0 will disable email headers logging. The default value for this option is 1464. 

Please note, in case of multiple configs, this default config's value is used. The values specified in
 the non-default config will be ignored and overwritten by the default config's values.
This option must be configured in the default config even if the SMTP configuration is disabled.

* memcap <int>*
This option determines in bytes the maximum amount of memory the SMTP preprocessor will
use for logging of filename, MAIL FROM addresses, RCPT TO addresses and email headers. This value 
along with the buffer size used to log MAIL FROM, RCPT TO, filenames and email_hdrs_log_depth will 
determine the maximum SMTP sessions that will log the email headers at any given time. When this memcap is 
reached SMTP will stop logging the filename, MAIL FROM address, RCPT TO addresses and email headers 
until memory becomes available.

Max SMTP sessions logging email headers at any given time 
		= memcap/(1024 + 1024 + 1024 + email_hdrs_log_depth)

The size 1024 is the maximum buffer size used for logging filename, RCPTTO and MAIL FROM addresses.

Default value for this option is 838860. The allowed range for this option is 3276 to 104857600.
The value specified in the default config is used when this option is specified in multiple configs.
This option must be configured in the default config even if the SMTP configuration is disabled.


Example:
preprocessor SMTP: \
  ports { 25 } \
  inspection_type stateful \
  normalize cmds \
  normalize_cmds { EXPN VRFY RCPT } \
  ignore_data \
  ignore_tls_data \
  max_command_line_len  512 \
  max_header_line_len   1024 \
  max_response_line_len 512 \
  no_alerts \
  alt_max_command_line_len 300 { RCPT } \
  invalid_cmds { } \
  valid_cmds { } \
  xlink2state { disable } \
  print_cmds \
  log_filename \
  log_email_hdrs \
  log_mailfrom \
  log_rcptto \
  email_hdrs_log_depth 2920 \
  memcap 6000

 

preprocessor SMTP: \
  max_mime_depth 100 \
  max_mime_mem 4000 \
  memcap 6000 \
  email_hdrs_log_depth 2920 \
  disabled

Default:
preprocessor SMTP: \
  ports { 25 } \
  inspection_type stateful \
  normalize cmds \
  normalize_cmds { EXPN VRFY RCPT } \
  alt_max_command_line_len 260 { MAIL } \
  alt_max_command_line_len 300 { RCPT } \
  alt_max_command_line_len 500 { HELP HELO ETRN } \
  alt_max_command_line_len 255 { EXPN VRFY }

Notes:
"RCPT TO:" and "MAIL FROM:" are SMTP commands.  For the preprocessor
configuration, they are referred to as RCPT and MAIL, respectively.
Within the code, the preprocessor actually maps RCPT and MAIL to the
correct command name.

