#!/usr/bin/perl # # snort2modsec.pl # mod_security, http://www.modsecurity.org/ # Copyright (c) 2002-2004 Ivan Ristic # # $Id: snort2modsec.pl,v 1.2.2.2 2006/02/13 21:51:34 ivanr Exp $ # # This script will convert Snort rules into the mod_security # rule format. Supply a list of files on the command line and # it will write mod_security rules to the standard output. # # See http://www.modsecurity.org/documentation/converted-snort-rules.html # for more information $DEFAULT_ACTION = "log,pass"; die("Usage: snort2modsec.pl \n") unless(@ARGV); foreach $file (@ARGV) { open(RULES, $file) or die( "Cannot open file: $file\n" ); LOOP: while() { next if(/^\s$/); next if(/^\#/); next if(!/\$HTTP_PORTS/); if (/\((.*)\)/) { $action = $1; $uricontent = ""; $content = ""; $msg = ""; $classtype = ""; $reference = ""; $sid = ""; foreach $rule (split(/;\s+/, $action)) { # print "$rule\n"; if ($rule =~ /uricontent:\s*\"(.*)\"/) { $uricontent = $1; } elsif ($rule =~ /content:\s*\"(.*)\"/) { $content = $1; } elsif ($rule =~ /msg:\s*\"(.*)\"/) { $msg = $1; } elsif ($rule =~ /classtype:\s*(.*)/) { $classtype = $1; } elsif ($rule =~ /sid:\s*(\d+)/) { $sid = $1; } elsif ($rule =~ /rev:\s*(\d+)/) { $rev = $1; } } # decode URL decoding $uricontent =~ s/%([a-fA-F0-9][a-fA-F0-9])/\\x$1/sg; $content =~ s/%([a-fA-F0-9][a-fA-F0-9])/\\x$1/sg; $uricontent =~ s/([][|()\$\^{}+?.])/\\\1/g; $content =~ s/([][|()\$\^{}+?.])/\\\1/g; # TODO decode |XX XX XX| content, for now # skip over the rules that are using it if ($content =~ /\|/) { next LOOP; } if ($uricontent =~ /\|/) { next LOOP; } print "# (sid $sid) $msg"; # if (!($reference eq "")) { # print ", $reference"; # } print "\n"; $action = $DEFAULT_ACTION; $meta = ""; if (!($sid eq "")) { $meta = "id:sid$sid"; if (!($rev eq "")) { $meta = $meta . ",rev:$rev"; } } if (!($msg eq "")) { # TODO escape msg $meta = $meta . ",msg:'$msg'"; } if (!($meta eq "")) { $joint = $action . "," . $meta; } if (!($uricontent eq "")) { if (!($content eq "")) { print "SecFilterSelective THE_REQUEST \"$uricontent\" \"$meta,chain\"\n"; print "SecFilter \"$content\" \"" . $action . "\""; } else { print "SecFilterSelective THE_REQUEST \"$uricontent\" \"" . $joint . "\""; } } else { print "SecFilter \"$content\" \"" . $joint . "\""; } #if ($classtype eq "web-application-activity") { # print " log,pass"; #} print "\n\n"; } } close(RULES); }