Information, OpenSourceSoftware, Security, Snort, Suricata

www.NetworkTotal.com

Twenty months ago, I wanted to try something out, and made a proof of concept in just 3 hours (thats including the time it took to buy the domain networktotal.com and point it to the IP!).

The concept was to have a place where one could upload a pcap, and have Snort and Suricata (and other tools), with all the different rule sets (VRT-Registered, VRT-Subscription, ET Open and ET PRO), parse through a pcap and display the result. Other engines like Bro could also be added etc…

It would be what VirusTotal is for binaries, just for pcaps…. I did not announce my project anywhere, and I just kept it private, but some of my friends knew about the place. So during the the first year, I counted around 250 pcaps uploaded from different places around the world (not bad for not announcing it!).

My personal usage of networktotal.com was more for taking random pcap at different places and uploading it to look for infections easy.

First off, I liked the NetworkTotal idea, but keeping the IDS engines up2date and the rulesets up2date took some time. Also, the way Suricata and Snort used to work, made it so that it took like 5 to 10 minutes to process a pcap on the old hardware that NT is running on :/ (You needed to start and stop the engines for each pcap, and just starting them up takes some time). So when Suricata went stable with their unix-socket support, meant that it would take me around a second to process a pcap with Suricata on my old hardware (Still 5 minutes with Snort). My subscription for VRT-Subscriber rules also ran out, so I dropped Snort for this setup, and I might add it back one day, but I would need more powerful hardware and a new VRT-S license…

But I started to develop the NetworkTotal backend code more on a host I set up at home. There where many goals with this, among learning about different NoSQL/Document stores which I find necessary in today’s world of data. I stared out with Cassandra, but needed fulltext, so I tried ElasticSearch (ES), but had some trouble using the Ruby Tire to do what I wanted. I ended up doing a MongoDB setup along side the ES setup, and kept that for about 8 months. But now I got ES to behave like I want to, but I still got lots to learn about ES.

Anyways, I have now ported NetworkTotal.com to only use Suricata with the Emerging Threats PRO rules. Processing of a pcap should normally take around a second and the events are stored in ElasticSearch. For all the malware I process at home with my cuckoo setup, I send the pcap in the form of <md5sum of the malware>.pcap to NetworkTotal.com, so you can search for events generated by a malware on NetworkTotal.com. As I don’t have storage to save all the pcaps, I do save some metadata in ElasticSearch. Mainly because I want to search up malware I upload based on events that fired, IPs that it talked to, domains it resolved, User-agent or URIs. This also uses disk space, so I wounder how long I can keep doing that too. Luckily, ElasticSearch scales linearly, so I’m hoping that will save me somehow…

Virustotal has also began to run pcaps through Snort and Suricata, but its not always that a malware produces a pcap, so there will be times that there are no events etc…

Here is an example from VT: https://www.virustotal.com/en/file/a7a526177c4475d47cdd49ea1b3ead2b/analysis/ where there is no snort or suricata events from the network traffic. You can search for the same md5sum on NetworkTotal.com where there is a rule that tags this as SpyEye fires : http://www.networktotal.com/search.php?q=a7a526177c4475d47cdd49ea1b3ead2b

I made a simple bash-scripts to upload a pcap to NetworkTotal and one to Search for IDS Events on NetworkTotal.

Example of the search bash-script output:

$ nt-search.sh a7a526177c4475d47cdd49ea1b3ead2b
[i] Result URL: http://networktotal.com/search.php?q=a7a526177c4475d47cdd49ea1b3ead2b&json=1
[i] Results:
{
“events”: [
“[1:2012686:4] ET TROJAN SpyEye Checkin version 1.3.25 or later“,
“[1:2010706:8] ET USER_AGENTS Internet Explorer 6 in use – Significant Security Risk”,
“[1:2406376:303] ET RBN Known Russian Business Network IP (189)”
],
“md5”: “a7a526177c4475d47cdd49ea1b3ead2b”
}

I still have some more stuff to fix in the backend code, but having started to write this blog post for about 18 months ago, I figured Ill just blog it, and write updates as they come πŸ™‚

I’ll see if I can make my cuckoo module more generic and share that, ( it uploads the <malware-md5sum>.pcap to NT and gets back the events that fired).

Again, I hope this is useful for anyone out there. Suggestions on improvements are also appreciated πŸ™‚ Im also open to discuss what more data could be displayed publicly without showing off information from the uploaded pcaps that can be somehow sensitive (like Microsoft registration keys encoded in the URI of a malware checkin, or the name of a company etc.).

Advertisement
Standard
Information, OpenSourceSoftware, Security, Snort, Sourcefire, Suricata

Suricata and some phun with flowints

