[prev in list] [next in list] [prev in thread] [next in thread] 

List:       inet-access
Subject:    Fw: [Snort-sigs] Announcing sp_perl
From:       "james" <hackerwacker () cybermesa ! com>
Date:       2003-05-11 0:07:57
[Download RAW message or body]

For those of us that run Snort, the ability to use regular expressions in rules
to match exploits has been a dream. Regex means if you can capture an exploit
you can write a rule which is very specifc; with no false positives.

james


> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
> 
> As described in our CanSecWest/core03 presentation, Advanced IDS, Brian
> Caswell and I are proud to present a new detection plugin for Snort:
> sp_perl.  This detection plugin offers users full regular expression
> matching within a Snort rule as well as runtime execution of perl code.
> 
> The patch is available here:
> http://www.snort.org/dl/contrib/patches/snort-perl/snort_perl.diff.gz
> and here:
> http://cerberus.sourcefire.com/~jeff/presentations/cansecwest-2003/snort_pe
> rl.diff.gz
> 
> A README related to this patch and the PowerPoint slides used in the
> presentation are available here:
> http://cerberus.sourcefire.com/~jeff/presentations/cansecwest-2003/READ_ME_
> FIRST.txt
> http://cerberus.sourcefire.com/~jeff/presentations/cansecwest-2003/caswell-
> nathan.ppt
> 
> Enjoy,
> 
> Brian and Jeff
> 
> P.S. Jed Haile rules.
> 
> - --
> http://cerberus.sourcefire.com/~jeff       (pgp key available)
> "Great spirits have always encountered violent opposition from mediocre
> minds."
> - - Albert Einstein
> -----BEGIN PGP SIGNATURE-----
> Version: GnuPG v1.0.7 (OpenBSD)
> 
> iD8DBQE+vNkXEqr8+Gkj0/0RAvNNAJ9hSWmStD5PgvyL8zz2M0w3CR+grgCgiY5v
> VZTv1yuYLynWA/HG81faod0=
> =g1CC
> -----END PGP SIGNATURE-----

###########################################################################
(C) 2003 Brian Caswell <bmc at snort dot org>
(C) 2003 Jeff Nathan <jeff at snort dot org>
###########################################################################

For an overview of the presentation, please view the powerpoint slides
in the file caswell-nathan.ppt

The contents of this README describe the perl patch for Snort described in
the presented "Advanced IDS" at the CanSecWest/core03 security conference.
This document explains how to apply the perl patch to Snort
as well as how to use the new detection keywords added by the patch.

************************************
Applying the perl patch to Snort 2.0
************************************

The following instructions require GNU autoconf and GNU automake

Anything following a hash character (#) is a command.

a) copy the patch into the top level snort source distribution directory
   if your Snort directory uses a different name, this is not a problem
   just make sure you know which version of Snort you intend to compile
  # cd snort-2.0
  # cp ../snort_perl.diff.gz .

b) decompress the patch with gzip
  # gzip -d snort_perl.diff.gz

c) patch configure.in
  # patch -p0 < snort_perl.diff

d) regenerate the configure script (this step REQUIRES that GNU autoconf and
   GNU automake are installed)

  (if you are using a CVS version of Snort 2.0 use the following command)
  # ./autojunk.sh

  (otherwise use the following commands)
  # aclocal
  # autoheader
  # automake
  # autoconf

e) you may now run the configure script with your desired arguments
  # ./configure --enable-perl

f) compile Snort
  # make

Note: Due to the way perl is packaged in some operating systems, we have
encountered problems building Snort with this patch.

This functionality provided by this patch is still under development.  Use it
at your own risk.  You have been warned.

***********************************
Utilizing the new keywords in Snort
***********************************

After patching and compiling Snort with the snort_perl patch, two new detection
keywords can be used within snort rules: perlre and perl.  The perlre keyword
will perform full regular expression matching on the contents of a packet.
The perl keyword provides runtime execution of perl code.

The perl subroutines that are called when the perlre or perl keyword is
used within a Snort rule are stored in a file named snort.pl.  When using the
new keywords, the snort.pl file must be located in the same directory as the
snort binary.  Be aware that plugins are initialized before a Snort process is
chrooted.

By storing the perl subroutines in a file rather than compiling them into the
Snort binary, a user can modify the subroutines as well as add new subroutines.
A new subroutine can be called directly from the perl keyword.

Both of the new keywords operate by manipulating the perl stack.  When a Snort
rule contains either the perl or perlre keyword and the prerequisite conditions
contained in the rule have been met (protocol, port, TCP stream state, etc)
the packet payload, source and destination IP address, and source and
destination port (where applicable) are converted to perl scalar data.  By
storing this data as perl scalars, the new plugins are able to fully mutiliate,
er.. manipulate the packet data to perform more elaborate detection functions.

The following variables contain the converted perl scalar data:
$content      (packet data)
$srcip        (source IP address, in dotted quad format)
$dstip        (destination IP address, in dotted quad format)
$srcport      (source port)
$dstport      (destination port)

