added replay attack detection test
This commit is contained in:
+152
-57
@@ -1,17 +1,20 @@
|
||||
#!/usr/bin/perl -w
|
||||
|
||||
use IO::Socket;
|
||||
use Data::Dumper;
|
||||
use Getopt::Long 'GetOptions';
|
||||
use strict;
|
||||
|
||||
#==================== config =====================
|
||||
my $logfile = 'test.log';
|
||||
my $logfile = 'test.log';
|
||||
my $local_key_file = 'local_spa.key';
|
||||
my $output_dir = 'output';
|
||||
my $lib_dir = '../lib/.libs';
|
||||
my $conf_dir = 'conf';
|
||||
my $run_dir = 'run';
|
||||
my $output_dir = 'output';
|
||||
my $lib_dir = '../lib/.libs';
|
||||
my $conf_dir = 'conf';
|
||||
my $run_dir = 'run';
|
||||
my $configure_path = '../configure';
|
||||
my $cmd_out_tmp = 'cmd.out';
|
||||
my $server_cmd_tmp = 'server_cmd.out';
|
||||
|
||||
my $default_conf = "$conf_dir/default_fwknopd.conf";
|
||||
my $default_access_conf = "$conf_dir/default_access.conf";
|
||||
@@ -471,6 +474,17 @@ my @tests = (
|
||||
"-i $loopback_intf --foreground --verbose",
|
||||
'fatal' => $NO
|
||||
},
|
||||
{
|
||||
'category' => 'Rijndael SPA ops',
|
||||
'subcategory' => 'client+server',
|
||||
'detail' => 'replay attack detection',
|
||||
'err_msg' => 'could not detect replay attack',
|
||||
'function' => \&replay_detection_rijndael,
|
||||
'cmdline' => $default_client_args,
|
||||
'fwknopd_cmdline' => "$fwknopdCmd $default_server_conf_args " .
|
||||
"-i $loopback_intf --foreground --verbose",
|
||||
'fatal' => $NO
|
||||
},
|
||||
|
||||
|
||||
);
|
||||
@@ -544,12 +558,12 @@ sub process_include_exclude() {
|
||||
if (@tests_to_include) {
|
||||
my $found = 0;
|
||||
for my $test (@tests_to_include) {
|
||||
if ($test_hr->{'category'} =~ /$test)/) {
|
||||
if ($test_hr->{'category'} =~ /$test/) {
|
||||
$found = 1;
|
||||
last;
|
||||
}
|
||||
}
|
||||
return 1 unless $found;
|
||||
return 0 unless $found;
|
||||
}
|
||||
if (@tests_to_exclude) {
|
||||
my $found = 0;
|
||||
@@ -572,16 +586,16 @@ sub compile_warnings() {
|
||||
unless $username;
|
||||
|
||||
return 0 unless &run_cmd("$sudo_path -u $username make -C .. clean",
|
||||
$current_test_file);
|
||||
$cmd_out_tmp, $current_test_file);
|
||||
return 0 unless &run_cmd("$sudo_path -u $username make -C ..",
|
||||
$current_test_file);
|
||||
$cmd_out_tmp, $current_test_file);
|
||||
|
||||
} else {
|
||||
|
||||
return 0 unless &run_cmd('make -C .. clean',
|
||||
$current_test_file);
|
||||
$cmd_out_tmp, $current_test_file);
|
||||
return 0 unless &run_cmd('make -C ..',
|
||||
$current_test_file);
|
||||
$cmd_out_tmp, $current_test_file);
|
||||
|
||||
}
|
||||
|
||||
@@ -621,7 +635,7 @@ sub expected_code_version() {
|
||||
if ($line =~ /(\d.*\d)/) {
|
||||
my $version = $1;
|
||||
return 0 unless &run_cmd($test_hr->{'cmdline'},
|
||||
$current_test_file);
|
||||
$cmd_out_tmp, $current_test_file);
|
||||
return 1 if &file_find_regex([qr/$version/], $current_test_file);
|
||||
}
|
||||
return 0;
|
||||
@@ -631,7 +645,7 @@ sub dump_config() {
|
||||
my $test_hr = shift;
|
||||
|
||||
return 0 unless &run_cmd($test_hr->{'cmdline'},
|
||||
$current_test_file);
|
||||
$cmd_out_tmp, $current_test_file);
|
||||
|
||||
### search for one of the config vars (basic check)
|
||||
return 0 unless &file_find_regex([qr/SYSLOG_IDENTITY/],
|
||||
@@ -644,7 +658,7 @@ sub override_config() {
|
||||
my $test_hr = shift;
|
||||
|
||||
return 0 unless &run_cmd($test_hr->{'cmdline'},
|
||||
$current_test_file);
|
||||
$cmd_out_tmp, $current_test_file);
|
||||
|
||||
### search for the altered config value
|
||||
return 0 unless &file_find_regex([qr/ENABLE_PCAP_PROMISC.*\'Y\'/],
|
||||
@@ -657,7 +671,7 @@ sub non_get_key_path() {
|
||||
my $test_hr = shift;
|
||||
|
||||
return 0 if &run_cmd($test_hr->{'cmdline'},
|
||||
$current_test_file);
|
||||
$cmd_out_tmp, $current_test_file);
|
||||
return 0 unless &file_find_regex([qr/could\snot\sopen/i],
|
||||
$current_test_file);
|
||||
return 1;
|
||||
@@ -667,7 +681,7 @@ sub no_allow_ip() {
|
||||
my $test_hr = shift;
|
||||
|
||||
return 0 if &run_cmd($test_hr->{'cmdline'},
|
||||
$current_test_file);
|
||||
$cmd_out_tmp, $current_test_file);
|
||||
return 0 unless &file_find_regex([qr/must\suse\sone\sof/i],
|
||||
$current_test_file);
|
||||
return 1;
|
||||
@@ -677,7 +691,7 @@ sub invalid_allow_ip() {
|
||||
my $test_hr = shift;
|
||||
|
||||
return 0 if &run_cmd($test_hr->{'cmdline'},
|
||||
$current_test_file);
|
||||
$cmd_out_tmp, $current_test_file);
|
||||
return 0 unless &file_find_regex([qr/Invalid\sallow\sIP\saddress/i],
|
||||
$current_test_file);
|
||||
return 1;
|
||||
@@ -687,7 +701,7 @@ sub invalid_proto() {
|
||||
my $test_hr = shift;
|
||||
|
||||
return 0 if &run_cmd($test_hr->{'cmdline'},
|
||||
$current_test_file);
|
||||
$cmd_out_tmp, $current_test_file);
|
||||
return 0 unless &file_find_regex([qr/Invalid\sSPA\saccess\smessage/i],
|
||||
$current_test_file);
|
||||
return 1;
|
||||
@@ -699,7 +713,7 @@ sub generate_spa_packet() {
|
||||
&write_key('fwknoptest', $local_key_file);
|
||||
|
||||
return 0 unless &run_cmd($test_hr->{'cmdline'},
|
||||
$current_test_file);
|
||||
$cmd_out_tmp, $current_test_file);
|
||||
return 0 unless &file_find_regex([qr/final\spacked/i],
|
||||
$current_test_file);
|
||||
|
||||
@@ -726,17 +740,34 @@ sub basic_rijndael_spa() {
|
||||
return $rv;
|
||||
}
|
||||
|
||||
sub server_start() {
|
||||
sub replay_detection_rijndael() {
|
||||
my $test_hr = shift;
|
||||
|
||||
my $rv = &client_server_interaction($test_hr, [],
|
||||
$USE_PREDEF_PKTS, $NO_FW_RULE, $NO_FORCE_STOP);
|
||||
### do a complete SPA cycle and then parse the SPA packet out of the
|
||||
### current test file and re-send
|
||||
|
||||
unless (&file_find_regex([qr/Starting\sfwknopd\smain\sevent\sloop/],
|
||||
$server_output_file)) {
|
||||
$rv = 0;
|
||||
return 0 unless &basic_rijndael_spa($test_hr);
|
||||
|
||||
my $spa_pkt = &get_spa_packet_from_file($current_test_file);
|
||||
|
||||
unless ($spa_pkt) {
|
||||
&write_test_file("[-] could not get SPA packet " .
|
||||
"from file: $current_test_file\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
my @packets = (
|
||||
{
|
||||
'proto' => 'udp',
|
||||
'port' => $default_spa_port,
|
||||
'dst_ip' => $loopback_ip,
|
||||
'data' => $spa_pkt,
|
||||
},
|
||||
);
|
||||
|
||||
my $rv = &client_server_interaction($test_hr, \@packets,
|
||||
$USE_PREDEF_PKTS, $NO_FW_RULE, $NO_FORCE_STOP);
|
||||
|
||||
if (&is_fwknopd_running()) {
|
||||
&stop_fwknopd();
|
||||
unless (&file_find_regex([qr/Got\sSIGTERM/],
|
||||
@@ -748,6 +779,36 @@ sub server_start() {
|
||||
$rv = 0;
|
||||
}
|
||||
|
||||
unless (&file_find_regex([qr/Replay\sdetected\sfrom\ssource\sIP/i],
|
||||
$server_output_file)) {
|
||||
$rv = 0;
|
||||
}
|
||||
|
||||
return $rv;
|
||||
}
|
||||
|
||||
sub server_start() {
|
||||
my $test_hr = shift;
|
||||
|
||||
my $rv = &client_server_interaction($test_hr, [],
|
||||
$USE_PREDEF_PKTS, $NO_FW_RULE, $NO_FORCE_STOP);
|
||||
|
||||
if (&is_fwknopd_running()) {
|
||||
&stop_fwknopd();
|
||||
unless (&file_find_regex([qr/Got\sSIGTERM/],
|
||||
$server_output_file)) {
|
||||
$rv = 0;
|
||||
}
|
||||
} else {
|
||||
&write_test_file("[-] server is not running.\n");
|
||||
$rv = 0;
|
||||
}
|
||||
|
||||
unless (&file_find_regex([qr/Starting\sfwknopd\smain\sevent\sloop/],
|
||||
$server_output_file)) {
|
||||
$rv = 0;
|
||||
}
|
||||
|
||||
return $rv;
|
||||
}
|
||||
|
||||
@@ -757,11 +818,6 @@ sub server_stop() {
|
||||
my $rv = &client_server_interaction($test_hr, [],
|
||||
$USE_PREDEF_PKTS, $NO_FW_RULE, $NO_FORCE_STOP);
|
||||
|
||||
unless (&file_find_regex([qr/Starting\sfwknopd\smain\sevent\sloop/],
|
||||
$server_output_file)) {
|
||||
$rv = 0;
|
||||
}
|
||||
|
||||
if (&is_fwknopd_running()) {
|
||||
&stop_fwknopd();
|
||||
unless (&file_find_regex([qr/Got\sSIGTERM/],
|
||||
@@ -864,7 +920,7 @@ sub client_server_interaction() {
|
||||
sleep 1;
|
||||
unless (&run_cmd("$fwknopdCmd $default_server_conf_args " .
|
||||
"--fw-list | grep $fake_ip |grep _exp_",
|
||||
$current_test_file)) {
|
||||
$cmd_out_tmp, $current_test_file)) {
|
||||
$rv = 0;
|
||||
}
|
||||
}
|
||||
@@ -891,9 +947,39 @@ sub client_server_interaction() {
|
||||
return $rv;
|
||||
}
|
||||
|
||||
sub get_spa_packet_from_file() {
|
||||
my $file = shift;
|
||||
|
||||
my $spa_pkt = '';
|
||||
|
||||
my $found_trigger_line = 0;
|
||||
open F, "< $file" or die "[*] Could not open file $file: $!";
|
||||
while (<F>) {
|
||||
if (/final\spacked/i) {
|
||||
$found_trigger_line = 1;
|
||||
next;
|
||||
}
|
||||
next unless $found_trigger_line;
|
||||
|
||||
### the next line with non whitespace is the SPA packet
|
||||
if (/(\S+)/) {
|
||||
$spa_pkt = $1;
|
||||
last;
|
||||
}
|
||||
}
|
||||
close F;
|
||||
|
||||
return $spa_pkt;
|
||||
}
|
||||
|
||||
sub send_packets() {
|
||||
my $pkts_ar = shift;
|
||||
|
||||
open F, ">> $current_test_file" or die $!;
|
||||
print F "[+] send_packets(): Sending the following packets...\n";
|
||||
print F Dumper $pkts_ar;
|
||||
close F;
|
||||
|
||||
for my $pkt_hr (@$pkts_ar) {
|
||||
if ($pkt_hr->{'proto'} eq 'tcp' or $pkt_hr->{'proto'} eq 'udp') {
|
||||
my $socket = IO::Socket::INET->new(
|
||||
@@ -922,7 +1008,7 @@ sub fw_list() {
|
||||
my $test_hr = shift;
|
||||
|
||||
return 0 unless &run_cmd($test_hr->{'cmdline'},
|
||||
$current_test_file);
|
||||
$cmd_out_tmp, $current_test_file);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -930,7 +1016,7 @@ sub fw_list_all() {
|
||||
my $test_hr = shift;
|
||||
|
||||
return 0 unless &run_cmd($test_hr->{'cmdline'},
|
||||
$current_test_file);
|
||||
$cmd_out_tmp, $current_test_file);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -938,7 +1024,7 @@ sub fw_flush() {
|
||||
my $test_hr = shift;
|
||||
|
||||
return 0 unless &run_cmd($test_hr->{'cmdline'},
|
||||
$current_test_file);
|
||||
$cmd_out_tmp, $current_test_file);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -946,7 +1032,7 @@ sub usage_info() {
|
||||
my $test_hr = shift;
|
||||
return 0 unless $test_hr->{'binary'};
|
||||
return 0 unless &run_cmd("$test_hr->{'binary'} -h",
|
||||
$current_test_file);
|
||||
$cmd_out_tmp, $current_test_file);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -954,7 +1040,7 @@ sub no_such_arg() {
|
||||
my $test_hr = shift;
|
||||
return 0 unless $test_hr->{'binary'};
|
||||
return 0 if &run_cmd("$test_hr->{'binary'} --no-such-arg",
|
||||
$current_test_file);
|
||||
$cmd_out_tmp, $current_test_file);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -963,7 +1049,7 @@ sub pie_binary() {
|
||||
my $test_hr = shift;
|
||||
return 0 unless $test_hr->{'binary'};
|
||||
&run_cmd("./hardening-check $test_hr->{'binary'}",
|
||||
$current_test_file);
|
||||
$cmd_out_tmp, $current_test_file);
|
||||
return 0 if &file_find_regex([qr/Position\sIndependent.*:\sno/i],
|
||||
$current_test_file);
|
||||
return 1;
|
||||
@@ -974,7 +1060,7 @@ sub stack_protected_binary() {
|
||||
my $test_hr = shift;
|
||||
return 0 unless $test_hr->{'binary'};
|
||||
&run_cmd("./hardening-check $test_hr->{'binary'}",
|
||||
$current_test_file);
|
||||
$cmd_out_tmp, $current_test_file);
|
||||
return 0 if &file_find_regex([qr/Stack\sprotected.*:\sno/i],
|
||||
$current_test_file);
|
||||
return 1;
|
||||
@@ -985,7 +1071,7 @@ sub fortify_source_functions() {
|
||||
my $test_hr = shift;
|
||||
return 0 unless $test_hr->{'binary'};
|
||||
&run_cmd("./hardening-check $test_hr->{'binary'}",
|
||||
$current_test_file);
|
||||
$cmd_out_tmp, $current_test_file);
|
||||
return 0 if &file_find_regex([qr/Fortify\sSource\sfunctions:\sno/i],
|
||||
$current_test_file);
|
||||
return 1;
|
||||
@@ -996,7 +1082,7 @@ sub read_only_relocations() {
|
||||
my $test_hr = shift;
|
||||
return 0 unless $test_hr->{'binary'};
|
||||
&run_cmd("./hardening-check $test_hr->{'binary'}",
|
||||
$current_test_file);
|
||||
$cmd_out_tmp, $current_test_file);
|
||||
return 0 if &file_find_regex([qr/Read.only\srelocations:\sno/i],
|
||||
$current_test_file);
|
||||
return 1;
|
||||
@@ -1007,7 +1093,7 @@ sub immediate_binding() {
|
||||
my $test_hr = shift;
|
||||
return 0 unless $test_hr->{'binary'};
|
||||
&run_cmd("./hardening-check $test_hr->{'binary'}",
|
||||
$current_test_file);
|
||||
$cmd_out_tmp, $current_test_file);
|
||||
return 0 if &file_find_regex([qr/Immediate\sbinding:\sno/i],
|
||||
$current_test_file);
|
||||
return 1;
|
||||
@@ -1016,7 +1102,7 @@ sub immediate_binding() {
|
||||
sub specs() {
|
||||
|
||||
&run_cmd("$fwknopdCmd $default_server_conf_args --fw-list-all",
|
||||
$current_test_file);
|
||||
$cmd_out_tmp, $current_test_file);
|
||||
|
||||
for my $cmd (
|
||||
'uname -a',
|
||||
@@ -1036,7 +1122,7 @@ sub specs() {
|
||||
'ls -l /usr/lib/*fko*',
|
||||
'ls -l /usr/local/lib/*fko*',
|
||||
) {
|
||||
&run_cmd($cmd, $current_test_file);
|
||||
&run_cmd($cmd, $cmd_out_tmp, $current_test_file);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@@ -1071,7 +1157,8 @@ sub start_fwknopd() {
|
||||
if ($pid == 0) {
|
||||
|
||||
### we are the child, so start fwknopd
|
||||
exit &run_cmd($test_hr->{'fwknopd_cmdline'}, $server_output_file);
|
||||
exit &run_cmd($test_hr->{'fwknopd_cmdline'},
|
||||
$server_cmd_tmp, $server_output_file);
|
||||
}
|
||||
return $pid;
|
||||
}
|
||||
@@ -1092,12 +1179,13 @@ sub dump_pids() {
|
||||
or die "[*] Could not open $current_test_file: $!";
|
||||
print C "\n" . localtime() . " [+] PID dump:\n";
|
||||
close C;
|
||||
&run_cmd("ps auxww | grep knop |grep -v grep", $current_test_file);
|
||||
&run_cmd("ps auxww | grep knop |grep -v grep",
|
||||
$cmd_out_tmp, $current_test_file);
|
||||
return;
|
||||
}
|
||||
|
||||
sub run_cmd() {
|
||||
my ($cmd, $file) = @_;
|
||||
my ($cmd, $cmd_out, $file) = @_;
|
||||
|
||||
if (-e $file) {
|
||||
open F, ">> $file"
|
||||
@@ -1110,7 +1198,17 @@ sub run_cmd() {
|
||||
print F "CMD: $cmd\n";
|
||||
close F;
|
||||
}
|
||||
my $rv = ((system "$cmd >> $file 2>&1") >> 8);
|
||||
|
||||
my $rv = ((system "$cmd > $cmd_out 2>&1") >> 8);
|
||||
|
||||
open C, "< $cmd_out" or die "[*] Could not open $cmd_out: $!";
|
||||
my @cmd_lines = <C>;
|
||||
close C;
|
||||
|
||||
open F, ">> $file" or die "[*] Could not open $file: $!";
|
||||
print F $_ for @cmd_lines;
|
||||
close F;
|
||||
|
||||
if ($rv == 0) {
|
||||
return 1;
|
||||
}
|
||||
@@ -1152,6 +1250,7 @@ sub init() {
|
||||
|
||||
die "[*] $conf_dir directory does not exist." unless -d $conf_dir;
|
||||
die "[*] $lib_dir directory does not exist." unless -d $lib_dir;
|
||||
die "[*] $run_dir directory does not exist." unless -d $run_dir;
|
||||
die "[*] default config $default_conf does not exist" unless -e $default_conf;
|
||||
die "[*] default access config $default_access_conf does not exist"
|
||||
unless -e $default_access_conf;
|
||||
@@ -1196,25 +1295,21 @@ sub init() {
|
||||
|
||||
sub is_fwknopd_running() {
|
||||
|
||||
my $cmd = "$fwknopdCmd $default_server_conf_args --status";
|
||||
&run_cmd("$fwknopdCmd $default_server_conf_args --status",
|
||||
$cmd_out_tmp, $current_test_file);
|
||||
|
||||
return 0 if &file_find_regex([qr/no\s+running/i], $cmd_out_tmp);
|
||||
|
||||
&run_cmd($cmd, $current_test_file);
|
||||
return 0 if &file_find_regex([qr/no\s+running/i], $current_test_file);
|
||||
return 1;
|
||||
}
|
||||
|
||||
sub stop_fwknopd() {
|
||||
|
||||
my $cmd = "$fwknopdCmd $default_server_conf_args -K";
|
||||
&run_cmd($cmd, $current_test_file);
|
||||
&run_cmd("$fwknopdCmd $default_server_conf_args -K",
|
||||
$cmd_out_tmp, $current_test_file);
|
||||
|
||||
sleep 1;
|
||||
|
||||
if (&is_fwknopd_running()) {
|
||||
&write_test_file("[*] stop_fwknopd(): Could not stop fwknopd.\n");
|
||||
} else {
|
||||
&write_test_file("[*] stop_fwknopd(): Successfully stopped fwknopd.\n");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user