I have been looking into malware traffic that is hard to make signatures for in a “regular” way. I’m not a malware reverser, so I don’t dig into a malware to determine byte-testes and jumps etc. in binary protocols. This lead me to use a lot of flowbits at first, for making my sigs, but the performance in Snort and Suricata was “crap” to say it nice. So I talked to Victor Julien, lead programmer of Suricata, discussing implementing packet and byte counting in Suricata. I want to count each packet sent by a client and server and the total amount of bytes sent by client and server. Talking back and forth, Victor convinced me that I might be best to go for byte count for reassembled streams. So I added a feature request to Suricata. I since then updated the feature request to add the packet and byte counters, as I think they will do great use.

Talking to Matt Jonkman (Emerging Threats Pro), he pointed me to flowint in Suricata to try to solve my packet counting. So in Suricata 1.1.1, you can do something like this to initialize the packet counters:

# Initialize the packet counter (Suricata 1.1.1 and some older versions)
#alert ip $HOME_NET any -> $EXTERNAL_NET any (msg:”Generic Client Established Flow IP Packet Counter set”; flow:established,from_client; flowint:client_packet,notset; flowint:client_packet,=,0; flowbits:noalert; classtype:not-suspicious; sid:1; rev:1;)

#alert ip $EXTERNAL_NET any -> $HOME_NET any (msg:”Generic Server Established Flow IP Packet Counter set”; flow:established,from_server; flowint:server_packet,notset; flowint:server_packet,=,0; flowbits:noalert; classtype:not-suspicious; sid:2; rev:1;)

In Suricata 1.2dev (rev 4c1e417) (I did my test for the blog on this version) and newer, you dont need to initialize the counter, as it will automagical be initialized to zero, so you don’t need sid:1 and sid:2:

## Generic packet counter: (This could be better done internally in Suricata/Snort? and not with rules?)
alert ip $HOME_NET any -> $EXTERNAL_NET any (msg:”Generic Client Established Flow IP Packet Counter”; flow:established,from_client; flowint:client_packet,+,1; flowbits:noalert; classtype:not-suspicious; sid:3; rev:1;)

alert ip $EXTERNAL_NET any -> $HOME_NET any (msg:”Generic Server Established Flow IP Packet Counter”; flow:established,from_server; flowint:server_packet,+,1; flowbits:noalert; classtype:not-suspicious; sid:4; rev:1;)

So, what can you do with packet counters?

First off, lets look at some generic rules I made up to test with, which basically should limit the detections in streams to the first 29 packets from the client:

# GENERiC GET
alert http $HOME_NET any -> $EXTERNAL_NET any (msg:”GENERIC GET (classic)”; flow:from_client,established; content:”GET “; depth:4; content:!”connection: keep-alive”; nocase; http_header; classtype:not-suspicious; sid:5; rev:1;)

alert http $HOME_NET any -> $EXTERNAL_NET any (msg:”GENERIC GET (flowint)”; flow:from_client,established; flowint:client_packet,<,30; content:”GET “; depth:4; content:!”connection: keep-alive”; nocase; http_header; classtype:not-suspicious; sid:6; rev:1;)

# GENERiC UA
alert http $HOME_NET any -> $EXTERNAL_NET any (msg:”GENERIC User-Agent (classic)”; flow:from_client,established; content:”User-Agent: “; http_header; content:!”connection: keep-alive”; nocase; http_header; classtype:not-suspicious; sid:7; rev:1;)

alert http $HOME_NET any -> $EXTERNAL_NET any (msg:”GENERIC User-Agent (flowint)”; flow:from_client,established; flowint:client_packet,<,30; content:”User-Agent: “; http_header; content:!”connection: keep-alive”; nocase; http_header; classtype:not-suspicious; sid:8; rev:1;)

Sid 5 and 6 looks for a HTTP GET request that is not a HTTP keep-alive. Sid 7 and 8 is looking for User-Agent in non HTTP keep-alive request. Common for the flowint versions of the rules, are that they are just limited to the first 29 packets in an established flow. So running Suricata against 2009-04-20-09-05-46.dmp etc. shows some interesting results:

Num Rule Gid Rev Ticks % Checks Matches Max Ticks Avg Ticks Avg Match Avg No Match
——– ———— ——– ——– ———— —— ——– ——– ———– ———– ———– ————–
1 4 1 1 1695335708 67.74 510720 510720 6412616 3319.50 3319.50 0.00
2 3 1 1 581354624 23.23 508970 82175 3602972 1142.22 3061.99 772.59
3 7 1 1 135943292 5.43 7900 2352 499972 17208.01 16156.62 17653.74
4 5 1 1 43040648 1.72 3313 2517 199052 12991.44 16247.74 2694.82
5 8 1 1 29172972 1.17 7900 2352 434592 3692.78 6588.51 2465.18
6 6 1 1 17917112 0.72 3313 2517 353684 5408.12 6528.93 1864.06