Due to a subtle bug (feature) in snort's parser, regular expression
arguments to the perlre keyword should NOT be enclosed in quotes (trust us).

Without further delay, here are some examples for your reading pleasure.
(The sniffer mode output shown below looks strange because it was compressed
to fit in the powerpoint slides)

IMAP LSUB Buffer Overflow
*************************
CAN-2000-0284

11/11-10:45:41.482210 172.16.2.130:33012 -> 10.2.2.250:143
***AP*** Seq: 0x6F578C60  Ack: 0xFE6E84A1  Win: 0x16D0  TcpLen: 32
31 20 4C 53 55 42 20 22 22 20 7B 31 30 36 34 7D  1 LSUB "" {1064}
0D 0A                                            ..

11/11-10:45:41.482699 10.2.2.250:143 -> 172.16.2.130:33012
***AP*** Seq: 0xFE6E84A1  Ack: 0x6F578C72  Win: 0x7BFC  TcpLen: 32
TCP Options (3) => NOP NOP TS: 26213694 338288987
2B 20 52 65 61 64 79 20 66 6F 72 20 61 72 67 75  + Ready for argu
6D 65 6E 74 0D 0A                                ment..

11/11-10:45:41.483459 172.16.2.130:33012 -> 10.2.2.250:143
***AP*** Seq: 0x6F578C72  Ack: 0xFE6E84B7  Win: 0x16D0  TcpLen: 32
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90  ................
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90  ................
<snip>

Our content
------------

1 LSUB "" {1064}\r\nSHELLCODEHERE

Vulnerability condition
------------------------
1 LSUB "" {1064}\r\nSHELLCODEHERE

Essentially, IMAP's LSUB command allows the user to specify a the length of
the options to the LSUB command.  Unfortunately, in at least one
implementation, the arguements for the LSUB command are copied into a
statically sized buffer.  If a user sends more data than can fit in the
statically sized buffer, then the data overflows into other memory.

So how do we detect this?
-------------------------
1) Regex
2) Regex and some perl

Detecting an attack of against the overflow condition
------------------------------------------------------
1) Regex
   /^\w+\s+LSUB\s+"[^"]*"\s+{\d+{4,}}/

   This looks for any number of word characters (IMAP's command sequence
   identifier), followed by any number of spaces, followed by the LSUB
   command, followed any number of spaces, followed by a quote, followed by
   any number of characters except ", followed by a ", followed by any number
   of spaces, followed by a {, **** IMPORTANT PART **** followed by at least
   4 or more numeric characters **** END IMPORTANT PART ****, followed by a }

   Sounds complex, Right?  Right.  If you are confused about regular
   expressions, O'reilly has published an EXCELENT book on regular exprsesions
   entitled "Mastering Regular Expressions".

2) Regex and some perl
   /^\w+\s+LSUB\s+"[^"]*"\s+{(\d+)}/

   This looks for any number of word characters (IMAP's command sequence
   identifier), followed by any number of spaces, followed by the LSUB
   command, followed any number of spaces, followed by a quote, followed by
   any number of characters except ", followed by a ", followed by any number
   of spaces, followed by a {, **** IMPORTANT PART **** then any number of
   digits (and store those in the first match buffer) **** END IMPORTANT
   PART ****, followed by a }

   $1 > 1000

   Then, using the matched data, check to see if the value is greater than
   1000.  If so, this rule condition has successfully matched.

Using the new keywords to detect an attempted attack
----------------------------------------------------
alert ip any any -> any any (perlre:/\w+\s+LSUB\s+"[^"]*"\s+{\d+{4,}}/;)

