#!/usr/bin/perl -w # # nessus2modsec.pl # mod_security, http://www.modsecurity.org/ # Copyright (c) 2004 Javier Fernandez-Sanguino # # $Id: nessus2modsec.pl,v 1.1 2005/06/06 15:33:29 ivanr Exp $ # # This script will convert Nessus plugins (.nasl) into the mod_security # rule format. Supply a list of plugins on the command line and # it will write mod_security rules to the standard output. # # To create an up-to-date set of rules, follow # these steps: # # wget http://www.nessus.org/nasl/all-2.0.tar.gz # mkdir plugins # cd plugins && tar zxvf ../all-2.0.tar.gz # ./nessus2modsec.pl plugins/* > nessusmodsec-rules.txt # die("Usage: nessus2modsec.pl \n") unless(@ARGV); foreach $dir (@ARGV) { read_plugins($dir) } exit 0; sub read_plugins { my ($dir) = @_; opendir (DIR, $dir) or die ("Cannot open directory $dir: $!\n"); foreach $file (readdir(DIR)) { parse_plugin($dir, $file) if -f $dir."/".$file; } return 0 } sub parse_plugin { my ($dir,$file) = @_; open(PLUGIN, $dir."/".$file) or die( "Cannot open file $file: $!\n" ); my $id = ""; my $name = ""; my $btq = ""; my $cve = ""; my $content = ""; my $uricontent = ""; LOOP: while() { chomp; next if(/^\s$/); next if(/^\#/); if (/script_id\(\s*(\d+)\s*\)/) { $id = $1; } if (/name\["english"\]\s*=\s*"(.*)"/) { $name = $1; } if (/script_bugtraq_id\(\s*(.*)\s*\)/) { $btq = $1; } if (/script_cve_id\(\s*(.*)\s*\)/) { $cve = $1; } next if (!/http_get/); # TODO: will not understand things like: # req = http_get(item:"/NonExistant" + rand() + "/", port:port); # Also, will not parse POST requests if (/http_get\(item:"(.*)"\s*,/ ) { $content = $1; } if (/http_get\(item:string\("(.*)"\s*,/) { $content = $1; } if ( $content ne "" ) { $content = $1; # decode URL decoding $content =~ s/%([a-fA-F0-9][a-fA-F0-9])/\\x$1/sg; $content =~ s/([][|()\$\^{}+?.])/\\\1/g; print "# ($id) $name\n"; if ($cve ne "") { print "# CVE: $cve\n"; } if ($btq ne "") { print "# BID: $btq\n"; } if ($uricontent ne "") { if (!($content eq "")) { print "SecFilterSelective THE_REQUEST \"$uricontent\" chain\n"; print "SecFilter \"$content\""; } else { print "SecFilterSelective THE_REQUEST \"$uricontent\""; } } else { print "SecFilter \"$content\""; } print "\n\n"; next LOOP; } } close(PLUGIN); return 0; }