Sorry for the formating πŸ™‚
First, if we look at sid 5 and 6, we see that they both where checked 3313 times, and matched 2517 times. If we look at total ticks, sid 5 uses 43040648 ticks and sid 6 (flowint) uses 17917112 ticks. Average ticks for sid 5 is 12991.44 ticks and 5408.12 ticks for sid 6 (flowint).

Looking at sid 7 and 8, we see that they both where checked 7900 times, and matched 2352 times. If we look at total ticks, sid 7 uses 135943292 ticks and sid 8 (flowint) uses 29172972 ticks. Average ticks for sid 7 is 17208.01 ticks and 3692.78 ticks for sid 8 (flowint).

A basic conclusion for this test, is that the rules with the flowint check are faster and will give you the same alerts.
But if we look at the ticks sid 3 and 4 uses to count the all the packets, they are high in total, but low on average ticks. So they are not expensive for each check, but since they are checked (and possibly incremented) for each packet, the total ticks are relative high. Having this in the core of Suricata and Snort, would probably make them less expensive (hint hint).

So what more c00l stuff can we do with packet counters?

Some malware I stumbled upon will give you an example (Mostly used in the Gheg Spam bot, aka Tofsee/Mondera)
b31e4624cdc45655b468921823e1b72b
3c453e40ff63da3c2a914c29b6c62ee0
e8034335afb724d8fe043166ba57cd23

It seems to communicate in a binary way (encrypted), but looking at 5 different pcaps I got, I saw a pattern and my flowint counters came to good use. It seems like the client and server sends packets with a specific payload size in different parts of the communication. I did not see any obvious content to match on, so content matches didn’t seem trivial, and this is a great way to demonstrate my point: Flowint+packet counters to the rescue! Here is a tcpdump output of traffic on port 443 (not including the port 22050 traffic, which is much longer, but the start is the same), so you can see the packets sizes and in which order they do come in this short sessions:

reading from file b31e4624cdc45655b468921823e1b72b.pcap, link-type EN10MB (Ethernet)
03:47:02.571111 IP 192.168.1.10.1031 > 216.246.8.230.443: Flags [S], seq 910650996, win 65535, options [mss 1460,nop,nop,sackOK], length 0
03:47:02.608784 IP 216.246.8.230.443 > 192.168.1.10.1031: Flags [S.], seq 442582883, ack 910650997, win 5840, options [mss 1380,nop,nop,sackOK], length 0
03:47:02.608977 IP 192.168.1.10.1031 > 216.246.8.230.443: Flags [.], ack 1, win 65535, length 0
03:47:02.646959 IP 216.246.8.230.443 > 192.168.1.10.1031: Flags [P.], seq 1:201, ack 1, win 5840, length 200
03:47:02.647342 IP 192.168.1.10.1031 > 216.246.8.230.443: Flags [P.], seq 1:142, ack 201, win 65335, length 141
03:47:02.685098 IP 216.246.8.230.443 > 192.168.1.10.1031: Flags [.], ack 142, win 6432, length 0
03:47:02.718986 IP 216.246.8.230.443 > 192.168.1.10.1031: Flags [P.], seq 201:676, ack 142, win 6432, length 475
03:47:02.718999 IP 216.246.8.230.443 > 192.168.1.10.1031: Flags [F.], seq 676, ack 142, win 6432, length 0
03:47:02.719268 IP 192.168.1.10.1031 > 216.246.8.230.443: Flags [.], ack 677, win 64860, length 0
03:47:02.719584 IP 192.168.1.10.1031 > 216.246.8.230.443: Flags [F.], seq 142, ack 677, win 64860, length 0
03:47:02.757350 IP 216.246.8.230.443 > 192.168.1.10.1031: Flags [.], ack 143, win 6432, length 0

And here is how I sigged it:

# Backdoor:Win32/Tofsee (aka: Gheg / Mondera)
alert tcp $EXTERNAL_NET any -> $HOME_NET any (msg:”Possible Tofsee server Packet 2 (200 Bytes)”; flow:established,from_server; flowint:server_packet,=,2; dsize:200; flowbits:set,Tofsee_SERVER_200; flowbits:noalert; classtype:trojan-activity; sid:9; rev:1;)

alert tcp $HOME_NET any -> $EXTERNAL_NET any (msg:”Possible Tofsee client Packet 3 (141 Bytes)”; flow:established,from_client; flowint:client_packet,=,3; dsize:141; flowbits:isset,Tofsee_SERVER_200; flowbits:set,Tofsee_CLIENT_141; flowbits:noalert; classtype:trojan-activity; sid:10; rev:1;)

alert tcp $EXTERNAL_NET any -> $HOME_NET any (msg:”Possible Tofsee server Packet 4(475 Bytes)”; flow:established,from_server; flowint:server_packet,=,4; dsize:475; flowbits:isset,Tofsee_CLIENT_141; classtype:trojan-activity; sid:11; rev:1;)