alert ip any any -> any any (perl:"$content =~ \w+\s+LSUB\s+"[^"]*"\s+{(\d+)}\; && $1 \
> 1000";)

Optimizing the rules
--------------------
Care must be taken when using these two keywords.  Using keywords such as
flow creates prerequisite conditions that will prevent the perl interpreter
from executing code and the conversion of packet data to perl scalar data
unnecessarily.  While sp_perl has been written to operate reasonably fast,
executing perl code is nevertheless costly on a computer's processor.

alert tcp any any -> any 143 (flow:to_server,established; content:"LSUB"; nocase; \
perlre:/^\d+\s+LSUB\s+""\s+{\d{4,}/;)

alert tcp any any -> any 143 (flow:to_server,established; content:"LSUB"; nocase; \
perl:"$content =~ /\d+\s+LSUB\s+""\s+{(\d+)}/\; && $1 > 1000";)


FTP Port Bounce
*************************
CVE-1999-0017

12/31--5:00:00.007051 10.1.1.254:3161 -> 10.1.1.113:21
***AP*** Seq: 0x4FE9C1C4  Ack: 0x1E001761  Win: 0x7D78  TcpLen: 32
70 6F 72 74 20 31 37 32 2C 31 36 2C 30 2C 33 32  port 172,16,0,32
2C 31 32 2C 37 32 0A                             ,12,72.

Our content
-----------

port 172,16,0,32,12,72\n

Vulnerability condition
-----------------------

port 172,16,0,32,12,72\n

The FTP port command specifies an IP address and port for the recipient to
connect to.  A Vulnerable FTP implementation disregards the source address
of the packet containing the port command and is generally used by an attacker
to relay a connection through an FTP server.

So how do we detect this?
-------------------------

1) Regex and some perl

Detecting an ftp port bounce attack
-----------------------------------

1) Regex and some perl

   /PORT\s+(\d+),(\d+),(\d+),(\d+)/i

   Look for the word PORT, followed by any number of spaces,
   then any number of digits (store them for later), then a comma,
   then any number of digits (store them for later), then a comma,
   then any number of digits (store them for later), then a comma,
   then any number of digits (store them for later)

   $srcip ne $1.'.'.$2.'.'.$3.'.'.$4

   Then alert if the source ip of the packet is not the same as the
   first matched digits, followed by a dot, followed by the second
   matched digits, followed by a dot, followed by the third matched
   digits, followed by a dot, followed by the forth matched digit

Using the new keywords to detect an attempted attack
----------------------------------------------------
alert ip any any -> any any (perl:"$content =~ /port\s+(\d+),(\d+),(\d+),(\d+)/i && \
$srcip ne $1.'.'.$2.'.'.$3.'.'.$4";)

Optimizing the rule
-------------------
alert tcp any any -> any 21 ( flow:to_server,established; content:"port"; nocase; \
perl:"$content =~ /port\s+(\d+),(\d+),(\d+),(\d+)/i && $srcip ne \
$1.'.'.$2.'.'.$3.'.'.$4";)


HTTP Unknown Version
********************

04/06-20:04:12.457297 10.200.1.100:33599 -> 66.35.250.150:80
TCP TTL:64 TOS:0x0 ID:58321 IpLen:20 DgmLen:56 DF
***AP*** Seq: 0xDD594D3E  Ack: 0xAEE  Win: 0x1490  TcpLen: 20
47 45 54 20 2F 20 48 54 54 50 2F 30 2E 32 0A 0A  GET / HTTP/0.2..

Our content
-----------

GET / HTTP/0.2\n\n

Vulnerability condition
------------------------

The only valid HTTP versions are 0.9, 1.0 and 1.1.  A non-conforming
webserver could potentially accept an HTTP request with an invalid version
specified.

So how do we detect this?
-------------------------

1) Regex
2) Regex and some perl

Detecting an attack of against the overflow condition
-----------------------------------------------------

1) Regex

   /\s+HTTP/(0\.9|1\.1|1\.0)[\r]{0,1}\n/i

   Look for any number of space characters, followed by HTTP/, followed by 0.9, or
   1.1, or 1.0, followed by an optional \r, and then a \n

2) Regex and some perl

   $content =~ !\s+HTTP/(.{3})!i

   Look for any number of space characters, followed by HTTP/,, then store the next
   three characters for later.

   $1 ne '1.1' && $1 ne '1.0' && $1 ne '0.9'";

   Alert if the three characters are not 1.1, or 1.0, or 0.9.

Using the new keywords to detect an attempted attack
----------------------------------------------------

alert ip any any -> any any (perlre:/\s+HTTP/(0\.9|1\.1|1\.0)[\r]{0,1}\n/;)

alert ip any any -> any any (perl:"$content =~ !\s+HTTP/(.{3})! && $1 ne '1.1' && $1 \
ne '1.0' && $1 ne '0.9'";)

Optimizing the rules
--------------------

alert tcp any any -> any 80 (flow:to_server,established; content:"HTTP"; nocase; \
perlre:/\s+HTTP/(0\.9|1\.1|1\.0)[\r]{0,1}\n/i;)

alert tcp any any -> any 80 (flow:to_server,established; content:"HTTP"; nocase; \
perl:"$content =~ ! HTTP/(.{3})!i && $1 ne '1.1' && $1 ne '1.0' && $1 ne '0.9'";)


Creating a custom subroutine
****************************

After dozens of requests to the snort-users mailing list, here's a subroutine
that will send an email message when called.  Keep in mind that the cost of
sending the email message will be blocking the rest of the Snort process.  If
you're crazy enough to use this, add subroutine listed below to snort.pl.

sub insane {
 my ($srcip,$content) = @_;
  use Net::SMTP;
  my $server  = "mail.server.com"; my $email   = "perlfoo\@snort.org";
  my $smtp = Net::SMTP->new($server) || die "Can't connect to mail server";
 $smtp->mail($from); $smtp->to($to); $smtp->data();
 $smtp->datasend("To: $email\nFrom: $email\n");
 $smtp->datasend("Subject: perl alert - srcip = $srcip\n\n$content\n");
 $smtp->dataend(); $smtp->quit();
}

Using the subroutine in a rule
------------------------------

perl:"insane($srcip,$content)"




-
Send 'unsubscribe' in the body to 'list-request@inet-access.net' to leave.
Eat sushi frequently.   inet@inet-access.net is the human contact address.


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic