29 October, 2008

Snort shared object rules with Sguil

More and more Sourcefire VRT Snort rules are being released in the shared object (SO) rules format. As examples, Sourcefire released rules on 14 October that were designed to detect attacks targeting MS08-057, MS08-058, MS08-059, MS08-060, MS08-062, MS08-063 and MS08-065 vulnerabilities. On 23 October, Sourcefire released rules related to MS08-067, a vulnerability that has garnered a lot of attention.

It looks like all these recently released rules are SO rules. It is easy to tell a SO rule from a traditional Snort rule using the Generator ID, because SO rules use GID 3 while the old rule format uses GID 1.

Because Sourcefire is issuing all these rules in SO format, if you don't want to miss rules for recent vulnerabilities it is definitely important to test and implement the new format and keep the rules updated. When I implemented the rules in production, I used How to use shared object rules in Snort by Richard Bejtlich as a guide for adding shared object rules to Snort. It seems fairly complete and I was able to get the precompiled rules working on RHEL/CentOS.

Unfortunately, getting the rules working and updating them is not as simple and certainly not identical to updating rules that use the old format. Oinkmaster will edit the stub files to enable and disable the SO rules, but it requires running Oinkmaster a second time with a separate configuration file. From the Oinkmaster FAQ:

Q34: Can Oinkmaster update the shared object rules (so_rules)?

A34: Yes, but you have to run Oinkmaster separately with its own
configuration file. Copy your regular oinkmaster.conf file
to oinkmaster-so-rules.conf (or create a new one) and set
"rules_dir = so_rules". Then run Oinkmaster with
-C <path tooinkmaster-so-rules.conf> and use an output directory
(-o <dir>) different than your regular rules directory. This is
important as the "rules" and "so_rules" directories contains
files with identical filenames. See the Snort documentation on how
to use shared object rules. The shared object rules are currently
disabled by default so you have to use "enablesid" or "modifysid"
to activate the ones you want to use.
To update my rules, I first download the rules and run Oinkmaster to update my GID 1 rules. Then I extract the so_rules so I can run Snort with the '--dump-dynamic-rules' option. This will generate the required stub files, but they will not contain any changes you made to enable or disable specific rules. To change which are enabled or disabled, I run Oinkmaster again with the oinkmaster-so-rules.conf.

For Sguil to properly show the rule msg in the 'Event Message' column on the client, you must generate a new gen-msg.map file. David Bianco gave me a couple shell commands, one of which uses 'create-sidmap.pl' from the Oinkmaster contrib directory, to update the gen-msg.map file.
create-sidmap.pl ruledir/so_rules | perl -ne 'm/(\d+) \|\| ([^\|]+) \|\|/g; print "3 || $1 || $2\n";' > ruledir/so_rules/gen-msg.map

cat ruledir/gen-msg.map ruledir/so_rules/gen-msg.map | sort -n | uniq > ruledir/so_rules/gen-msg-merged.map
After you check that the new file is correct, it can be moved to overwrite the old gen-msg.map. The alert name will be found based on the GID and SID, so without the update you would only see the numerical GID and SID when viewing alerts in Sguil instead of the actual text of the alert message.

One last thing to do is get the "Show Rule" checkbox in Sguil to show the rule stub when viewing SO rules. A quick temporary fix is fairly simple. Either rename and place all the rule stub files in the directory on your sguild server with all the other rules, or use a symbolic link. Either way, you have to use alternate names since the SO rules stub files use the same naming scheme as the standard rule files.

Once that is done, it just requires a simple change to 'extdata.tcl' in the 'lib' directory of the Sguil client. Change the following line:
 if { $genID != "1" } {
 if { $genID != "1" && $genID != "3" } {
David Bianco pointed out that there is nothing to prevent SO rules and standard rules from sharing a SID since they have a different GID, so the above solution could get the wrong rule message if there are identical SIDs. He said he will probably add code to look in the ruledir for GID 1, and look in ruledir/so_rules for GID 3. This is definitely the better way and not too complicated, so hopefully Sguil CVS will have the code added in the near future.


  1. There should never be a duplicate SID. While there is nothing to prevent it in snort, our internal process is to make sure this doesn't happen.

    However, it is possible for a GID 3 SID X rule to become a GID 1 SID X rule.

  2. Your perl does not take into account the possibility that there may be a line that has no || after the actual message portion (SID 15433 is a good example). This causes odd results. For generic snort use:

    create-sidmap.pl so_rules/ | awk -F '|' '{print "3 || "$1" || "$3}'

    Works just fine. Yes this leaves out the cve,urls,etc.

  3. Ross, thanks for pointing that out! Yours is much simpler, too.