Sid 9 looks only for the 2. packet in an established flow from the Server (C&C) and the packet has to have payload size/dsize 200. It then sets the flowbit Tofsee_SERVER_200 if this hits and the rule has noalert, because this could easily trigger a false positive just this check. So we got to do some more checks. Sid 10 checks only Client packet 3, it has to have a payload size/dsize of 141 and flowbit Tofsee_SERVER_200 has to be set for this too match. Sid 10 is also no alert, as we still can check some more, to not be spammed by falses. So sid 11 checks if server packet 4 has payload size/dsize 475, and that flowbit Tofsee_CLIENT_141 is set. No we can give an alert, as this would probably be an unique set of conditions. So testing again with out 2009-04-20-09-05-46.dmp test pcap, we get:

Num Rule Gid Rev Ticks % Checks Matches Max Ticks Avg Ticks Avg Match Avg No Match
——– ———— ——– ——– ———— —— ——– ——– ———– ———– ———– ————–
1 4 1 1 1727862376 63.39 510720 510720 14059784 3383.19 3383.19 0.00
2 3 1 1 508719672 18.66 508970 82176 3689732 999.51 2830.58 646.95
3 7 1 1 140271824 5.15 7900 2352 1013800 17755.93 18570.93 17410.42
4 9 1 1 101662288 3.73 28419 0 6625384 3577.26 0.00 3577.26
5 11 1 1 84264720 3.09 32938 0 612848 2558.28 0.00 2558.28
6 10 1 1 71553560 2.62 32938 0 576132 2172.37 0.00 2172.37
7 5 1 1 42053248 1.54 3313 2517 805736 12693.40 15831.10 2771.81
8 8 1 1 31547660 1.16 7900 2352 153972 3993.37 7039.04 2702.21
9 6 1 1 17944504 0.66 3313 2517 292508 5416.39 6476.95 2062.83

Overall, sid 9, 10 and 11 did not do that bad here. And the best thing is, they all have 0 matches. I ran this on many of my test pcaps, and I’ve not been close to false positives. Sid 10 seems to fire some times, but not the others, so rather unique combo of packets in a stream I guess and a way to sig malware like this. Also, we could add check for the TCP “PUSH” flag in sid 9, 10 and 11 etc to be more accurate if we need.

So the proof of the pudding, running it against a pcap of the malware:

Num Rule Gid Rev Ticks % Checks Matches Max Ticks Avg Ticks Avg Match Avg No Match
——– ———— ——– ——– ———— —— ——– ——– ———– ———– ———– ————–
1 3 1 1 443120 33.03 165 158 102108 2685.58 2731.72 1644.00
2 11 1 1 310420 23.14 259 2 2860 1198.53 2478.00 1188.58
3 4 1 1 302944 22.58 269 269 15376 1126.19 1126.19 0.00
4 10 1 1 257896 19.22 259 3 16484 995.74 7446.67 920.14
5 9 1 1 27088 2.02 10 3 7448 2708.80 5080.00 1692.57

Events:

[**] [1:11:1] Possible Tofsee server Packet 4(475 Bytes) [**] {TCP} 216.246.8.230:443 -> 192.168.1.10:1031
[**] [1:11:1] Possible Tofsee server Packet 4(475 Bytes) [**] {TCP} 84.16.252.136:22050 -> 192.168.1.10:1032

My Tofsee rules fire on all 5 pcaps I looked at initially (and lots more pcaps I tested after that), so hopefully it will fire on all current Tofsee traffic.

I also replied on an e-mail to the snort-user list 3. of November, making the same feature request as I did for Suricata. No one followed up :/ The email should probably be directed to the snort-devel list some time in the future…

I hope this post has been useful, and hopefully we can get some more flowint rules out there, and maybe even get native packet and byte counting in Snort and Suricata one day πŸ™‚

Standard
Debian, Information, Linux Distributions, OpenSourceSoftware, Security, Sguil, Suricata, Ubuntu

OISF Suricata 1.1.0 beta 1 debian package for Ubuntu 10.04

I also got time to put together a package for the latest version of Suricata, namely 1.1 beta1.

My plan was to stick to a stable version when OISF released 1.0.3, but they skipped that, and went for a 1.1 release instead.
As I also try to help out where I can, I don’t mind running beta software, and reporting bugs etc. when and if I can. I’ll probably pack beta2 and so on until OISF hits a stable release, and then I’ll stick with that in my gamelinux PPA. So until then, I hope you try out Suricata with me on the quest for a stable release πŸ™‚

Read more about suricata 1.1 beta 1 here.

Standard
Debian, Linux Distributions, OpenSourceSoftware, Security, Sguil, Snort, Suricata, Ubuntu

