fwsnort-1.6.5/0000775000175000017500000000000012377231022011350 5ustar mbrmbrfwsnort-1.6.5/test/0000775000175000017500000000000012377230712012334 5ustar mbrmbrfwsnort-1.6.5/test/test-fwsnort.pl0000775000175000017500000007215212377230712015362 0ustar mbrmbr#!/usr/bin/perl -w use Cwd; use File::Copy; use File::Path; use Getopt::Long 'GetOptions'; use strict; #==================== config ===================== my $logfile = 'test.log'; my $output_dir = 'output'; my $conf_dir = 'conf'; my $run_dir = 'run'; my $test_install_dir = 'fwsnort-install'; my $fwsnortCmd = "$test_install_dir/usr/sbin/fwsnort"; my $fwsnort_sh = "$test_install_dir/var/lib/fwsnort/fwsnort.sh"; my $cmd_out_tmp = 'cmd.out'; my $default_conf = "$conf_dir/default_fwsnort.conf"; ### alert tcp $EXTERNAL_NET any -> $HOME_NET 7597 (msg:"BACKDOOR QAZ Worm Client Login access"; \ ### flow:to_server,established; content:"qazwsx.hsq"; reference:MCAFEE,98775; \ ### classtype:misc-activity; sid:108; rev:6;) my $simple_sig_id = 108; #================== end config =================== my $current_test_file = "$output_dir/init"; my $YES = 1; my $NO = 0; my $IGNORE = 2; my $passed = 0; my $failed = 0; my $executed = 0; my $test_include = ''; my @tests_to_include = (); my $test_exclude = ''; my @tests_to_exclude = (); my $list_mode = 0; my $diff_mode = 0; my $fw_exec = 0; my $saved_last_results = 0; my $test_system_install = 0; my $PRINT_LEN = 68; my $REQUIRED = 1; my $OPTIONAL = 0; my $MATCH_ALL_RE = 1; my $MATCH_SINGLE_RE = 2; my $help = 0; my %test_keys = ( 'category' => $REQUIRED, 'subcategory' => $OPTIONAL, 'detail' => $REQUIRED, 'function' => $REQUIRED, 'cmdline' => $OPTIONAL, 'fatal' => $OPTIONAL, 'exec_err' => $OPTIONAL, 'match_all' => $OPTIONAL, 'fw_exec' => $OPTIONAL, 'postive_output_matches' => $OPTIONAL, 'negative_output_matches' => $OPTIONAL, ); my @args_cp = @ARGV; exit 1 unless GetOptions( 'fwsnort-path=s' => \$fwsnortCmd, 'test-include=s' => \$test_include, 'include=s' => \$test_include, ### synonym 'test-exclude=s' => \$test_exclude, 'exclude=s' => \$test_exclude, ### synonym 'test-system-install' => \$test_system_install, 'List-mode' => \$list_mode, 'diff' => \$diff_mode, 'enable-fw-exec' => \$fw_exec, 'help' => \$help ); &usage() if $help; ### define all tests my @tests = ( { 'category' => 'install', 'detail' => "test directory: $test_install_dir", 'err_msg' => 'could not install', 'function' => \&install_test_dir, 'cmdline' => "./install.pl --install-test-dir", 'exec_err' => $NO, 'fatal' => $YES }, { 'category' => 'compilation', 'detail' => 'fwsnort compiles', 'err_msg' => 'could not compile', 'function' => \&generic_exec, 'cmdline' => "perl -c $fwsnortCmd", 'exec_err' => $NO, 'fatal' => $YES }, { 'category' => 'operations', 'detail' => '--help', 'err_msg' => 'could not get --help output', 'function' => \&generic_exec, 'cmdline' => "$fwsnortCmd -h -c $default_conf", 'exec_err' => $NO, 'fatal' => $NO }, { 'category' => 'operations', 'detail' => '--dump-conf', 'err_msg' => 'could not get --Dump-conf output', 'function' => \&generic_exec, 'cmdline' => "$fwsnortCmd --Dump-conf -c $default_conf --no-ipt-test", 'exec_err' => $NO, 'fatal' => $NO }, { 'category' => 'operations', 'detail' => '--ipt-list', 'err_msg' => 'could not get --ipt-list output', 'function' => \&generic_exec, 'cmdline' => "$fwsnortCmd --ipt-list -c $default_conf --no-ipt-test", 'exec_err' => $NO, 'fatal' => $NO }, { 'category' => 'operations', 'detail' => "--ipt-check-capabilities", 'err_msg' => "could not check iptables capabilities", 'positive_output_matches' => [ qr/iptables\shas/ ], 'match_all' => $MATCH_ALL_RE, 'function' => \&generic_exec, 'cmdline' => "$fwsnortCmd --ipt-check-capabilities --verbose -c $default_conf", 'exec_err' => $NO, 'fatal' => $NO }, { 'category' => 'operations', 'detail' => "--snort-sid $simple_sig_id EXTERNAL->HOME", 'err_msg' => "did not translate sid: $simple_sig_id", 'positive_output_matches' => [qr/Found\ssid\:\s$simple_sig_id/, qr/Successful\stranslation/ ], 'match_all' => $MATCH_ALL_RE, 'function' => \&generic_exec, 'cmdline' => "$fwsnortCmd --no-ipt-test -c $default_conf --snort-sid $simple_sig_id", 'fw_exec' => $fw_exec, 'exec_err' => $NO, 'fatal' => $NO }, { 'category' => 'operations', 'detail' => "--snort-sid 1292 HOME->EXTERNAL", 'err_msg' => "did not translate sid: 1292", 'positive_output_matches' => [qr/Found\ssid\:\s1292/, qr/Successful\stranslation/ ], 'match_all' => $MATCH_ALL_RE, 'function' => \&generic_exec, 'cmdline' => "$fwsnortCmd --no-ipt-test -c $default_conf --snort-sid 1292", 'fw_exec' => $fw_exec, 'exec_err' => $NO, 'fatal' => $NO }, { 'category' => 'operations', 'detail' => "multiple rules --snort-sid $simple_sig_id,109,321", 'err_msg' => "did not translate sid: $simple_sig_id", 'positive_output_matches' => [qr/Found\ssid/, qr/Found\ssid\:\s109/, qr/Found\ssid\:\s321/, qr/Successful\stranslation/, ], 'match_all' => $MATCH_ALL_RE, 'function' => \&generic_exec, 'cmdline' => "$fwsnortCmd --no-ipt-test -c $default_conf --snort-sid $simple_sig_id,109,321", 'fw_exec' => $fw_exec, 'exec_err' => $NO, 'fatal' => $NO }, { 'category' => 'operations', 'detail' => "--snort-sid badsid", 'err_msg' => 'translated badsid signature', 'positive_output_matches' => [ qr/No\sSnort\srules\scould\sbe\stranslated/ ], 'match_all' => $MATCH_ALL_RE, 'function' => \&generic_exec, 'cmdline' => "$fwsnortCmd --no-ipt-test -c $default_conf --snort-sid badsid", 'exec_err' => $YES, 'fatal' => $NO }, { 'category' => 'operations', 'detail' => "--include-type backdoor", 'err_msg' => "did not translate backdoor signatures", 'positive_output_matches' => [ qr/backdoor\.rules/, qr/Generated\siptables\srules\sfor/ ], 'match_all' => $MATCH_ALL_RE, 'function' => \&generic_exec, 'cmdline' => "$fwsnortCmd --no-ipt-test -c $default_conf --include-type backdoor", 'fw_exec' => $fw_exec, 'exec_err' => $NO, 'fatal' => $NO }, { 'category' => 'operations', 'detail' => "--strict --include-type backdoor", 'err_msg' => "did not translate backdoor signatures", 'positive_output_matches' => [ qr/backdoor\.rules/, qr/Generated\siptables\srules\sfor/ ], 'match_all' => $MATCH_ALL_RE, 'function' => \&generic_exec, 'cmdline' => "$fwsnortCmd --no-ipt-test -c $default_conf --strict --include-type backdoor", 'fw_exec' => $fw_exec, 'exec_err' => $NO, 'fatal' => $NO }, { 'category' => 'operations', 'detail' => "--include-type emerging-all", 'err_msg' => "did not translate emerging-all signatures", 'positive_output_matches' => [ qr/emerging-all\.rules/, qr/Generated\siptables\srules\sfor/ ], 'match_all' => $MATCH_ALL_RE, 'function' => \&generic_exec, 'cmdline' => "$fwsnortCmd --no-ipt-test -c $default_conf --include-type emerging-all", 'fw_exec' => $fw_exec, 'exec_err' => $NO, 'fatal' => $NO }, { 'category' => 'operations', 'detail' => "multiple files --include-type backdoor,dns,ftp", 'err_msg' => "did not translate backdoor,dns,ftp signatures", 'positive_output_matches' => [ qr/backdoor\.rules/, qr/dns\.rules/, qr/ftp\.rules/, qr/Generated\siptables\srules\sfor/ ], 'match_all' => $MATCH_ALL_RE, 'function' => \&generic_exec, 'cmdline' => "$fwsnortCmd --no-ipt-test -c $default_conf --include-type backdoor,dns,ftp", 'fw_exec' => $fw_exec, 'exec_err' => $NO, 'fatal' => $NO }, { 'category' => 'operations', 'detail' => "--exclude-type emerging-all", 'err_msg' => "did not translate signatures", 'positive_output_matches' => [ qr/backdoor\.rules/, qr/dns\.rules/, qr/ftp\.rules/, qr/Generated\siptables\srules\sfor/ ], 'match_all' => $MATCH_ALL_RE, 'function' => \&generic_exec, 'cmdline' => "$fwsnortCmd --no-ipt-test -c $default_conf --exclude-type emerging-all", 'fw_exec' => $fw_exec, 'exec_err' => $NO, 'fatal' => $NO }, { 'category' => 'operations', 'detail' => "multiple --exclude-type emerging-all,backdoor,dns,ftp", 'err_msg' => "did not translate signatures", 'positive_output_matches' => [ qr/chat\.rules/, qr/ddos\.rules/, qr/Generated\siptables\srules\sfor/ ], 'match_all' => $MATCH_ALL_RE, 'function' => \&generic_exec, 'cmdline' => "$fwsnortCmd --no-ipt-test -c $default_conf --exclude-type emerging-all,backdoor,dns,ftp", 'fw_exec' => $fw_exec, 'exec_err' => $NO, 'fatal' => $NO }, { 'category' => 'operations', 'detail' => "--include-type backdoor,dns,ftp --exclude-type dns", 'err_msg' => "did not translate backdoor,ftp signatures", 'positive_output_matches' => [ qr/backdoor\.rules/, qr/ftp\.rules/, qr/Generated\siptables\srules\sfor/ ], 'negative_output_matches' => [ qr/dns\.rules/, ], 'match_all' => $MATCH_ALL_RE, 'function' => \&generic_exec, 'cmdline' => "$fwsnortCmd --no-ipt-test -c $default_conf --include-type backdoor,dns,ftp --exclude-type dns", 'fw_exec' => $fw_exec, 'exec_err' => $NO, 'fatal' => $NO }, { 'category' => 'operations', 'detail' => "--snort-sid $simple_sig_id,109,321 --exclude-regex sid\:109", 'err_msg' => "did not translate sid: $simple_sig_id", 'positive_output_matches' => [qr/Found\ssid/, qr/Found\ssid\:\s321/, qr/Successful\stranslation/, ], 'negative_output_matches' => [ qr/Found\ssid\:\s109/, ], 'match_all' => $MATCH_ALL_RE, 'function' => \&generic_exec, 'cmdline' => "$fwsnortCmd --no-ipt-test -c $default_conf --snort-sid $simple_sig_id,109,321 --exclude-regex sid\:109", 'fw_exec' => $fw_exec, 'exec_err' => $NO, 'fatal' => $NO }, { 'category' => 'operations', 'detail' => "--snort-sid $simple_sig_id,109,321 --include-regex sid\:109", 'err_msg' => "did not translate sid: $simple_sig_id", 'positive_output_matches' => [qr/Found\ssid/, qr/Found\ssid\:\s109/, qr/Successful\stranslation/, ], 'negative_output_matches' => [ qr/Found\ssid\:\s321/, ], 'match_all' => $MATCH_ALL_RE, 'function' => \&generic_exec, 'cmdline' => "$fwsnortCmd --no-ipt-test -c $default_conf --snort-sid $simple_sig_id,109,321 --include-regex sid\:109", 'fw_exec' => $fw_exec, 'exec_err' => $NO, 'fatal' => $NO }, ### ip6tables testing { 'category' => 'operations', 'detail' => "ip6tables --snort-sid $simple_sig_id", 'err_msg' => "did not translate sid: $simple_sig_id", 'positive_output_matches' => [qr/Found\ssid\:\s$simple_sig_id/, qr/Successful\stranslation/ ], 'match_all' => $MATCH_ALL_RE, 'function' => \&generic_exec, 'cmdline' => "$fwsnortCmd --ip6tables --no-ipt-test -c $default_conf --snort-sid $simple_sig_id", 'fw_exec' => $fw_exec, 'exec_err' => $NO, 'fatal' => $NO }, { 'category' => 'operations', 'detail' => "ip6tables --snort-sid $simple_sig_id,109,321", 'err_msg' => "did not translate sid: $simple_sig_id", 'positive_output_matches' => [qr/Found\ssid/, qr/Found\ssid\:\s109/, qr/Found\ssid\:\s321/, qr/Successful\stranslation/, ], 'match_all' => $MATCH_ALL_RE, 'function' => \&generic_exec, 'cmdline' => "$fwsnortCmd --ip6tables --no-ipt-test -c $default_conf --snort-sid $simple_sig_id,109,321", 'fw_exec' => $fw_exec, 'exec_err' => $NO, 'fatal' => $NO }, { 'category' => 'operations', 'detail' => "ip6tables --snort-sid badsid", 'err_msg' => 'translated badsid signature', 'positive_output_matches' => [ qr/No\sSnort\srules\scould\sbe\stranslated/ ], 'match_all' => $MATCH_ALL_RE, 'function' => \&generic_exec, 'cmdline' => "$fwsnortCmd --ip6tables --no-ipt-test -c $default_conf --snort-sid badsid", 'exec_err' => $YES, 'fatal' => $NO }, { 'category' => 'operations', 'detail' => "ip6tables --include-type backdoor", 'err_msg' => "did not translate backdoor signatures", 'positive_output_matches' => [ qr/backdoor\.rules/, qr/Generated\sip6tables\srules\sfor/ ], 'match_all' => $MATCH_ALL_RE, 'function' => \&generic_exec, 'cmdline' => "$fwsnortCmd --ip6tables --no-ipt-test -c $default_conf --include-type backdoor", 'fw_exec' => $fw_exec, 'exec_err' => $NO, 'fatal' => $NO }, { 'category' => 'operations', 'detail' => "ip6tables --strict --include-type backdoor", 'err_msg' => "did not translate backdoor signatures", 'positive_output_matches' => [ qr/backdoor\.rules/, qr/Generated\sip6tables\srules\sfor/ ], 'match_all' => $MATCH_ALL_RE, 'function' => \&generic_exec, 'cmdline' => "$fwsnortCmd --ip6tables --no-ipt-test -c $default_conf --strict --include-type backdoor", 'fw_exec' => $fw_exec, 'exec_err' => $NO, 'fatal' => $NO }, { 'category' => 'operations', 'detail' => "ip6tables --include-type emerging-all", 'err_msg' => "did not translate emerging-all signatures", 'positive_output_matches' => [ qr/emerging-all\.rules/, qr/Generated\sip6tables\srules\sfor/ ], 'match_all' => $MATCH_ALL_RE, 'function' => \&generic_exec, 'cmdline' => "$fwsnortCmd --ip6tables --no-ipt-test -c $default_conf --include-type emerging-all", 'fw_exec' => $fw_exec, 'exec_err' => $NO, 'fatal' => $NO }, { 'category' => 'operations', 'detail' => "ip6tables --include-type backdoor,dns,ftp", 'err_msg' => "did not translate backdoor,dns,ftp signatures", 'positive_output_matches' => [ qr/backdoor\.rules/, qr/dns\.rules/, qr/ftp\.rules/, qr/Generated\sip6tables\srules\sfor/ ], 'match_all' => $MATCH_ALL_RE, 'function' => \&generic_exec, 'cmdline' => "$fwsnortCmd --ip6tables --no-ipt-test -c $default_conf --include-type backdoor,dns,ftp", 'fw_exec' => $fw_exec, 'exec_err' => $NO, 'fatal' => $NO }, { 'category' => 'operations', 'detail' => "ip6tables --exclude-type emerging-all", 'err_msg' => "did not translate signatures", 'positive_output_matches' => [ qr/backdoor\.rules/, qr/dns\.rules/, qr/ftp\.rules/, qr/Generated\sip6tables\srules\sfor/ ], 'match_all' => $MATCH_ALL_RE, 'function' => \&generic_exec, 'cmdline' => "$fwsnortCmd --ip6tables --no-ipt-test -c $default_conf --exclude-type emerging-all", 'fw_exec' => $fw_exec, 'exec_err' => $NO, 'fatal' => $NO }, { 'category' => 'operations', 'detail' => "ip6tables --ex... emerging-all,backdoor,dns,ftp", 'err_msg' => "did not translate signatures", 'positive_output_matches' => [ qr/chat\.rules/, qr/ddos\.rules/, qr/Generated\sip6tables\srules\sfor/ ], 'match_all' => $MATCH_ALL_RE, 'function' => \&generic_exec, 'cmdline' => "$fwsnortCmd --ip6tables --no-ipt-test -c $default_conf --exclude-type emerging-all,backdoor,dns,ftp", 'fw_exec' => $fw_exec, 'exec_err' => $NO, 'fatal' => $NO }, { 'category' => 'operations', 'detail' => "ip6tables --in.. backdoor,dns,ftp --ex.. dns", 'err_msg' => "did not translate backdoor,ftp signatures", 'positive_output_matches' => [ qr/backdoor\.rules/, qr/ftp\.rules/, qr/Generated\sip6tables\srules\sfor/ ], 'negative_output_matches' => [ qr/dns\.rules/, ], 'match_all' => $MATCH_ALL_RE, 'function' => \&generic_exec, 'cmdline' => "$fwsnortCmd --ip6tables --no-ipt-test -c $default_conf --include-type backdoor,dns,ftp --exclude-type dns", 'fw_exec' => $fw_exec, 'exec_err' => $NO, 'fatal' => $NO }, { 'category' => 'operations', 'detail' => "ip6tables --sn.. $simple_sig_id,109,321 --ex.. sid\:109", 'err_msg' => "did not translate sid: $simple_sig_id", 'positive_output_matches' => [qr/Found\ssid/, qr/Found\ssid\:\s321/, qr/Successful\stranslation/, ], 'negative_output_matches' => [ qr/Found\ssid\:\s109/, ], 'match_all' => $MATCH_ALL_RE, 'function' => \&generic_exec, 'cmdline' => "$fwsnortCmd --ip6tables --no-ipt-test -c $default_conf --snort-sid $simple_sig_id,109,321 --exclude-regex sid\:109", 'fw_exec' => $fw_exec, 'exec_err' => $NO, 'fatal' => $NO }, { 'category' => 'operations', 'detail' => "ip6tables --sn.. $simple_sig_id,109,321 --in.. sid\:109", 'err_msg' => "did not translate sid: $simple_sig_id", 'positive_output_matches' => [qr/Found\ssid/, qr/Found\ssid\:\s109/, qr/Successful\stranslation/, ], 'negative_output_matches' => [ qr/Found\ssid\:\s321/, ], 'match_all' => $MATCH_ALL_RE, 'function' => \&generic_exec, 'cmdline' => "$fwsnortCmd --ip6tables --no-ipt-test -c $default_conf --snort-sid $simple_sig_id,109,321 --include-regex sid\:109", 'fw_exec' => $fw_exec, 'exec_err' => $NO, 'fatal' => $NO }, { 'category' => 'errors', 'detail' => 'look for perl warnings', 'err_msg' => 'found perl warnings', 'negative_output_matches' => [qr/Use\sof\suninitialized\svalue/i, qr/Missing\sargument/, qr/Argument.*isn\'t\snumeric/], 'match_all' => $MATCH_ALL_RE, 'function' => \&look_for_warnings, 'cmdline' => "grep -i uninit $output_dir/*.test", 'exec_err' => $IGNORE, 'fatal' => $NO }, ); ### make sure everything looks as expected before continuing &init(); &logr("\n[+] Starting the fwsnort test suite...\n\n" . " args: @args_cp\n\n" ); ### save the results from any previous test suite run ### so that we can potentially compare them with --diff if ($saved_last_results) { &logr(" Saved results from previous run " . "to: ${output_dir}.last/\n\n"); } ### main loop through all of the tests for my $test_hr (@tests) { &run_test($test_hr); } &logr("\n[+] passed/failed/executed: $passed/$failed/$executed tests\n\n"); copy $logfile, "$output_dir/$logfile" or die $!; exit 0; #===================== end main ======================= sub run_test() { my $test_hr = shift; my $msg = "[$test_hr->{'category'}]"; $msg .= " [$test_hr->{'subcategory'}]" if $test_hr->{'subcategory'}; $msg .= " $test_hr->{'detail'}"; return unless &process_include_exclude($msg); if ($list_mode) { print $msg, "\n"; return; } &dots_print($msg); $executed++; $current_test_file = "$output_dir/$executed.test"; &write_test_file("[+] TEST: $msg\n"); if (&{$test_hr->{'function'}}($test_hr)) { &logr("pass ($executed)\n"); $passed++; } else { &logr("fail ($executed)\n"); $failed++; if ($test_hr->{'fatal'} eq $YES) { die "[*] required test failed, exiting."; } } return; } sub look_for_warnings() { my $test_hr = shift; my $orig_test_file = $current_test_file; $current_test_file = "$output_dir/grep.output"; my $rv = &generic_exec($test_hr); copy $current_test_file, $orig_test_file; unlink $current_test_file; return $rv; } sub install_test_dir() { my $test_hr = shift; my $rv = 1; my $curr_pwd = cwd() or die $!; if (-d $test_install_dir) { rmtree $test_install_dir or die $!; } mkdir $test_install_dir or die $!; chdir '..' or die $!; my $exec_rv = &run_cmd($test_hr->{'cmdline'}, "test/$cmd_out_tmp", "test/$current_test_file"); if ($test_hr->{'exec_err'} eq $YES) { $rv = 0 if $exec_rv; } elsif ($test_hr->{'exec_err'} eq $NO) { $rv = 0 unless $exec_rv; } else { $rv = 1; } if ($test_hr->{'positive_output_matches'}) { $rv = 0 unless &file_find_regex( $test_hr->{'positive_output_matches'}, $test_hr->{'match_all'}, $current_test_file); } if ($test_hr->{'negative_output_matches'}) { $rv = 0 if &file_find_regex( $test_hr->{'negative_output_matches'}, $test_hr->{'match_all'}, $current_test_file); } chdir $curr_pwd or die $!; return $rv; } sub generic_exec() { my $test_hr = shift; my $rv = 1; my $exec_rv = &run_cmd($test_hr->{'cmdline'}, $cmd_out_tmp, $current_test_file); if ($test_hr->{'exec_err'} eq $YES) { $rv = 0 if $exec_rv; } elsif ($test_hr->{'exec_err'} eq $NO) { $rv = 0 unless $exec_rv; } else { $rv = 1; } if ($test_hr->{'positive_output_matches'}) { $rv = 0 unless &file_find_regex( $test_hr->{'positive_output_matches'}, $test_hr->{'match_all'}, $current_test_file); } if ($test_hr->{'negative_output_matches'}) { $rv = 0 if &file_find_regex( $test_hr->{'negative_output_matches'}, $test_hr->{'match_all'}, $current_test_file); } if ($test_hr->{'fw_exec'} eq $YES) { if (-e $fwsnort_sh) { $rv = 0 unless &run_cmd($fwsnort_sh, $cmd_out_tmp, $current_test_file); if ($test_hr->{'detail'} =~ /ip6tables/) { $rv = 0 unless &run_cmd("$fwsnortCmd --ipt-list --ip6tables", $cmd_out_tmp, $current_test_file); } else { $rv = 0 unless &run_cmd("$fwsnortCmd --ipt-list", $cmd_out_tmp, $current_test_file); } $rv = 0 unless &run_cmd("$fwsnort_sh -r", $cmd_out_tmp, $current_test_file); } else { &write_test_file("[-] $fwsnort_sh script does not exist.\n"); } } return $rv; } sub run_cmd() { my ($cmd, $cmd_out, $file) = @_; if (-e $file) { open F, ">> $file" or die "[*] Could not open $file: $!"; print F localtime() . " CMD: $cmd\n"; close F; } else { open F, "> $file" or die "[*] Could not open $file: $!"; print F localtime() . " CMD: $cmd\n"; close F; } my $rv = ((system "$cmd > $cmd_out 2>&1") >> 8); open C, "< $cmd_out" or die "[*] Could not open $cmd_out: $!"; my @cmd_lines = ; close C; open F, ">> $file" or die "[*] Could not open $file: $!"; print F $_ for @cmd_lines; close F; if ($rv == 0) { return 1; } return 0; } sub file_find_regex() { my ($re_ar, $match_all_flag, $file) = @_; my @write_lines = (); my @file_lines = (); open F, "< $file" or die "[*] Could not open $file: $!"; while () { push @file_lines, $_; } close F; my $found = 0; RE: for my $re (@$re_ar) { $found = 0; LINE: for my $line (@file_lines) { next LINE if $line =~ /file_file_regex\(\)/; if ($line =~ $re) { push @write_lines, "[.] file_find_regex() " . "Matched '$re' with line: $line (file: $file)\n"; $found = 1; last LINE; } } if ($found) { if ($match_all_flag == $MATCH_SINGLE_RE) { last RE; } } else { push @write_lines, "[.] file_find_regex() " . "did not match '$re' (file: $file)\n"; if ($match_all_flag == $MATCH_ALL_RE) { last RE; } } } for my $line (@write_lines) { &write_test_file($line); } return $found; } sub dots_print() { my $msg = shift; &logr($msg); my $dots = ''; for (my $i=length($msg); $i < $PRINT_LEN; $i++) { $dots .= '.'; } &logr($dots); return; } sub init() { $|++; ### turn off buffering $< == 0 and $> == 0 or die "[*] $0: You must be root (or equivalent ", "UID 0 account) to effectively test fwsnort"; ### validate test hashes my $hash_num = 0; for my $test_hr (@tests) { for my $key (keys %test_keys) { if ($test_keys{$key} == $REQUIRED) { die "[*] Missing '$key' element in hash: $hash_num" unless defined $test_hr->{$key}; } else { $test_hr->{$key} = '' unless defined $test_hr->{$key}; } } $hash_num++; } die "[*] $conf_dir directory does not exist." unless -d $conf_dir; die "[*] default config $default_conf does not exist" unless -e $default_conf; if (-d $output_dir) { if (-d "${output_dir}.last") { rmtree "${output_dir}.last" or die "[*] rmtree ${output_dir}.last $!"; } mkdir "${output_dir}.last" or die "[*] ${output_dir}.last: $!"; for my $file (glob("$output_dir/*.test")) { if ($file =~ m|.*/(.*)|) { copy $file, "${output_dir}.last/$1" or die $!; } } if (-e "$output_dir/init") { copy "$output_dir/init", "${output_dir}.last/init"; } if (-e $logfile) { copy $logfile, "${output_dir}.last/$logfile" or die $!; } $saved_last_results = 1; } else { mkdir $output_dir or die "[*] Could not mkdir $output_dir: $!"; } unless (-d $run_dir) { mkdir $run_dir or die "[*] Could not mkdir $run_dir: $!"; } for my $file (glob("$output_dir/*.test")) { unlink $file or die "[*] Could not unlink($file)"; } if (-e "$output_dir/init") { unlink "$output_dir/init" or die $!; } if (-e $logfile) { unlink $logfile or die $!; } if ($test_include) { @tests_to_include = split /\s*,\s*/, $test_include; } if ($test_exclude) { @tests_to_exclude = split /\s*,\s*/, $test_exclude; } return; } sub process_include_exclude() { my $msg = shift; ### inclusions/exclusions if (@tests_to_include) { my $found = 0; for my $test (@tests_to_include) { if ($msg =~ /$test/) { $found = 1; last; } } return 0 unless $found; } if (@tests_to_exclude) { my $found = 0; for my $test (@tests_to_exclude) { if ($msg =~ /$test/) { $found = 1; last; } } return 0 if $found; } return 1; } sub write_test_file() { my $msg = shift; if (-e $current_test_file) { open F, ">> $current_test_file" or die "[*] Could not open $current_test_file: $!"; print F $msg; close F; } else { open F, "> $current_test_file" or die "[*] Could not open $current_test_file: $!"; print F $msg; close F; } return; } sub logr() { my $msg = shift; print STDOUT $msg; open F, ">> $logfile" or die $!; print F $msg; close F; return; } sub usage() { ### FIXME } fwsnort-1.6.5/test/conf/0000775000175000017500000000000012377230712013261 5ustar mbrmbrfwsnort-1.6.5/test/conf/default_fwsnort.conf0000664000175000017500000001162412377230712017342 0ustar mbrmbr# ########################################################################### # # This is the configuration file for fwsnort. There are some similarities # between this file and the configuration file for Snort. # ########################################################################### # ### Fwsnort treats all traffic directed to / originating from the local ### machine as going to / coming from the HOME_NET in Snort rule parlance. ### If there is only one interface on the local system, then there will be ### no rules processed via the FWSNORT_FORWARD chain because no traffic ### would make it into the iptables FORWARD chain. HOME_NET any; EXTERNAL_NET any; ### List of servers. Fwsnort supports the same variable resolution as ### Snort. HTTP_SERVERS $HOME_NET; SMTP_SERVERS $HOME_NET; DNS_SERVERS $HOME_NET; SQL_SERVERS $HOME_NET; TELNET_SERVERS $HOME_NET; ### AOL AIM server nets AIM_SERVERS [64.12.24.0/24, 64.12.25.0/24, 64.12.26.14/24, 64.12.28.0/24, 64.12.29.0/24, 64.12.161.0/24, 64.12.163.0/24, 205.188.5.0/24, 205.188.9.0/24]; ### Configurable port numbers SSH_PORTS 22; HTTP_PORTS 80; SHELLCODE_PORTS !80; ORACLE_PORTS 1521; ### Default update URL for new rules. This variable can be given multiple ### times on separate lines in order to specify multiple update URL's: #UPDATE_RULES_URL #UPDATE_RULES_URL UPDATE_RULES_URL http://rules.emergingthreats.net/open/snort-2.9.0/emerging-all.rules; ### define average packet lengths and maximum frame length. This is ### used for iptables length match emulation of the Snort dsize option. AVG_IP_HEADER_LEN 20; ### IP options are not usually used. AVG_TCP_HEADER_LEN 30; ### Include 10 bytes for options MAX_FRAME_LEN 1500; ### define the max length of the content (null terminated string) that ### can be passed to either the --hex-string or --string iptables matches. ### Note that as of fwsnort-1.5, the max string length supported by the ### local iptables instance is automatically determined, so this variable ### is not really needed, and just allows a max value to be set ### independently of what iptables supports. MAX_STRING_LEN 1024; ### Use the WHITELIST variable to define a list of hosts/networks ### that should be completely ignored by fwsnort. For example, if you ### want to whitelist the IP 192.168.10.1 and the network 10.1.1.0/24, ### you would use (note that you can also specify multiple WHITELIST ### variables, one per line): #WHITELIST 192.168.10.1, 10.1.1.0/24; WHITELIST NONE; ### Use the BLACKLIST variable to define a list of hosts/networks ### that for which fwsnort should DROP or REJECT all traffic. For ### example, to DROP all traffic from the 192.168.10.0/24 network, you ### can use: ### BLACKLIST 192.168.10.0/24 DROP; ### To have fwsnort REJECT all traffic from 192.168.10.0/24, you would ### use: ### BLACKLIST 192.168.10.0/24 REJECT; BLACKLIST NONE; ### define the jump position in the built-in chains to jump to the ### fwsnort chains FWSNORT_INPUT_JUMP 1; FWSNORT_OUTPUT_JUMP 1; FWSNORT_FORWARD_JUMP 1; ### iptables chains (these do not normally need to be changed). FWSNORT_INPUT FWSNORT_INPUT; FWSNORT_INPUT_ESTAB FWSNORT_INPUT_ESTAB; FWSNORT_OUTPUT FWSNORT_OUTPUT; FWSNORT_OUTPUT_ESTAB FWSNORT_OUTPUT_ESTAB; FWSNORT_FORWARD FWSNORT_FORWARD; FWSNORT_FORWARD_ESTAB FWSNORT_FORWARD_ESTAB; ### fwsnort filesystem paths INSTALL_ROOT fwsnort-install; CONF_DIR $INSTALL_ROOT/etc/fwsnort; RULES_DIR $CONF_DIR/snort_rules; LOG_DIR $INSTALL_ROOT/var/log/fwsnort; LIBS_DIR $INSTALL_ROOT/usr/lib/fwsnort; ### for perl modules STATE_DIR $INSTALL_ROOT/var/lib/fwsnort; QUEUE_RULES_DIR $STATE_DIR/snort_rules_queue; ARCHIVE_DIR $STATE_DIR/archive; CONF_FILE $CONF_DIR/fwsnort.conf; LOG_FILE $LOG_DIR/fwsnort.log; FWSNORT_SCRIPT $STATE_DIR/fwsnort_iptcmds.sh; ### slow version FWSNORT_SAVE_EXEC_FILE $STATE_DIR/fwsnort.sh; ### main fwsnort.sh script FWSNORT_SAVE_FILE $STATE_DIR/fwsnort.save; ### main fwsnort.save file IPT_BACKUP_SAVE_FILE $STATE_DIR/iptables.save; ### iptables policy backup ### system binaries shCmd /bin/sh; echoCmd /bin/echo; tarCmd /bin/tar; wgetCmd /usr/bin/wget; unameCmd /usr/bin/uname; ifconfigCmd /sbin/ifconfig; iptablesCmd /sbin/iptables; iptables-saveCmd /sbin/iptables-save; iptables-restoreCmd /sbin/iptables-restore; ip6tablesCmd /sbin/ip6tables; ip6tables-saveCmd /sbin/ip6tables-save; ip6tables-restoreCmd /sbin/ip6tables-restore; fwsnort-1.6.5/INSTALL0000664000175000017500000000215212377230712012406 0ustar mbrmbr fwsnort has its own installer "install.pl". Just run install.pl to install fwsnort. After fwsnort has been installed, it is recommended that you edit the /etc/fwsnort/fwsnort.conf file to define your internal network and lists of your server infrastructure. You can just run fwsnort with the defaults if you like. DEPENDENCIES: iptables String Matching: fwsnort requires the iptables string match extensions in order to be able to detect application layer attacks. Most Linux distributions include iptables, and the string match extension is commonly included as well, so if you are running a recent Linux distro you probably already have string matching available. If not, you will need to enable the CONFIG_NETFILTER_XT_MATCH_STRING variable in the kernel config file (for 2.6 series kernels) and recompile. Perl modules: fwsnort requires two perl modules in order to run properly: IPTables::Parse NetAddr::IP These two modules are bundled with fwsnort within the deps/ directory, unless you have downloaded the fwsnort-nodeps tarball, in which case these two modules need to be installed in the perl library tree. fwsnort-1.6.5/README0000664000175000017500000000630612377230712012242 0ustar mbrmbrfwsnort (Firewall Snort) Version: 1.6.4 Author: Michael Rash Website: http://www.cipherdyne.org/fwsnort/ DESCRIPTION: fwsnort is a perl script that translates Snort rules into equivalent iptables rules. Some Snort rule options (such as "pcre") have no direct translation into iptables options so not all Snort rules can be translated. However approximately 65% of all Snort-2.3.3 signatures (the last release of Snort signatures under the GPL) can be successfully translated through the use of the iptables string match module. When tranlating Snort rules, fwsnort makes heavy use of the iptables string match extension with its "--hex-string" option (added to iptables by the fwsnort project) which accepts Snort "content" argument with hex bytes between "|" chars (such as "|5a 4e|"). This allows the content fields in Snort rules to be directly input into iptables rulesets from the command line. fwsnort alse parses the running iptables policy on the machine in order to determine which Snort rules are applicable to the specific policy loaded on the machine. fwsnort requires the iptables string match module in order to be able to detect application layer attacks. If you are running modern Linux distribution then it is likely that the kernel has been compiled with iptables string matching support, and fwsnort will automatically test this. PLATFORMS: fwsnort is compatible with iptables only, hence fwsnort will exclusively run on Linux running a 2.6 series kernel (with some support for 2.4 kernels as well). Snort is a registered trademark of Sourcefire, Inc INSTALLATION: (See the INSTALL file in the source directory.) UPGRADING: If are installing fwsnort from sources (i.e. not through a distribution package manager such as RPM or apt), you can just run the "install.pl" script. It takes care of upgrades, and it will merge any customized configuration variables in the /etc/fwsnort/fwsnort.conf file with the new file in the source directory. Even if you are using a distribution package manager, you can still run the install.pl script in order to preserve any existing configuration. However, in this case the install.pl script will also put in place fwsnort according to how it normally handles installation paths, and these may not match how your distribution package manager normally handles things. COPYRIGHT: Copyright (C) 2003-2014 Michael Rash (mbr@cipherdyne.org) fwsnort is distributed under the GNU General Public License (GPLv2), and the latest version may be downloaded from http://www.cipherdyne.org/ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA fwsnort-1.6.5/bump_version.pl0000775000175000017500000000257012377230712014431 0ustar mbrmbr#!/usr/bin/perl -w # ############################################################################# # # File: bump_version.pl # # Purpose: Minor script to enforce consistency in fwsnort version tags. # ############################################################################# # use strict; my @files = (qw( fwsnort README )); my $new_version = $ARGV[0] or die "[*] $0 "; open F, '< VERSION' or die "[*] Could not open VERSION file: $!"; my $old_version = ; close F; chomp $old_version; print "[+] Updating software versions...\n"; for my $file (@files) { if ($file =~ /\.c/) { ###* Version: 1.8.4-pre2 my $search_re = qr/^\*\s+Version:\s+$old_version/; my $replace_str = '* Version: ' . $new_version; system qq{perl -p -i -e 's|$search_re|} . qq{$replace_str|' $file}; } else { ### Version: 1.8.4 my $search_re = qr/#\s+Version:\s+$old_version/; my $replace_str = '# Version: ' . $new_version; system qq{perl -p -i -e 's|$search_re|$replace_str|' $file}; ### my $version = '1.8.4'; $search_re = qr/^my\s+\x24version\s+=\s+'$old_version';/; $replace_str = q|my \x24version = '| . $new_version . q|';|; system qq{perl -p -i -e "s|$search_re|$replace_str|" $file}; } } system qq{perl -p -i -e 's|$old_version|$new_version|' VERSION}; exit 0; fwsnort-1.6.5/README.RPM0000664000175000017500000000643612377230712012703 0ustar mbrmbr NOTE: Before building an RPM manually for your Linux system, it is recommended to try installing fwsnort via the standard software install mechanism for your distribution since fwsnort is available in many distribution software repositories. For example, you can try installing fwsnort with 'yum' or 'apt-get' depending on the type of Linux distribution that you are running. Building RPM files that are compatible with all possible Linux distributions is a difficult task. If a given RPM file that is downloaded from http://www.cipherdyne.org/ is not compatible with your particular Linux distro, then you can use the "cd_rpmbuilder" ("CipherDyne RPM Builder") to build an RPM file for you on your own system. The command line interface to cd_rpmbuilder is simple, and one command line argument is always required "-p " so that cd_rpmbuilder knows which CipherDyne software project you want to build: # cd_rpmbuilder -p Note that cd_rpmbuilder is normally as root because it builds RPM's within the /usr/src/redhat/ directory by default. However, if you would like to build as a normal user within a directory of your choosing you can do: # cd_rpmbuilder -p -r By default, cd_rpmbuilder builds the latest version of the specified project, but if you want to build an older version, use the -b flag: # cd_rpmbuilder -p -b If you want to see verbose output (including all output of the system rpmbuild command), then use the -v flag: # cd_rpmbuilder -p -v Finally, here is some sample output for building the psad project available at http://www.cipherdyne.org/psad/: # ./cd_rpmbuilder -p psad [+] Getting latest version file: http://www.cipherdyne.org/psad/psad-latest [+] Downloading file: http://www.cipherdyne.org/psad/download/psad-2.0.1.spec [+] Downloading file: http://www.cipherdyne.org/psad/download/psad-2.0.1.spec.md5 [+] Valid md5 sum check for psad-2.0.1.spec [+] Downloading file: http://www.cipherdyne.org/psad/download/psad-2.0.1.tar.gz [+] Downloading file: http://www.cipherdyne.org/psad/download/psad-2.0.1.tar.gz.md5 [+] Valid md5 sum check for psad-2.0.1.tar.gz [+] Building RPM, this may take a little while... [+] The following RPMS were successfully built: /usr/src/redhat/SRPMS/psad-2.0.1-1.src.rpm (source RPM) /usr/src/redhat/RPMS/i386/psad-2.0.1-1.i386.rpm You can view the usage information like so: [mbr@minastirith ~/src/psad]$ ./cd_rpmbuilder -h cd_rpmbuilder; the CipherDyne RPM builder [+] Version: 0.9 [+] By Michael Rash (mbr@cipherdyne.org, http://www.cipherdyne.org) Usage: cd_rpmbuilder -p [-b ] [-r ] [-v] [-V] [-h] Options: -p, --project - This can be one of "psad", "fwknop", "gpgdir", or "fwsnort". -b, --build-version - Build a specific project version. -r, --rpm-build-dir - Change the RPM build directory from the default of /usr/src/redhat. -v, --verbose - Run in verbose mode. -V, --Version - Print version and exit. -h, --help - Display usage information. fwsnort-1.6.5/ChangeLog0000664000175000017500000010121012377230712013122 0ustar mbrmbrfwsnort-1.6.5 (08/26/2014): - (Paulo Bruck) Submitted a patch to fix a bug in fwsnort usage of the iptables --ulog-prefix option (an invalid quote was being used previous to the fix). - Updated to bundle the latest Emerging Threats rule set. fwsnort-1.6.4 (02/02/2014): - Bug fix for vulnerability CVE-2014-0039 reported by Murray McAllister of the Red Hat Security Team in which an attacker-controlled fwsnort.conf file could be read by fwsnort when not running as root. This was caused by fwsnort reading './fwsnort.conf' when not running as root and when a path to the config file was not explicitly set with -c on the command line. This behavior has been changed to require the user to specify a path to fwsnort.conf with -c when not running as root. - Switch fwsnort.sh iptables-restore exec() strategy to leverage 'cat' against fwsnort.save file (fixes CentOS deployments). - Updated to bundle the latest Emerging Threats rule set. fwsnort-1.6.3 (12/21/2012): - Bug fix to ensure that !, <, >, and = chars in content strings are converted to the appropriate hex equivalents. All content strings with characters outside of [A-Za-z0-9] are now converted to hex-string format in their entirety. This should also fix an issue that results in the following error when running /var/lib/fwsnort/fwsnort.sh: Using intrapositioned negation (`--option ! this`) is deprecated in favor of extrapositioned (`! --option this`). Bad argument `bm' Error occurred at line: 64 Try `iptables-restore -h' or 'iptables-restore --help' for more information. Done. - Bug fix to set default max string length in --no-ipt-test mode where iptables capabilities are not tested. - (Andrew Merenbach) Bug fix to properly honor --exclude-regex filtering option. - Added fwsnort test suite to the test/ directory. This mimics the test suites from the psad and fwknop projects, and it designed to examine many of the run time results of fwsnort. - Added the ability to easily revert the fwsnort policy back to the original iptables policy with "/var/lib/fwsnort/fwsnort.sh -r". Note that this reverts back to the policy as it was when fwsnort itself was executed. - Implemented a single unified function for iptables match parameter length testing, and optimized to drastically reduce run time for iptables capabilities checks (going from over 20 seconds to less than one second in some cases). - (Dwight Davis) Contributed patches for several bugs including not handling --exclude-regex properly, not ignoring the deleted.rules file, not handling --strict mode operations correctly, and more. These issues and the corresponding patch were originally reported here: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=693000 - Bug fix for Snort rules with HOME_NET(any) -> EXTERNAL_NET(any) to ensure they go into the OUTPUT chain instead of the INPUT chain. This bug was reported by Dwight Davis. - Updated to bundle the latest Emerging Threats rule set. fwsnort-1.6.2 (04/28/2012): - Switched --no-ipt-sync to default to not syncing with the iptables policy. By default fwsnort attempts to match translated Snort rules to the running iptables policy, but this is tough to do well because iptables policies can be complex. And, before fwsnort switched to the iptables-save format for instantiating the policy, a large set of translated rules could take a really long time to make active within the kernel. Finally, many Snort rules restrict themselves to established TCP connections anyway, and if a restrictive policy doesn't allow connections to get into the established state for some port let's say, then there is little harm in having translated Snort rules for this port. Some kernel memory would be wasted (small), but no performance would be lost since packets won't be processed against these rules anyway. The end result is that the default behavior is now to not sync with the local iptables policy in favor of translating and instantiating as many rules as possible. - Replaced Net::IPv4Addr with the excellent NetAddr::IP module which has comprehensive support for IPv6 address network parsing and comparisons. - Moved the fwsnort.sh script and associated files into the /var/lib/fwsnort/ directory. This was suggested by Peter Vrabec. - Bug fix for recent versions of iptables (such as 1.4.12) where the icmp match requires --icmp-type to be set - some Snort rules look for a string to match in icmp traffic, but don't also specify an icmp type. - Bug fix for 'qw(...) usage as parenthesis' warnings for perl > 5.14 - Removed the ExtUtils::MakeMaker RPM build requirement from the fwsnort.spec file. This is a compromise which will allow the fwsnort RPM to be built even if RPM dosen't or can't see that ExtUtils::MakeMaker is installed - most likely it will build anyway. If it doesn't, there are bigger problems since fwsnort is written in perl. If you want to build the fwsnort RPM with a .spec file that requires ExtUtils::MakeMaker, then use the "fwsnort-require-makemaker.spec" file that is bundled in the fwsnort sources. fwsnort-1.6.1 (11/01/2011): - (Kim Hagen) submitted a patch for a bug in fwsnort-1.6 where the fwsnort policy in iptables-save format could not be loaded whenever iptables-save put the nat table output after the filter table output. In this case, fwsnort would fail with an error like the following: Couldn't load target `FWSNORT_FORWARD_ESTAB':/lib/xtables/libipt_FWSNORT_FORWARD_ESTAB.so: cannot open shared object file: No such file or directory fwsnort now invokes 'iptables-save -t filter' in order to ensure that ordering issues do not affect how fwsnort builds its translated rule set. - Bug fix to ensure that fwsnort does not attempt to re-order pattern matches for patterns that have a relative match requirement. For non- relative matches fwsnort re-orders pattern matches based on the pattern length, reasoning that the longest pattern should be processed first for better performance. The usage of the fast_pattern keyword give the user explicit control over this. Here is a Snort rule that is now properly handled by fwsnort (references removed): alert tcp $EXTERNAL_NET $HTTP_PORTS -> $HOME_NET any (msg:"ET WEB_CLIENT Possible Adobe Reader and Acrobat Forms Data Format Remote Security Bypass Attempt"; flow:established,to_client; file_data; content:"%FDF-"; depth:300; content:"/F(JavaScript|3a|"; nocase; distance:0; classtype:attempted-user; sid:2010664; rev:8;) Before this change, fwsnort translated this rule as: $IPTABLES -A FWSNORT_FORWARD_ESTAB -p tcp -m tcp --sport 80 -m string --hex-string "/F(JavaScript|3a|" --algo bm --from 69 --icase -m string --hex-string "%FDF|2d|" --algo bm --to 364 -m comment --comment "sid:2010664; msg:ET WEB_CLIENT Possible Adobe Reader and Acrobat Forms Data Format Remote Security Bypass Attempt; classtype:attempted-user; rev:8; FWS:1.6;" -j LOG --log-ip-options --log-tcp-options --log-prefix "SID2010664 ESTAB " Note that in the above rule, the "/F(JavaScript|3a|" pattern was switched to be evaluated first even though it is a relative match to the previous pattern in the original Snort rule. After this change, fwsnort translates this rule as: $IPTABLES -A FWSNORT_FORWARD_ESTAB -p tcp -m tcp --sport 80 -m string --hex-string "%FDF|2d|" --algo bm --to 364 -m string --hex-string "/F(JavaScript|3a|" --algo bm --from 69 --icase -m comment --comment "sid:2010664; msg:ET WEB_CLIENT Possible Adobe Reader and Acrobat Forms Data Format Remote Security Bypass Attempt; classtype:attempted-user; rev:8; FWS:1.6;" -j LOG --log-ip-options --log-tcp-options --log-prefix "SID2010664 ESTAB " - Updated to the latest Emerging Threats rule set. fwsnort-1.6 (07/28/2011): - Fixed the --ipt-apply functionality - the variable that held the fwsnort.sh path was not initialized properly prior to this change. - Added the --Conntrack-state argument to specify a conntrack state in place of the "established" state that commonly accompanies the Snort "flow" keyword. By default, fwsnort uses the conntrack state of "ESTABLISHED" for this. In certain corner cases, it might be useful to use "ESTABLISHED,RELATED" instead to apply application layer inspection to things like ICMP port unreachable messages that are responses to real attempted communications. (Need to add UDP tracking for the _ESTAB chains for this too - coming soon.) - Recent releases of iptables and the Linux kernel support matching on connection state via the conntrack modules and the --ctstate switch. Added a capabilities test for this, and will fall back to using the state match if the conntrack module is not available. - Bugfix to ensure the iptables log prefixes built by fwsnort are not longer than those allowed by the running iptables firewall. This is usually a total of 29 characters, but fwsnort now dynamically figures out this value. - Bugfix for --ipt-list and --ipt-flush to ensure that the proper iptables binary path is chosen. These args failed without this because the iptables binary was not set. fwsnort-1.5 (01/08/2011): - Major update to use the iptables-save format instead of the older strategy of always just executing iptables commands directly (which was very flow for large fwsnort policies). The /etc/fwsnort/fwsnort.sh script now just executes: /sbin/iptables-restore < /etc/fwsnort/fwsnort.save All fwsnort rules are now placed in the /etc/fwsnort/fwsnort.save file, but the older fwsnort.sh output (for the individual commands version) is still available at /etc/fwsnort/fwsnort_iptcmds.sh. This functionality extends to ip6tables policies as well. The fwsnort man page explain this in better detail: "As of fwsnort-1.5 all iptables rules built by fwsnort are written out to the /etc/fwsnort/fwsnort.save file in iptables-save format. This allows a long fwsnort policy (which may contain thousands of iptables rules translated from a large Snort signature set) to be quickly instantiated via the "iptables-restore" command. A wrapper script /etc/fwsnort/fwsnort.sh is also written out to make this easy. Hence, the typical work flow for fwsnort is to: 1) run fwsnort, 2) note the Snort rules that fwsnort was able to successfully translate (the number of such rules is printed to stdout), and then 3) execute the /etc/fwsnort/fwsnort.sh wrapper script to instantiate the policy in the running kernel." - Added the --rules-url argument so that the URL for updating the Emerging Threats rule set can be specified from the command line. The default is: http://rules.emergingthreats.net/open/snort-2.9.0/emerging-all.rules - Updated to automatically check for the maximum length string that the string match supports, and this is used to through out any Snort rules with content matches longer than this length. - Updated the iptables capabilities testing routines to add and delete testing rules to/from the custom chain 'FWS_CAP_TEST'. This maintains a a cleaner separation between fwsnort and any existing iptables policy even during the capabilities testing phase. - Added the --ipt-check-capabilities argument to have fwsnort test the capabilities of the local iptables firewall and exit. - Added the --string-match-alg argument to allow the string matching algorithm used by fwsnort to be specified from the command line. The default algorithm is 'bm' for 'Boyer-Moore', but 'kmp' may also be specified (short for the 'Knuth–Morris–Pratt' algorithm). - Updated to the latest complete rule set from Emerging Threats (see http://www.emergingthreats.net/). fwsnort-1.1 (01/05/2010): - Added the ability to build an fwsnort policy that utilizes ip6tables instead of iptables. This allows fwsnort filtering and altering capabilities to apply to IPv6 traffic instead of just IPv4 traffic. To enable ip6tables usage, use the "-6" or "--ip6tables" command line arguments. - Added the --include-perl-triggers command line argument so that translated Snort rules can easily be tested. This argument instructs fwsnort to include 'perl -e print ... ' commands as comments in the /etc/fwsnort/fwsnort.sh script, and these commands can be combined with netcat to send payloads across the wire that match Snort rules. - Updated fwsnort to create logs in the /var/log/fwsnort/ directory instead of directly in the /var/log/ directory. The path is controlled by a new variable 'LOG_FILE' in the /etc/fwsnort/fwsnort.conf file. - Added several variables in /etc/fwsnort/fwsnort.conf to control paths to everything from the config file to the snort rules path. Coupled with this is the ability to create variables within path components and fwsnort will expand them (e.g. 'CONF_DIR /etc/fwsnort; CONF_FILE $CONF_DIR/fwsnort.conf'). - Added --Last-cmd arg so that it is easy to rebuild the fwsnort.sh script with the same command line args as the previous execution. fwsnort-1.0.6 (05/30/2009): - (Franck Joncourt) Updated fwsnort to use the "!