From 15832b10c20212fe80aa5ba41521a4ad69965bb2 Mon Sep 17 00:00:00 2001 From: Stefan Schantl Date: Thu, 1 Apr 2021 20:02:48 +0200 Subject: [PATCH] IDS: Redesign backend for enabled/disabled sids in rulefiles. The enabled or disabled sids now will be written to an own provider exclusive configuration file which dynamically will be included by oinkmaster if needed. Signed-off-by: Stefan Schantl --- config/cfgroot/ids-functions.pl | 10 +- config/oinkmaster/oinkmaster.conf | 7 +- html/cgi-bin/ids.cgi | 158 +++++++++++++++++------------- 3 files changed, 97 insertions(+), 78 deletions(-) diff --git a/config/cfgroot/ids-functions.pl b/config/cfgroot/ids-functions.pl index 13803d1f41..9ea9b69dc7 100644 --- a/config/cfgroot/ids-functions.pl +++ b/config/cfgroot/ids-functions.pl @@ -50,12 +50,15 @@ our $dns_servers_file = "$settingsdir/suricata-dns-servers.yaml"; # File where the HTTP ports definition is stored. our $http_ports_file = "$settingsdir/suricata-http-ports.yaml"; -# File which contains the enabled sids. +# DEPRECATED - File which contains the enabled sids. our $enabled_sids_file = "$settingsdir/oinkmaster-enabled-sids.conf"; -# File which contains the disabled sids. +# DEPRECATED - File which contains the disabled sids. our $disabled_sids_file = "$settingsdir/oinkmaster-disabled-sids.conf"; +# File which contains includes for provider specific rule modifications. +our $oinkmaster_provider_includes_file = "$settingsdir/oinkmaster-provider-includes.conf"; + # File which contains wheater the rules should be changed. our $modify_sids_file = "$settingsdir/oinkmaster-modify-sids.conf"; @@ -144,8 +147,7 @@ my %dl_type_to_suffix = ( # sub check_and_create_filelayout() { # Check if the files exist and if not, create them. - unless (-f "$enabled_sids_file") { &create_empty_file($enabled_sids_file); } - unless (-f "$disabled_sids_file") { &create_empty_file($disabled_sids_file); } + unless (-f "$oinkmaster_provider_includes_file") { &create_empty_file($oinkmaster_provider_includes_file); } unless (-f "$modify_sids_file") { &create_empty_file($modify_sids_file); } unless (-f "$suricata_used_providers_file") { &create_empty_file($suricata_used_providers_file); } unless (-f "$ids_settings_file") { &create_empty_file($ids_settings_file); } diff --git a/config/oinkmaster/oinkmaster.conf b/config/oinkmaster/oinkmaster.conf index 57c3281395..4d4ee40efd 100644 --- a/config/oinkmaster/oinkmaster.conf +++ b/config/oinkmaster/oinkmaster.conf @@ -182,11 +182,8 @@ update_files = \.rules$|\.config$|\.conf$|\.txt$|\.map$ # files from included files. Example to load stuff from "/etc/foo.conf". # include /etc/foo.conf -# Include file for enabled sids. -include /var/ipfire/suricata/oinkmaster-enabled-sids.conf - -# Include file for disabled sids. -include /var/ipfire/suricata/oinkmaster-disabled-sids.conf +# Include file for provider specific includes. +include /var/ipfire/suricata/oinkmaster-provider-includes.conf # Include file which defines the runmode of suricata. include /var/ipfire/suricata/oinkmaster-modify-sids.conf diff --git a/html/cgi-bin/ids.cgi b/html/cgi-bin/ids.cgi index b10b8abbe2..c6bb86ae4f 100644 --- a/html/cgi-bin/ids.cgi +++ b/html/cgi-bin/ids.cgi @@ -317,9 +317,6 @@ if ($cgiparams{'RULESET'} eq $Lang::tr{'ids apply'}) { # Arrays to store which rulefiles have been enabled and will be used. my @enabled_rulefiles; - # Hash to store the user-enabled and disabled sids. - my %enabled_disabled_sids; - # Store if a restart of suricata is required. my $suricata_restart_required; @@ -341,88 +338,111 @@ if ($cgiparams{'RULESET'} eq $Lang::tr{'ids apply'}) { } } - # Read-in the files for enabled/disabled sids. - # This will be done by calling the read_enabled_disabled_sids_file function two times - # and merge the returned hashes together into the enabled_disabled_sids hash. - %enabled_disabled_sids = ( - &read_enabled_disabled_sids_file($IDS::disabled_sids_file), - &read_enabled_disabled_sids_file($IDS::enabled_sids_file)); + # Open oinkmaster main include file for provider modifications. + open(OINKM_INCL_FILE, ">", "$IDS::oinkmaster_provider_includes_file") or die "Could not open $IDS::oinkmaster_provider_includes_file. $!\n"; - # Loop through the hash of idsrules. - foreach my $rulefile (keys %idsrules) { - # Loop through the single rules of the rulefile. - foreach my $sid (keys %{$idsrules{$rulefile}}) { - # Skip the current sid if it is not numeric. - next unless ($sid =~ /\d+/ ); - - # Check if there exists a key in the cgiparams hash for this sid. - if (exists($cgiparams{$sid})) { - # Look if the rule is disabled. - if ($idsrules{$rulefile}{$sid}{'State'} eq "off") { - # Check if the state has been set to 'on'. - if ($cgiparams{$sid} eq "on") { - # Add/Modify the sid to/in the enabled_disabled_sids hash. - $enabled_disabled_sids{$sid} = "enabled"; + # Print file header and notice about autogenerated file. + print OINKM_INCL_FILE "#Autogenerated file. Any custom changes will be overwritten!\n"; + + # Get enabled providers. + my @enabled_providers = &IDS::get_enabled_providers(); + + # Loop through the array of enabled providers. + foreach my $provider (@enabled_providers) { + # Hash to store the used-enabled and disabled sids. + my %enabled_disabled_sids; + + # Generate modified sids file name for the current processed provider. + my $providers_modified_sids_file = "$IDS::settingsdir/oinkmaster-$provider-modified-sids.conf"; + + # Check if a modified sids file for this provider exists. + if (-f $providers_modified_sids_file) { + # Read-in the file for enabled/disabled sids. + %enabled_disabled_sids = &read_enabled_disabled_sids_file($providers_modified_sids_file); + } + + # Loop through the hash of idsrules. + foreach my $rulefile (keys %idsrules) { + # Split the rulefile to get the vendor. + my @filename_parts = split(/-/, $rulefile); + + # Assign rulefile vendor. + my $rulefile_vendor = @filename_parts[0]; + + # Skip the rulefile if the vendor is not our current processed provider. + next unless ($rulefile_vendor eq $provider); + + # Loop through the single rules of the rulefile. + foreach my $sid (keys %{$idsrules{$rulefile}}) { + # Skip the current sid if it is not numeric. + next unless ($sid =~ /\d+/ ); + + # Check if there exists a key in the cgiparams hash for this sid. + if (exists($cgiparams{$sid})) { + # Look if the rule is disabled. + if ($idsrules{$rulefile}{$sid}{'State'} eq "off") { + # Check if the state has been set to 'on'. + if ($cgiparams{$sid} eq "on") { + # Add/Modify the sid to/in the enabled_disabled_sids hash. + $enabled_disabled_sids{$sid} = "enabled"; + + # Drop item from cgiparams hash. + delete $cgiparams{$rulefile}{$sid}; + } + } + } else { + # Look if the rule is enabled. + if ($idsrules{$rulefile}{$sid}{'State'} eq "on") { + # Check if the state is 'on' and should be disabled. + # In this case there is no entry + # for the sid in the cgiparams hash. + # Add/Modify it to/in the enabled_disabled_sids hash. + $enabled_disabled_sids{$sid} = "disabled"; # Drop item from cgiparams hash. delete $cgiparams{$rulefile}{$sid}; } } - } else { - # Look if the rule is enabled. - if ($idsrules{$rulefile}{$sid}{'State'} eq "on") { - # Check if the state is 'on' and should be disabled. - # In this case there is no entry - # for the sid in the cgiparams hash. - # Add/Modify it to/in the enabled_disabled_sids hash. - $enabled_disabled_sids{$sid} = "disabled"; - - # Drop item from cgiparams hash. - delete $cgiparams{$rulefile}{$sid}; - } } } - } - # Open enabled sid's file for writing. - open(ENABLED_FILE, ">$IDS::enabled_sids_file") or die "Could not write to $IDS::enabled_sids_file. $!\n"; - - # Open disabled sid's file for writing. - open(DISABLED_FILE, ">$IDS::disabled_sids_file") or die "Could not write to $IDS::disabled_sids_file. $!\n"; - - # Write header to the files. - print ENABLED_FILE "#Autogenerated file. Any custom changes will be overwritten!\n"; - print DISABLED_FILE "#Autogenerated file. Any custom changes will be overwritten!\n"; - - # Check if the hash for enabled/disabled files contains any entries. - if (%enabled_disabled_sids) { - # Loop through the hash. - foreach my $sid (keys %enabled_disabled_sids) { - # Check if the sid is enabled. - if ($enabled_disabled_sids{$sid} eq "enabled") { - # Print the sid to the enabled_sids file. - print ENABLED_FILE "enablesid $sid\n"; - # Check if the sid is disabled. - } elsif ($enabled_disabled_sids{$sid} eq "disabled") { - # Print the sid to the disabled_sids file. - print DISABLED_FILE "disablesid $sid\n"; - # Something strange happende - skip the current sid. - } else { - next; + # Check if the hash for enabled/disabled sids contains any entries. + if (%enabled_disabled_sids) { + # Open providers modified sids file for writing. + open(PROVIDER_MOD_FILE, ">$providers_modified_sids_file") or die "Could not write to $providers_modified_sids_file. $!\n"; + + # Write header to the files. + print PROVIDER_MOD_FILE "#Autogenerated file. Any custom changes will be overwritten!\n"; + + # Loop through the hash. + foreach my $sid (keys %enabled_disabled_sids) { + # Check if the sid is enabled. + if ($enabled_disabled_sids{$sid} eq "enabled") { + # Print the sid to the enabled_sids file. + print PROVIDER_MOD_FILE "enablesid $sid\n"; + # Check if the sid is disabled. + } elsif ($enabled_disabled_sids{$sid} eq "disabled") { + # Print the sid to the disabled_sids file. + print PROVIDER_MOD_FILE "disablesid $sid\n"; + # Something strange happende - skip the current sid. + } else { + next; + } } + + # Close file handle for the providers modified sids file. + close(PROVIDER_MOD_FILE); + + # Add the file to the oinkmasters include file. + print OINKM_INCL_FILE "include $providers_modified_sids_file\n"; } } - # Close file for enabled_sids after writing. - close(ENABLED_FILE); - - # Close file for disabled_sids after writing. - close(DISABLED_FILE); + # Close the file handle after writing. + close(OINKM_INCL_FILE); # Handle enabled / disabled rulefiles. # - # Get enabled providers. - my @enabled_providers = &IDS::get_enabled_providers(); # Loop through the array of enabled providers. foreach my $provider(@enabled_providers) { -- 2.39.2