Sourcefire daq-0.4 and Snort-2.9.0.2 debian packages for Ubuntu 10.04

Moving to the new Snort 2.9 version, it added dependencies on a new library, namely DAQ(Data Acquisition library) for packet I/O.

So the little extra of packaging a new deb (daq) and check snort-debian files that they where compliant to the new version, made me debianize Suricata instead, as I saw that as quicker way to get an IDS up and running on my new firewall at home.

Now that I have suricata in place, plus some extra time last night, and I see people struggling trying to install/upgrade to Snort 2.9 on Ubuntu, I could not help my self trying to be helpful, again…

So I made debian packages and put them in my Ubuntu 10.04 Lucid PPA on launchpad. I started a new clean debian package for Snort. Its not yet packed with “debian-easy-features”, so it just installs Snort, makes the directories and adds some default configuration files. I will improve this as I go.

DAQ is built with:

Build AFPacket DAQ module.. : yes
Build Dump DAQ module…… : yes
Build IPFW DAQ module…… : yes
Build IPQ DAQ module……. : no
Build NFQ DAQ module……. : no
Build PCAP DAQ module…… : yes

And Snort is compiled with:

–enable-perfprofiling
–enable-ipv6
–enable-sourcefire
–enable-dynamicplugin
–enable-targetbased
–enable-zlib
–enable-ppm
–enable-gre
–enable-mpls
–enable-decoder-preprocessor-rules
–without-mysql
–without-postgresql

So, if you add my PPA, you apt-get install snort version 2.9.0.2. Pronto though, Snort 2.9.0.3 will be out, and I’ll upgrade accordingly. Suricata will also soon be out in 1.0.3, hopefully this week. Maybe we get fresh releases from this Santa for both engines πŸ™‚

Until then,

-*> Snort! <*-
Version 2.9.0.2 IPv6 GRE (Build 92)
By Martin Roesch & The Snort Team: http://www.snort.org/snort/snort-team
Copyright (C) 1998-2010 Sourcefire, Inc., et al.
Using libpcap version 1.0.0
Using PCRE version: 7.8 2008-09-05
Using ZLIB version: 1.2.3.3

Standard
Debian, forensics, Information, Linux Distributions, OpenSourceSoftware, Suricata, Ubuntu

Suricata 1.0.2 Debian/Ubuntu package

In stead of compiling Suricata over and over again on different hosts I have… I just made a debian package for my Ubuntu Lucid 10.04 systems.

Its a simple build, and Ill hopefully update it with time to incorporate different usage and install help etc.
Right now its just aimed at being a simple IDS using libpcap.

You can find suricata and other cool NSM stuff at my gamelinux PPA found here.

apt-get install suricata
cd /etc/suricata/ && wget http://rules.emergingthreats.net/open/suricata/emerging.rules.tar.gz
vim /etc/default/suricata
vim /etc/suricata/suricata.yaml
/etc/init.d/suricata start

Feedback and thoughts are welcome and needed πŸ™‚ !

Standard
cxtracker, daemonlogger, Debian, forensics, Linux Distributions, OpenSourceSoftware, PADS, Security, Sguil, Snort, Suricata, Ubuntu

Ubuntu repo for sguil

I have spent the last week setting up a Ubuntu Launchpad PPA for my packages I used to hoste here on my blog.

The URL to my PPA is : https://launchpad.net/~ebf0/+archive/gamelinux

I pack the packages mainly for Lucid Lynx 10.04.
To try them out, you can add the following in /etc/apt/sources.list:
deb http://ppa.launchpad.net/ebf0/gamelinux/ubuntu lucid main
deb-src http://ppa.launchpad.net/ebf0/gamelinux/ubuntu lucid main

To add my key to you Ubuntu installation:
apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 4B04D050

Then you should be able to apt-get update, and then apt-get install my packages πŸ™‚

Please try them out and give me feedback!
You will find my howto on how to configure them here.

Happy F8’ing!

Standard
Information, Linux Distributions, OpenSourceSoftware, Security, Sguil, Snort, Sourcefire, Suricata

Some notes on “making Snort go fast under Linux”

These are general pointers too things you want to dig into when you need to optimize Snort. If you are one of those who believe that Snort can’t go beyond 100Mbit/s and still not drop packets, you should read on. Comments/feedback/new tips/corrections on how to tune a Snort system is very welcome.

–[ Optimize the hardware ]–
This is always a moving target… And you need to keep yourself updated on the topic and pay attention when you buy your hardware. If someone in the community is maintaining a updated list of such hardware, give me a note!

Intel Network Interface Controllers(NIC) are the off the shelf choice of network adapters, 825NNXX PCI Express series with minimum TCP segmentation offload, TCP, UDP, IPv4 checksum offload, interrupt moderation, and maybe Bypass if you use inline mode/IPS.

If you want to pay someone that already has researched a bit (pure speculation from my side), then maybe Endace could be a choice. But if you first go there, then why not just go straight to Sourcefire (The makers of Snort).

(Matt Jonkman states that you can increase your Snort throughput up to a 16-fold increase if you introduce Endace platform’s acceleration features. Matt is the founder of Emerging Threats, and also deep into the OISF and the Suricata project)

At one time (early 2009), a discussion on IRC (Freenode) summed up in something like this:
“IICH8 southbridge, and 975G north bridge performing at 1066MHz, 8GB of 1333MHz DDR2 ram on a Intel quad core 3.2Ghz 8MB L2 cache processor running at 1333 MHz FSB and Intel 825NNXX PCI Express Gigabit Ethernet Controller.” – for a high end sniffer at that time.

Your whole system would benefit great from fast hard drives, as I/O too hard drives generally sucks juice, and locks up the system.

To sum it up:
Fast CPUs, fast RAM, fast buses, fast hard drives and a good network adapter.

–[ Optimize the Linux kernel ]–
In the file /etc/sysctl.conf – you should consider options like these:

# Just sniffing:
net.core.netdev_max_backlog = 10000
net.core.r mem_default = 16777216
net.core.rmem_max = 33554432
net.ipv4.tcp_mem = 194688 259584 389376
net.ipv4.tcp_rmem = 1048576 4194304 33554432
net.ipv4.tcp_no_metrics_save = 1
# IF also in Inline mode:
net.core.wmem_default = 16777216
net.core.wmem_max = 33554432
net.ipv4.tcp_wmem = 1048576 4194304 16777216
# Memory handling – not that important
vm.overcommit_memory=2
vm.overcommit_ratio = 50

–[ Optimize your network interface card ]–
Change the RX and TX parameters for the interfaces. The following command will display the current settings and the maximum settings you can bump them up to.

# ethtool -g ethX

To change settings, the command is something like this:

# Just sniffing
ethtool -G ethX rx
# and for inline mode, also add
ethtool -G ethX tx

Adding the command to /etc/rc.d/rc.local so that they are execute automatically when you boot would be a good idea.

–[ Optimize Snort ]–
Snorts performance is based on several factors.
1 – YOUR network!
2 – How snort is compiled
3 – Preprocessors enabled
4 – Rules
5 – Snort in general and snort.conf

–[ 1. YOUR network! ]–
Your network is a variable that is most likely not like any other networks. The amount of concurrent connections, packets and packet size flowing through, is most likely unique. Also, depending on the payload in your packets, Snort will perform differently. Also, if your $HOME_NET is one single host, compared to complex list of “networks” and “!networks”, Snort will spend more time figuring out what to do.

–[ 2. How snort is compiled ]–
First, I recommend only to compile Snort with the options that you need. I used to compile Snort in two different ways, one including options among “–enable-ppm and –enable-perfprofiling” and one without. But as my sensors are not suffering enough at the moment, I include them both by default, for easy access to preprocessor and rule performance data if I need too.

Also, I have not confirmed this, because its out of my budged reach, but the rumors are that Snort performs up to 30% better if it is compiled with an Intel C compiler (and probably run on pure Intel hardware).

If you use Phil Wood mmap libpcap and compile Snort with that, you will get some better performance in the packetcapture, giving you less dropped packets. I nice writeup/howto is found here.

–[ 3 – Preprocessors enabled ]–
How many and which preprocessors you have enabled is also playing a role on the total performance of your system. So if you can, you need to reduce the numbers of preprocessor to a minimum. Also you need to read the Snort documentation, and figure out the best settings that you can live with for each preprocessors that takes configuration options. The flow_depth parameter in the http_inspect preprocessor is a good example.

Here are two settings/views I switch between when profiling preprocessors:

config profile_preprocs: print 20, sort avg_ticks, filename /tmp/preprocs_20-avg_stats.log append
# And
config profile_preprocs: print all, sort total_ticks, filename /tmp/preprocs_All-total_stats.log append

You should now review the *stats.log files and make changes based on your interpretation, and profile again to see if things get better or worse.

–[ 4 – Rules ]–
The amount of rules also affects the performance of Snort. So tuning your rules to just enable the ones that you need is essential when aiming for performance.
Also, how a rule is performing on your network, might defer from how it performs in my network… That said, you need to profile your set off rules, and tweak or disable them so your system uses less overall “ticks”.

Here are two settings/views I switch between when profiling rules:

config profile_rules: print 20, sort avg_ticks, filename /tmp/rules_20-avg_stats.log append
# And
config profile_rules: print all, sort total_ticks, filename /tmp/rules_All-total_stats.log append

You will get a fairly good view of rules that needs/should/would benefit from tuning/disabling.

–[ 5 – snort in general and snort.conf ]–
* search-method
You should look into which search-method snort is using. The default search method is AC-BNFA (Aho-Corasick NFA – low memory, high performance). This is probably the best overall search method, but if you have the RAM for it, AC (Aho-Corasick Full – high memory, best performance) would be a better choice. Snort 2.8.6 added a new pattern matcher named AC-SPLIT. The new pattern matcher is optimized to use less memory and perform at AC speed. This would probably the choice for the future? Need to test right away πŸ™‚
To enable it, add something like:

config detection: search-method ac-split, max-pattern-len 20,
search-optimize

* Latency-Based Packet Handling
If you have a problem with dropped packets, I would say over 1% on an average, I would recommend enabling Latency-Based Packet Handling. You should run some tests in your environment to find a value that works for you, but the general situation is like this:
If your Snort “Packet Performance Summary” is telling you that your “avg pkt time is 10 usecs” then Snort can inspect about 1000 packets in 10000 usecs. If a packet for some reason is using 10000 usec to get through Snort, you may have dropped/sacrificed 1000 other packets in that time frame, just to inspect this packet. So if you configure max-pkt-time to be 1000, Snort will stop inspecting packets that take more time than 1000 usec, and in this basic example leaving you with 100 dropped packets instead of 1000. You choose! (The example is not technical correct, as a packet can take over 10000 usec with out Snort dropping any packets at all (Imagine if there is only one packet going through snort that day…), but in my tests, this is more or less the real world outcome of enabling Latency-Based Packet Handling).
Example:

config ppm: max-pkt-time 10000, fastpath-expensive-packets, pkt-log

Other keywords you should be aware off in the Snort config, that I don’t want to go into details about, as I don’t have enough Snort-Fu about to stand firm, and the doc is rather lacking! I have a personal understanding of what they do, and how it effects performance etc. but if anyone has some nice writeup of the topics, please point me to it!! :
* Event Queue Configuration
* Latency-Based Rule Handling

–[ Additional notes ]–
Obviously, if you need to go as fast as possible, your system should not be used for lots of other different stuff. So keep your running processes/services too a minimum.

Snort is also, as far as I can tell, single threaded when it comes too packet inspection. There is a pdf here from Intel, explaining how Sensory Networks Software Acceleration Solutions boost performance of Snort and things alike, making them Multi-core enabled/aware.

That said, Snort benefits from sticking to one CPU, so using schedtool in a proper way, might help snort perform overall better. If you are running multiple instances of Snort on one multi-CPU server, you should use schedtool to stick each Snort process to its own physical CPU etc. Example:

$ man schedtool # and read about “AFFINITY MASK” and understand the difference between cpu-cores and hyper-threading etc.
$ schedtool <pid of snort> # Displays current settings
$ schedtool -a 0x01 <pid of snort> # Pin the snort process to one CPU (The first)
$ schedtool -M 2 -p 10 # Change the policy to SCHED_RR and set priority to 10 (0 highest, 100 lowest)
$ schedtool <pid of snort> # to verify your changes

Always when optimizing a system, you should have some sort of measuring system. I use Munin. I wrote some basic Munin plugins for Snort which monitors the most important stuff.

And as always,
“Measure, don’t speculate” — Unknown
“Premature optimization is the root of all evil” — Tony Hoare

Standard
Information, OpenSourceSoftware, Security, Sguil, Snort, Sourcefire, Suricata

sidrule update (yes, so soon!)

I friend of mine at Sourcefire, jim, made some comments yesterday on my little bash-script. He wanted to be able to search through the msg field in a snort rule, and be able to activate or deactivate based on the search.

Also after having Alex Kirks last blogpost fresh in mind, I had the thought on enabling rules based on one of the three default policies Sourcefire maintain – Connectivity Over Security, Balanced, and Security Over Connectivity. And since all the logic was done, why not just add support for classtype as well…

So, I added three new ways too search through the rules, using the msg,classtype and metadata fields.

And you can enable or disable rules in a bunch, say all rules that has “RPC portmap” in the msg field, or “Security Over Connectivity” in the metadata field. And also by classtype, say “attempted-user” or “attempted-admin”.

The script also supports walking through the bunch of rules and enabling/disabling/skipping(don’t do anything) rule by rule.

# sidrule -p policy security-ips drop
Bash’ed together by edward.fjellskal@redpill-linpro.com

[*] Found 4224 rules in 39 rule files.
[*] Searchterm: metadata:”policy security-ips drop”
[*] Disable ALL rules (y/N)?
[*] Enable ALL rules (y/N)?
[*] Enable/Disable rule by rule (y/N)?

# sidrule -s RPC portmap proxy
Bash’ed together by edward.fjellskal@redpill-linpro.com

[*] Found 4 rules in 1 rule files.
[*] Searchterm: msg:”RPC portmap proxy”
[*] Disable ALL rules (y/N)?
[*] Enable ALL rules (y/N)?
[*] Enable/Disable rule by rule (y/N)?

# sidrule -c attempted-admin
Bash’ed together by edward.fjellskal@redpill-linpro.com

[*] Found 894 rules in 41 rule files.
[*] Searchterm: classtype:”attempted-admin”
[*] Disable ALL rules (y/N)?
[*] Enable ALL rules (y/N)?
[*] Enable/Disable rule by rule (y/N)? y
[*] Getting sids from 41 file(s).
[*] (1/41) Getting sids from file: /etc/snort/rules/backdoor.rules
[*] (2/41) Getting sids from file: /etc/snort/rules/bad-traffic.rules
………
[*] (40/41) Getting sids from file: /etc/snort/rules/web-misc.rules
[*] (41/41) Getting sids from file: /etc/snort/rules/web-php.rules
[*] In file: /etc/snort/rules/backdoor.rules
[*] alert tcp $EXTERNAL_NET any -> $TELNET_SERVERS 23 (msg:”BACKDOOR w00w00 attempt”; flow:to_server,established; content:”w00w00″; metadata:policy security-ips drop; reference:arachnids,510; classtype:attempted-admin; sid:209; rev:5;)
[*] Rule 1 of 894
[*] Disable/Enable/Skip rule (d/e/S)?S
[*] Not processing rule..
……….

When I started working on this yesterday, I saw that I should rather do all this in perl, but I decided that since I had started it in bash(+sed), I should just finish this version in bash. I need to practice my bash too!

Maybe one day I’ll redo it in perl or something… But not today πŸ™‚
There code is still here.

Enjoy, Jim!

Standard
Information, OpenSourceSoftware, Security, Sguil, Snort, Suricata

sidrule – A simple and fast way to Enable, Disable or Display a Snort/Emerging Threats/Suricata rule

On my private servers and home machines etc. (even my laptop), I run snort.

I got tired of spawning vim to edit a rule file (disabling/enabling) or sometimes just to read a rule for joy and pleasure…

So I made a simple bash-script to solve my small needs…
Output from sidrule:

# sidrule
Bash’ed together by edward.fjellskal@redpill-linpro.com
Usage:
sidrule [list|enable|disable] sid
or
sidrule [ -l | -e | -d ] sid

# sidrule list 15363
[*] In file: /etc/snort/rules/web-client.rules
[*] alert tcp $EXTERNAL_NET $HTTP_PORTS -> $HOME_NET any (msg:”WEB-CLIENT Potential obfuscated javascript eval unescape attack attempt”; flow:established,to_client; content:”eval|28|”; nocase; content:”unescape|28|”; within:15; nocase; content:!”|29|”; within:250; metadata:policy balanced-ips alert, policy security-ips alert, service http; reference:url,cansecwest.com/slides07/csw07-nazario.pdf; reference:url,www.cs.ucsb.edu/~marco/blog/2008/10/dom-based-obfuscation-in-malicious-javascript.html; classtype:misc-activity; sid:15363; rev:1;)

# sidrule disable 15363

[*] Found sid:15363 in /etc/snort/rules/web-client.rules:
[*] Disabling:
[*] #alert tcp $EXTERNAL_NET $HTTP_PORTS -> $HOME_NET any (msg:”WEB-CLIENT Potential obfuscated javascript eval unescape attack attempt”; flow:established,to_client; content:”eval|28|”; nocase; content:”unescape|28|”; within:15; nocase; content:!”|29|”; within:250; metadata:policy balanced-ips alert, policy security-ips alert, service http; reference:url,cansecwest.com/slides07/csw07-nazario.pdf; reference:url,www.cs.ucsb.edu/~marco/blog/2008/10/dom-based-obfuscation-in-malicious-javascript.html; classtype:misc-activity; sid:15363; rev:1;)

# sidrule enable 15363

[*] Found sid:15363 in /etc/snort/rules/web-client.rules
[*] Enabling:
[*] alert tcp $EXTERNAL_NET $HTTP_PORTS -;gt& $HOME_NET any (msg:”WEB-CLIENT Potential obfuscated javascript eval unescape attack attempt”; flow:established,to_client; content:”eval|28|”; nocase; content:”unescape|28|”; within:15; nocase; content:!”|29|”; within:250; metadata:policy balanced-ips alert, policy security-ips alert, service http; reference:url,cansecwest.com/slides07/csw07-nazario.pdf; reference:url,www.cs.ucsb.edu/~marco/blog/2008/10/dom-based-obfuscation-in-malicious-javascript.html; classtype:misc-activity; sid:15363; rev:1;)

The git repo is on github.com/gamelinux/sidrule
git clone http://github.com/gamelinux/sidrule.git

Hope you find it usefull!

Standard