aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-x[-rw-r--r--]config/snort/snort.inc884
-rwxr-xr-x[-rw-r--r--]config/snort/snort.xml2
-rwxr-xr-x[-rw-r--r--]config/snort/snort_alerts.php0
-rwxr-xr-x[-rw-r--r--]config/snort/snort_check_for_rule_updates.php308
-rwxr-xr-x[-rw-r--r--]config/snort/snort_define_servers.php6
-rwxr-xr-x[-rw-r--r--]config/snort/snort_download_rules.php0
-rwxr-xr-x[-rw-r--r--]config/snort/snort_download_updates.php22
-rwxr-xr-x[-rw-r--r--]config/snort/snort_interfaces.php12
-rwxr-xr-x[-rw-r--r--]config/snort/snort_interfaces_edit.php131
-rwxr-xr-x[-rw-r--r--]config/snort/snort_preprocessors.php101
-rwxr-xr-x[-rw-r--r--]config/snort/snort_rules.php394
-rwxr-xr-x[-rw-r--r--]config/snort/snort_rules_edit.php40
-rwxr-xr-x[-rw-r--r--]config/snort/snort_rulesets.php220
13 files changed, 1619 insertions, 501 deletions
diff --git a/config/snort/snort.inc b/config/snort/snort.inc
index d930c08b..93db9424 100644..100755
--- a/config/snort/snort.inc
+++ b/config/snort/snort.inc
@@ -39,10 +39,13 @@ require_once("filter.inc");
/* package version */
$snort_version = "2.9.2.3";
-$pfSense_snort_version = "2.5.2";
+$pfSense_snort_version = "2.5.3";
$snort_package_version = "Snort {$snort_version} pkg v. {$pfSense_snort_version}";
$snort_rules_file = "snortrules-snapshot-2923.tar.gz";
$emerging_threats_version = "2.9.3";
+$flowbit_rules_file = "flowbit-required.rules";
+$snort_enforcing_rules_file = "snort.rules";
+
define("SNORTDIR", "/usr/local/etc/snort");
define("SNORTLOGDIR", "/var/log/snort");
@@ -719,6 +722,661 @@ function sync_snort_package_config() {
conf_mount_ro();
}
+function build_sid_msg_map($rules_path, $sid_file) {
+
+ /*************************************************************/
+ /* This function reads all the rules file in the passed */
+ /* $rules_path variable and produces a properly formatted */
+ /* sid-msg.map file for use by Snort and/or barnyard2. */
+ /*************************************************************/
+
+ $sidMap = array();
+ $rule_files = array();
+
+ /* First check if we were passed a directory, a single file */
+ /* or an array of filenames to read. Set our $rule_files */
+ /* variable accordingly. If we can't figure it out, return */
+ /* an empty rules map array. */
+ if (is_dir($rules_path))
+ $rule_files = glob($rules_path . "*.rules");
+ elseif (is_file($rules_path))
+ $rule_files = (array)$rules_path;
+ elseif (is_array($rules_path))
+ $rule_files = $rules_path;
+ else
+ return;
+
+ /* Read the rule files into an array, then iterate the list */
+ foreach ($rule_files as $file) {
+
+ /* Don't process files with "deleted" in the filename */
+ if (preg_match('/deleted/i', $file))
+ continue;
+
+ /* Read the file into an array, skipping empty lines. */
+ $rules_array = file($file, FILE_SKIP_EMPTY_LINES);
+ $record = "";
+ $b_Multiline = false;
+
+ /* Read and process each line from the rules in the */
+ /* current file. */
+ foreach ($rules_array as $rule) {
+
+ /* Skip any non-rule lines unless we're in */
+ /* multiline mode.
+ if (!preg_match('/^\s*#*\s*(alert|drop|pass)/i', $rule) && !$b_Multiline)
+ continue;
+
+ /* Test for a multi-line rule, and reassemble the */
+ /* pieces back into a single line. */
+ if (preg_match('/\\\\s*[\n]$/m', $rule)) {
+ $rule = substr($rule, 0, strrpos($rule, '\\'));
+ $record .= $rule;
+ $b_Multiline = true;
+ continue;
+ }
+ /* If the last segment of a multiline rule, then */
+ /* append it onto the previous parts to form a */
+ /* single-line rule for further processing below. */
+ elseif (!preg_match('/\\\\s*[\n]$/m', $rule) && $b_Multiline) {
+ $record .= $rule;
+ $rule = $record;
+ }
+ $b_Multiline = false;
+ $record = "";
+
+ /* Parse the rule to find sid and any references. */
+ $sid = '';
+ $msg = '';
+ $matches = '';
+ $sidEntry = '';
+ if (preg_match('/\bmsg\s*:\s*"(.+?)"\s*;/i', $rule, $matches))
+ $msg = trim($matches[1]);
+ if (preg_match('/\bsid\s*:\s*(\d+)\s*;/i', $rule, $matches))
+ $sid = trim($matches[1]);
+ if (!empty($sid) && !empty($msg)) {
+ $sidEntry = $sid . ' || ' . $msg;
+ preg_match_all('/\breference\s*:\s*([^\;]+)/i', $rule, $matches);
+ foreach ($matches[1] as $ref)
+ $sidEntry .= " || " . trim($ref);
+ $sidEntry .= "\n";
+ $sidMap[$sid] = $sidEntry;
+ }
+ }
+ }
+ /* Sort the generated sid-msg map by sid */
+ ksort($sidMap);
+
+ /* Now print the result to the supplied file */
+ file_put_contents($sid_file, array_values($sidMap));
+}
+
+function snort_merge_reference_configs($cfg_in, $cfg_out) {
+
+ /***********************************************************/
+ /* This function takes a list of "reference.config" files */
+ /* in the $cfg_in array and merges them into a single */
+ /* file specified by $cfg_out. The merging is done so */
+ /* no duplication of lines occurs in the output file. */
+ /***********************************************************/
+
+ $outMap = array();
+ foreach ($cfg_in as $file) {
+ $in = file($file, FILE_SKIP_EMPTY_LINES);
+ foreach ($in as $line) {
+ /* Skip comment lines */
+ if (preg_match('/^\s*#/', $line))
+ continue;
+ if (preg_match('/(\:)\s*(\w+)\s*(.*)/', $line, $matches)) {
+ if (!empty($matches[2]) && !empty($matches[3])) {
+ $matches[2] = trim($matches[2]);
+ if (!array_key_exists($matches[2], $outMap))
+ $outMap[$matches[2]] = trim($matches[3]);
+ }
+ }
+ }
+ }
+ /* Sort the new reference map. */
+ uksort($outMap,'strnatcasecmp');
+
+ /* Format and write it to the supplied output file. */
+ $format = "config reference: %-12s %s\n";
+ foreach ($outMap as $key=>$value)
+ $outMap[$key] = sprintf($format, $key, $value);
+ file_put_contents($cfg_out, array_values($outMap));
+}
+
+function snort_merge_classification_configs($cfg_in, $cfg_out) {
+
+ /************************************************************/
+ /* This function takes a list of "classification.config" */
+ /* files in the $cfg_in array and merges them into a */
+ /* single file specified by $cfg_out. The merging is done */
+ /* so no duplication of lines occurs in the output file. */
+ /************************************************************/
+
+ $outMap = array();
+ foreach ($cfg_in as $file) {
+ $in = file($file, FILE_SKIP_EMPTY_LINES);
+ foreach ($in as $line) {
+ if (preg_match('/(.*:)(\s*.*),(.*),(.*)/', $line, $matches)) {
+ /* Skip comment lines */
+ if (preg_match('/^\s*#/', $line))
+ continue;
+ if (!empty($matches[2]) && !empty($matches[3]) && !empty($matches[4])) {
+ $matches[2] = trim($matches[2]);
+ if (!array_key_exists($matches[2], $outMap))
+ $outMap[$matches[2]] = trim($matches[3]) . "," . trim($matches[4]);
+ }
+ }
+ }
+ }
+ /* Sort the new classification map. */
+ uksort($outMap,'strnatcasecmp');
+
+ /* Format and write it to the supplied output file. */
+ $format = "config classification: %s,%s\n";
+ foreach ($outMap as $key=>$value)
+ $outMap[$key] = sprintf($format, $key, $value);
+ file_put_contents($cfg_out, array_values($outMap));
+}
+
+function snort_load_rules_map($rules_path) {
+
+ /***************************************************************/
+ /* This function loads and returns an array with all the rules */
+ /* found in the *.rules files in the passed rules path. */
+ /* */
+ /* $rules_path can be: */
+ /* a directory (assumed to contain *.rules files) */
+ /* a filename (identifying a specific *.rules file) */
+ /* an array of filenames (identifying *.rules files) */
+ /***************************************************************/
+
+ $map_ref = array();
+ $rule_files = array();
+
+ if (empty($rules_path))
+ return $map_ref;
+
+ /***************************************************************
+ * Read all the rules into the map array.
+ * The structure of the map array is:
+ *
+ * map[gid][sid]['rule']['category']['disabled']['flowbits']
+ *
+ * where:
+ * gid = Generator ID from rule, or 1 if general text
+ * rule
+ * sid = Signature ID from rule
+ * rule = Complete rule text
+ * category = File name of file containing the rule
+ * disabled = 1 if rule is disabled (commented out), 0 if
+ * rule is enabled
+ * flowbits = Array of applicable flowbits if rule contains
+ * flowbits options
+ ***************************************************************/
+
+ /* First check if we were passed a directory, a single file */
+ /* or an array of filenames to read. Set our $rule_files */
+ /* variable accordingly. If we can't figure it out, return */
+ /* an empty rules map array. */
+ if (is_dir($rules_path))
+ $rule_files = glob($rules_path . "*.rules");
+ elseif (is_file($rules_path))
+ $rule_files = (array)$rules_path;
+ elseif (is_array($rules_path))
+ $rule_files = $rules_path;
+ else
+ return $map_ref;
+
+ /* Read the rule files into an array, then iterate the list */
+ /* to process the rules from the files one-by-one. */
+ foreach ($rule_files as $file) {
+
+ /* Don't process files with "deleted" in the filename. */
+ if (preg_match('/deleted/i', $file))
+ continue;
+
+ /* Read the file contents into an array, skipping */
+ /* empty lines. */
+ $rules_array = file($file, FILE_SKIP_EMPTY_LINES);
+ $record = "";
+ $b_Multiline = false;
+
+ /* Read and process each line from the rules in the */
+ /* current file into an array. */
+ foreach ($rules_array as $rule) {
+
+ /* Skip any lines that may be just spaces. */
+ if (trim($rule) == "")
+ continue;
+
+ /* Skip any non-rule lines unless we're in */
+ /* multiline mode. */
+ if (!preg_match('/^\s*#*\s*(alert|drop|pass)/i', $rule) && !$b_Multiline)
+ continue;
+
+ /* Test for a multi-line rule; loop and reassemble */
+ /* the pieces back into a single line. */
+ if (preg_match('/\\\\s*[\n]$/m', $rule)) {
+ $rule = substr($rule, 0, strrpos($rule, '\\'));
+ $record .= $rule;
+ $b_Multiline = true;
+ continue;
+ }
+ /* If the last segment of a multiline rule, then */
+ /* append it onto the previous parts to form a */
+ /* single-line rule for further processing below. */
+ elseif (!preg_match('/\\\\s*[\n]$/m', $rule) && $b_Multiline) {
+ $record .= $rule;
+ $rule = $record;
+ }
+
+ /* We have an actual single-line rule, or else a */
+ /* re-assembled multiline rule that is now a */
+ /* single-line rule, so store it in our rules map. */
+
+ /* Get and test the SID. If we don't find one, */
+ /* ignore and skip this rule as it is invalid. */
+ $sid = snort_get_sid($rule);
+ if (empty($sid)) {
+ $b_Multiline = false;
+ $record = "";
+ continue;
+ }
+
+ $gid = snort_get_gid($rule);
+ $map_ref[$gid][$sid]['rule'] = $rule;
+ $map_ref[$gid][$sid]['category'] = basename($file, ".rules");
+ if (preg_match('/^\s*\#+/', $rule))
+ $map_ref[$gid][$sid]['disabled'] = 1;
+ else
+ $map_ref[$gid][$sid]['disabled'] = 0;
+
+ /* Grab any associated flowbits from the rule. */
+ $map_ref[$gid][$sid]['flowbits'] = snort_get_flowbits($rule);
+
+ /* Reset our local flag and record variables */
+ /* for the next rule in the set. */
+ $b_Multiline = false;
+ $record = "";
+ }
+
+ /* Zero out our processing array and get the next file. */
+ unset($rules_array);
+ }
+ return $map_ref;
+}
+
+function snort_get_gid($rule) {
+
+ /****************************************************************/
+ /* If a gid is defined, then return it, else default to "1" for */
+ /* general text rules match. */
+ /****************************************************************/
+
+ if (preg_match('/\bgid\s*:\s*(\d+)\s*;/i', $rule, $matches))
+ return trim($matches[1]);
+ else
+ return "1";
+}
+
+function snort_get_sid($rule) {
+
+ /***************************************************************/
+ /* If a sid is defined, then return it, else default to an */
+ /* empty value. */
+ /***************************************************************/
+
+ if (preg_match('/\bsid\s*:\s*(\d+)\s*;/i', $rule, $matches))
+ return trim($matches[1]);
+ else
+ return "";
+}
+
+function snort_get_msg($rule) {
+
+ /**************************************************************/
+ /* Return the MSG section of the passed rule as a string. */
+ /**************************************************************/
+
+ $msg = "";
+ if (preg_match('/\bmsg\s*:\s*"(.+?)"\s*;/i', $rule, $matches))
+ $msg = trim($matches[1]);
+ return $msg;
+}
+
+function snort_get_flowbits($rule) {
+
+ /*************************************************************/
+ /* This will pull out "flowbits:" options from the rule text */
+ /* and return them in an array. */
+ /*************************************************************/
+
+ $flowbits = array();
+ if (preg_match_all('/flowbits\b:\s*(set|setx|unset|toggle|isset|isnotset)\s*,([^;]+)/i', $rule, $matches)) {
+ $i = -1;
+ while (++$i < count($matches[1])) {
+ $flowbits[] = trim($matches[1][$i]) ."," . trim($matches[2][$i]);
+ }
+ }
+ return $flowbits;
+}
+
+function snort_get_checked_flowbits(&$rules_map) {
+
+ /*************************************************************/
+ /* This function checks all the currently enabled rules to */
+ /* find any checked flowbits, and returns the checked */
+ /* flowbit names in an array. */
+ /*************************************************************/
+
+ $checked_flowbits = array();
+ foreach (array_keys($rules_map) as $k1) {
+ foreach (array_keys($rules_map[$k1]) as $k2) {
+ if ($rules_map[$k1][$k2]['disabled'] == 1)
+ continue;
+ if (empty($rules_map[$k1][$k2]['flowbits']))
+ continue;
+ foreach (array_values($rules_map[$k1][$k2]['flowbits']) as $flowbit) {
+ $action = substr($flowbit, 0, strpos($flowbit, ","));
+ if (preg_match('/is(not)?set/i', $action)) {
+ $tmp = substr($flowbit, strpos($flowbit, ",") +1 );
+ if (!in_array($tmp, $checked_flowbits))
+ $checked_flowbits[] = $tmp;
+ }
+ }
+ }
+ }
+ return $checked_flowbits;
+}
+
+function snort_get_set_flowbits(&$rules_map) {
+
+ /*********************************************************/
+ /* This function checks all the currently enabled rules */
+ /* to find any set flowbits, and returns the flowbit */
+ /* names in an array. */
+ /*********************************************************/
+
+ $set_flowbits = array();
+ foreach (array_keys($rules_map) as $k1) {
+ foreach (array_keys($rules_map[$k1]) as $k2) {
+ if ($rules_map[$k1][$k2]['disabled'] == 1)
+ continue;
+ if (empty($rules_map[$k1][$k2]['flowbits']))
+ continue;
+ foreach (array_values($rules_map[$k1][$k2]['flowbits']) as $flowbit) {
+ $action = substr($flowbit, 0, strpos($flowbit, ","));
+ if (preg_match('/^set/i', $action)) {
+ $tmp = substr($flowbit, strpos($flowbit, ",") +1 );
+ if (!in_array($tmp, $set_flowbits))
+ $set_flowbits[] = $tmp;
+ }
+ }
+ }
+ }
+ return $set_flowbits;
+}
+
+function snort_find_flowbit_required_rules(&$all_rules, &$unchecked_flowbits) {
+
+ /********************************************************/
+ /* This function finds all rules that must be enabled */
+ /* in order to satisfy the "checked flowbits" used by */
+ /* the currently enabled rules. It returns the list */
+ /* of required rules in an array. */
+ /********************************************************/
+
+ $required_flowbits_rules = array();
+ foreach (array_keys($all_rules) as $k1) {
+ foreach (array_keys($all_rules[$k1]) as $k2) {
+ if (empty($all_rules[$k1][$k2]['flowbits']))
+ continue;
+ foreach (array_values($all_rules[$k1][$k2]['flowbits']) as $flowbit) {
+ $action = substr($flowbit, 0, strpos($flowbit, ","));
+ if (preg_match('/^set/i', $action)) {
+ $tmp = substr($flowbit, strpos($flowbit, ",") +1 );
+ if (in_array($tmp, $unchecked_flowbits)) {
+ $required_flowbits_rules[$k1][$k2]['category'] = $all_rules[$k1][$k2]['category'];
+ if ($all_rules[$k1][$k2]['disabled'] == 0)
+ /* If not disabled, just return the rule text "as is" */
+ $required_flowbits_rules[$k1][$k2]['rule'] = ltrim($all_rules[$k1][$k2]['rule']);
+ else
+ /* If rule is disabled, remove leading '#' to enable it */
+ $required_flowbits_rules[$k1][$k2]['rule'] = ltrim(substr($all_rules[$k1][$k2]['rule'], strpos($all_rules[$k1][$k2]['rule'], "#") + 1));
+ }
+ }
+ }
+ }
+ }
+ return $required_flowbits_rules;
+}
+
+function snort_resolve_flowbits($rule_path) {
+
+ /******************************************************/
+ /* This function auto-resolves flowbit requirements */
+ /* by finding all checked flowbits in the currently */
+ /* enabled rules, and then making sure all the "set" */
+ /* flowbit rules for those "checked" flowbits are */
+ /* enabled. For any that are not enabled, they are */
+ /* copied to an array, enabled, and returned. */
+ /* */
+ /* $rule_path --> rules files of the interface */
+ /* to resolve flowbit dependencies */
+ /* for. This can be either of the */
+ /* following: */
+ /* - directory of *.rules files */
+ /* - array of *.rules filenames */
+ /* - a single *.rules filename */
+ /******************************************************/
+
+ $snortdir = SNORTDIR;
+
+ /* First, load up all the enabled rules. */
+ $rules_map = snort_load_rules_map($rule_path);
+
+ /* Next, find all the "checked" and "set" flowbits. */
+ $checked_flowbits = snort_get_checked_flowbits($rules_map);
+ $set_flowbits = snort_get_set_flowbits($rules_map);
+
+ /* We're done with the first rules array, so cleanup */
+ /* to conserve memory. */
+ unset($rules_map);
+
+ /* Next find any "checked" flowbits without matching */
+ /* "set" flowbit rules in the enabled rule set. */
+ $delta_flowbits = array_diff($checked_flowbits, $set_flowbits);
+
+ /* Cleanup and release the memory we no longer need. */
+ unset($checked_flowbits);
+ unset($set_flowbits);
+
+ /* Now find all the needed "set flowbit" rules from */
+ /* the master list of all rules. */
+ $all_rules_map = snort_load_rules_map("{$snortdir}/rules/");
+ $required_rules = snort_find_flowbit_required_rules($all_rules_map, $delta_flowbits);
+
+ /* Cleanup and release memory we no longer need. */
+ unset($all_rules_map);
+ unset($delta_flowbits);
+
+ return $required_rules;
+}
+
+function snort_write_flowbit_rules_file(&$flowbit_rules, $rule_file) {
+
+ /************************************************/
+ /* This function takes an array of rules in the */
+ /* rules_map format and writes them to the file */
+ /* given. */
+ /************************************************/
+
+ if (empty($flowbit_rules))
+ return;
+
+ /* See if we were passed a directory or full */
+ /* filename to write the rules to, and adjust */
+ /* the destination argument accordingly. */
+ if (is_dir($rule_file))
+ $rule_file = rtrim($rule_file, '/').'/flowbit-required.rules';
+
+ file_put_contents($rule_file, "# These rules set flowbits checked by your other enabled rules. If the\n");
+ file_put_contents($rule_file, "# the dependent flowbits are not set, then some of your chosen rules may\n", FILE_APPEND);
+ file_put_contents($rule_file, "# not fire. Enabling all rules that set these dependent flowbits ensures\n", FILE_APPEND);
+ file_put_contents($rule_file, "# your chosen rules fire as intended.\n#\n", FILE_APPEND);
+ file_put_contents($rule_file, "# If you wish to prevent alerts from any of these rules, add the GID:SID\n", FILE_APPEND);
+ file_put_contents($rule_file, "# of the rule to the Suppression List for the interface.\n", FILE_APPEND);
+ foreach (array_keys($flowbit_rules) as $k1) {
+ foreach (array_keys($flowbit_rules[$k1]) as $k2) {
+ file_put_contents($rule_file, "\n# Category: " . $flowbit_rules[$k1][$k2]['category'], FILE_APPEND);
+ file_put_contents($rule_file, " GID:" . $k1 . " SID:" . $k2 . "\n", FILE_APPEND);
+ file_put_contents($rule_file, $flowbit_rules[$k1][$k2]['rule'], FILE_APPEND);
+ }
+ }
+}
+
+function snort_load_vrt_policy($policy) {
+
+ /************************************************/
+ /* This function returns an array of all rules */
+ /* marked with the passed in $policy metadata. */
+ /* */
+ /* $policy --> desired VRT security policy */
+ /* 1. connectivity */
+ /* 2. balanced */
+ /* 3. security */
+ /************************************************/
+
+ $snortdir = SNORTDIR;
+ $vrt_policy_rules = array();
+
+ /* Create regular expression for searching. */
+ $policy_pcre = "/policy\\s" . $policy . "/i";
+
+ /* First, load up all the rules we have. */
+ $all_rules_map = snort_load_rules_map("{$snortdir}/rules/");
+
+ /* Now walk the rules list and find all those */
+ /* that are defined as active for the chosen */
+ /* security policy. */
+ foreach (array_keys($all_rules_map) as $k1) {
+ foreach (array_keys($all_rules_map[$k1]) as $k2) {
+ if (preg_match($policy_pcre, $all_rules_map[$k1][$k2]['rule'])) {
+ if (!preg_match('/flowbits\s*:\s*noalert/i', $all_rules_map[$k1][$k2]['rule'])) {
+ $vrt_policy_rules[$k1][$k2] = $all_rules_map[$k1][$k2];
+
+ /* Enable the policy rule if disabled */
+ if ($all_rules_map[$k1][$k2]['disabled'] == 1)
+ $vrt_policy_rules[$k1][$k2]['rule'] = ltrim(substr($all_rules_map[$k1][$k2]['rule'], strpos($all_rules_map[$k1][$k2]['rule'], "#") + 1));
+ }
+ }
+ }
+ }
+
+ /* Release memory we no longer need. */
+ unset($all_rules_map);
+
+ /* Return all the rules that match the policy. */
+ return $vrt_policy_rules;
+}
+
+function snort_write_enforcing_rules_file(&$rule_map, $rule_path) {
+
+ /************************************************/
+ /* This function takes a rules map array of */
+ /* the rules chosen for the active rule set */
+ /* and writes them out to the passed path. */
+ /************************************************/
+
+ global $snort_enforcing_rules_file;
+
+ $rule_file = "/snort.rules";
+
+ /* See if we were passed a directory or full */
+ /* filename to write the rules to, and adjust */
+ /* the destination argument accordingly. */
+ if (is_dir($rule_path))
+ $rule_file = rtrim($rule_path, '/').$rule_file;
+ else
+ $rule_file = $rule_path;
+
+ file_put_contents($rule_file, "# These rules are your current set of enforced rules for the protected\n");
+ file_put_contents($rule_file, "# interface. This list was compiled from the categories selected on the\n", FILE_APPEND);
+ file_put_contents($rule_file, "# CATEGORIES tab of the Snort configuration for the interface and/or any\n", FILE_APPEND);
+ file_put_contents($rule_file, "# chosen Snort VRT pre-defined IPS Policy.\n#\n", FILE_APPEND);
+ file_put_contents($rule_file, "# Any enablesid or disablesid customizations you made have been applied\n", FILE_APPEND);
+ file_put_contents($rule_file, "# to the rules in this file.\n\n", FILE_APPEND);
+ foreach (array_keys($rule_map) as $k1) {
+ foreach (array_keys($rule_map[$k1]) as $k2) {
+ file_put_contents($rule_file, $rule_map[$k1][$k2]['rule'], FILE_APPEND);
+ }
+ }
+}
+
+function snort_load_sid_mods($sids, $value) {
+
+ /*****************************************/
+ /* This function parses the string of */
+ /* SID values in $sids and returns an */
+ /* array with the SID as the key and */
+ /* passed $value as the value. The SID */
+ /* values in $sids are assumed to be */
+ /* delimited by "||". */
+ /*****************************************/
+
+ $result = array();
+ if (empty($sids) || empty($value))
+ return $result;
+ $tmp = explode("||", $sids);
+ foreach ($tmp as $v) {
+ if (preg_match('/\s\d+/', $v, $match))
+ $result[trim($match[0])] = $value;
+ }
+ return $result;
+}
+
+function snort_modify_sids(&$rule_map, $snortcfg) {
+
+ /*****************************************/
+ /* This function modifies the rules in */
+ /* the passed rules_map array based on */
+ /* values in the enablesid/disablesid */
+ /* configuration parameters. */
+ /* */
+ /* $rule_map = array of current rules */
+ /* $snortcfg = config settings */
+ /*****************************************/
+
+ if (!isset($snortcfg['rule_sid_on']) && !isset($snortcfg['rule_sid_off']))
+ return;
+
+ /* Load up our enablesid and disablesid */
+ /* arrays with lists of modified SIDs */
+ $enablesid = snort_load_sid_mods($snortcfg['rule_sid_on'], "enablesid");
+ $disablesid = snort_load_sid_mods($snortcfg['rule_sid_off'], "disablesid");
+
+ /* Turn on any rules that need to be */
+ /* forced "on" with enablesid mods. */
+ if (!empty($enablesid)) {
+ foreach ($enablesid as $k2 => $v) {
+ if ($rule_map[1][$k2]['disabled'] == 1)
+ $rule_map[1][$k2]['rule'] = ltrim(substr($rule_map[1][$k2]['rule'], strpos($rule_map[1][$k2]['rule'], "#") + 1));
+ }
+ }
+
+ /* Turn off any rules that need to be */
+ /* forced "off" with disablesid mods. */
+ if (!empty($disablesid)) {
+ foreach ($disablesid as $k2 => $v) {
+ if ($rule_map[1][$k2]['disabled'] == 0)
+ $rule_map[1][$k2]['rule'] = "# " . $rule_map[1][$k2]['rule'];
+ }
+ }
+}
+
/* Start of main config files */
/* open snort.sh for writing" */
function snort_create_rc() {
@@ -987,6 +1645,8 @@ function snort_generate_conf($snortcfg) {
$snortdir = SNORTDIR;
$snortlogdir = SNORTLOGDIR;
+ $flowbit_rules_file = "flowbit-required.rules";
+ $snort_enforcing_rules_file = "snort.rules";
if (!is_array($config['installedpackages']['snortglobal']['rule']))
return;
@@ -1013,7 +1673,7 @@ function snort_generate_conf($snortcfg) {
"{$snortlogdir}/snort_{$if_real}{$snort_uuid}",
"{$snortlogdir}/snort_{$if_real}{$snort_uuid}/barnyard2",
"{$snortcfgdir}/preproc_rules",
- "dynamicrules" => "{$snortcfgdir}/dynamicrules",
+ "dynamicrules" => "/usr/local/lib/snort/dynamicrules",
"dynamicengine" => "/usr/local/lib/snort/dynamicengine",
"dynamicpreprocessor" => "{$snortcfgdir}/dynamicpreprocessor"
);
@@ -1075,7 +1735,7 @@ function snort_generate_conf($snortcfg) {
$ssh_port = "22";
$snort_ports = array(
"dns_ports" => "53", "smtp_ports" => "25", "mail_ports" => "25,143,465,691",
- "http_ports" => "80", "oracle_ports" => "1521", "mssql_ports" => "1433",
+ "http_ports" => "80,901,3128,8080,9000", "oracle_ports" => "1521", "mssql_ports" => "1433",
"telnet_ports" => "23","snmp_ports" => "161", "ftp_ports" => "21",
"ssh_ports" => $ssh_port, "pop2_ports" => "109", "pop3_ports" => "110",
"imap_ports" => "143", "sip_proxy_ports" => "5060:5090,16384:32768",
@@ -1088,7 +1748,7 @@ function snort_generate_conf($snortcfg) {
"DCERPC_NCACN_IP_TCP" => "139,445", "DCERPC_NCADG_IP_UDP" => "138,1024:",
"DCERPC_NCACN_IP_LONG" => "135,139,445,593,1024:", "DCERPC_NCACN_UDP_LONG" => "135,1024:",
"DCERPC_NCACN_UDP_SHORT" => "135,593,1024:", "DCERPC_NCACN_TCP" => "2103,2105,2107",
- "DCERPC_BRIGHTSTORE" => "6503,6504"
+ "DCERPC_BRIGHTSTORE" => "6503,6504", "DNP3_PORTS" => "20000", "MODBUS_PORTS" => "502"
);
$portvardef = "";
@@ -1109,9 +1769,18 @@ preprocessor perfmonitor: time 300 file {$snortlogdir}/snort_{$if_real}{$snort_u
EOD;
- $def_flow_depth_type = '0';
- if (!empty($snortcfg['flow_depth']))
- $def_flow_depth_type = $snortcfg['flow_depth'];
+ $def_server_flow_depth_type = '300';
+ if ((!empty($snortcfg['server_flow_depth'])) || ($snortcfg['server_flow_depth'] == '0'))
+ $def_server_flow_depth_type = $snortcfg['server_flow_depth'];
+
+ $def_client_flow_depth_type = '300';
+ if ((!empty($snortcfg['client_flow_depth'])) || ($snortcfg['client_flow_depth'] == '0'))
+ $def_client_flow_depth_type = $snortcfg['client_flow_depth'];
+
+ if ($snortcfg['noalert_http_inspect'] == 'on')
+ $noalert_http_inspect = "no_alerts ";
+ else
+ $noalert_http_inspect = "";
$http_ports = str_replace(",", " ", $snort_ports['http_ports']);
/* def http_inspect */
@@ -1119,27 +1788,17 @@ EOD;
# HTTP Inspect #
preprocessor http_inspect: global iis_unicode_map unicode.map 1252 compress_depth 65535 decompress_depth 65535
-preprocessor http_inspect_server: server default \
- ports { {$http_ports} } \
- non_strict \
- non_rfc_char { 0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 } \
- flow_depth {$def_flow_depth_type} \
- apache_whitespace no \
- directory no \
- iis_backslash no \
- u_encode yes \
- extended_response_inspection \
- inspect_gzip \
- normalize_utf \
- normalize_javascript \
- unlimited_decompress \
- ascii no \
- chunk_length 500000 \
- bare_byte yes \
- double_decode yes \
- iis_unicode no \
- iis_delimiter no \
- multi_slash no
+preprocessor http_inspect_server: server default profile all {$noalert_http_inspect}\
+ ports { {$http_ports} } \
+ http_methods { GET POST PUT SEARCH MKCOL COPY MOVE LOCK UNLOCK NOTIFY POLL BCOPY BDELETE BMOVE LINK UNLINK OPTIONS HEAD DELETE TRACE TRACK CONNECT SOURCE SUBSCRIBE UNSUBSCRIBE PROPFIND PROPPATCH BPROPFIND BPROPPATCH RPC_CONNECT PROXY_SUCCESS BITS_POST CCM_POST SMS_POST RPC_IN_DATA RPC_OUT_DATA RPC_ECHO_DATA } \
+ server_flow_depth {$def_server_flow_depth_type} \
+ client_flow_depth {$def_client_flow_depth_type} \
+ enable_cookie \
+ extended_response_inspection \
+ inspect_gzip \
+ normalize_utf \
+ unlimited_decompress \
+ normalize_javascript
EOD;
@@ -1195,18 +1854,22 @@ EOD;
$pop_preproc = <<<EOD
preprocessor pop: \
ports { {$pop_ports} } \
- qp_decode_depth -1 \
+ memcap 1310700 \
+ qp_decode_depth 0 \
b64_decode_depth 0 \
- bitenc_decode_depth 100
+ bitenc_decode_depth 0
+
EOD;
$imap_ports = str_replace(",", " ", $snort_ports['imap_ports']);
$imap_preproc = <<<EOD
preprocessor imap: \
ports { {$imap_ports} } \
- qp_decode_depth -1 \
+ memcap 1310700 \
+ qp_decode_depth 0 \
b64_decode_depth 0 \
- bitenc_decode_depth 100
+ bitenc_decode_depth 0
+
EOD;
$smtp_ports = str_replace(",", " ", $snort_ports['mail_ports']);
@@ -1217,6 +1880,7 @@ preprocessor SMTP: \
ports { {$smtp_ports} } \
inspection_type stateful \
normalize cmds \
+ ignore_tls_data \
valid_cmds { MAIL RCPT HELP HELO ETRN EHLO EXPN VRFY ATRN SIZE BDAT DEBUG EMAL ESAM ESND ESOM EVFY IDENT NOOP RSET SEND SAML SOML AUTH TURN ETRN PIPELINING \
CHUNKING DATA DSN RSET QUIT ONEX QUEU STARTTLS TICK TIME TURNME VERB X-EXPS X-LINK2STATE XADR XAUTH XCIR XEXCH50 XGEN XLICENSE XQUEU XSTA XTRN XUSR } \
normalize_cmds { MAIL RCPT HELP HELO ETRN EHLO EXPN VRFY ATRN SIZE BDAT DEBUG EMAL ESAM ESND ESOM EVFY IDENT NOOP RSET SEND SAML SOML AUTH TURN ETRN \
@@ -1230,8 +1894,16 @@ PIPELINING CHUNKING DATA DSN RSET QUIT ONEX QUEU STARTTLS TICK TIME TURNME VERB
alt_max_command_line_len 246 { SEND SAML SOML AUTH TURN ETRN PIPELINING CHUNKING DATA DSN RSET QUIT ONEX } \
alt_max_command_line_len 246 { QUEU STARTTLS TICK TIME TURNME VERB X-EXPS X-LINK2STATE XADR } \
alt_max_command_line_len 246 { XAUTH XCIR XEXCH50 XGEN XLICENSE XQUEU XSTA XTRN XUSR } \
- xlink2state { enable }
-
+ xlink2state { enable } \
+ log_mailfrom \
+ log_rcptto \
+ log_email_hdrs \
+ email_hdrs_log_depth 1464 \
+ log_filename \
+ qp_decode_depth 0 \
+ b64_decode_depth 0 \
+ bitenc_decode_depth 0
+
EOD;
/* def sf_portscan */
@@ -1248,8 +1920,9 @@ EOD;
$sun_rpc_ports = str_replace(",", " ", $snort_ports['sun_rpc_ports']);
/* def other_preprocs */
$other_preprocs = <<<EOD
+
# Other preprocs #
-preprocessor rpc_decode: {$sun_rpc_ports}
+preprocessor rpc_decode: {$sun_rpc_ports} no_alert_multiple_requests no_alert_large_fragments no_alert_incomplete
# Back Orifice
preprocessor bo
@@ -1259,11 +1932,11 @@ EOD;
/* def dce_rpc_2 */
$dce_rpc_2 = <<<EOD
# DCE/RPC 2 #
-preprocessor dcerpc2: memcap 102400, events [smb, co, cl]
+preprocessor dcerpc2: memcap 102400, events [co]
preprocessor dcerpc2_server: default, policy WinXP, \
detect [smb [{$snort_ports['smb_ports']}], tcp 135, udp 135, rpc-over-http-server 593], \
autodetect [tcp 1025:, udp 1025:, rpc-over-http-server 1025:], \
- smb_max_chain 3
+ smb_max_chain 3, smb_invalid_shares ["C$", "D$", "ADMIN$"]
EOD;
@@ -1277,6 +1950,26 @@ preprocessor dns: \
EOD;
+ /* def dnp3_preprocessor */
+ $dnp3_ports = str_replace(",", " ", $snort_ports['DNP3_PORTS']);
+ $dnp3_preproc = <<<EOD
+# DNP3 preprocessor #
+preprocessor dnp3: \
+ ports { {$dnp3_ports} } \
+ memcap 262144 \
+ check_crc
+
+EOD;
+
+ /* def modbus_preprocessor */
+ $modbus_ports = str_replace(",", " ", $snort_ports['MODBUS_PORTS']);
+ $modbus_preproc = <<<EOD
+# Modbus preprocessor #
+preprocessor modbus: \
+ ports { {$modbus_ports} }
+
+EOD;
+
$def_ssl_ports_ignore = str_replace(",", " ", $snort_ports['ssl_ports']);
$ssl_preproc = <<<EOD
# Ignore SSL and Encryption #
@@ -1288,20 +1981,26 @@ EOD;
/* stream5 queued settings */
$def_max_queued_bytes_type = '';
- if (!empty($snortcfg['max_queued_bytes']))
+ if ((!empty($snortcfg['max_queued_bytes'])) || ($snortcfg['max_queued_bytes'] == '0'))
$def_max_queued_bytes_type = ", max_queued_bytes {$snortcfg['max_queued_bytes']}";
$def_max_queued_segs_type = '';
- if (!empty($snortcfg['max_queued_segs']))
+ if ((!empty($snortcfg['max_queued_segs'])) || ($snortcfg['max_queued_segs'] == '0'))
$def_max_queued_segs_type = ", max_queued_segs {$snortcfg['max_queued_segs']}";
+ $def_stream5_mem_cap = '';
+ if (!empty($snortcfg['stream5_mem_cap']))
+ $def_stream5_mem_cap = ", memcap {$snortcfg['stream5_mem_cap']}";
+
/* define servers and ports snortdefservers */
$snort_servers = array (
"dns_servers" => "\$HOME_NET", "smtp_servers" => "\$HOME_NET", "http_servers" => "\$HOME_NET",
"www_servers" => "\$HOME_NET", "sql_servers" => "\$HOME_NET", "telnet_servers" => "\$HOME_NET",
"snmp_servers" => "\$HOME_NET", "ftp_servers" => "\$HOME_NET", "ssh_servers" => "\$HOME_NET",
"pop_servers" => "\$HOME_NET", "imap_servers" => "\$HOME_NET", "sip_proxy_ip" => "\$HOME_NET",
- "sip_servers" => "\$HOME_NET", "rpc_servers" => "\$HOME_NET",
+ "sip_servers" => "\$HOME_NET", "rpc_servers" => "\$HOME_NET", "dnp3_server" => "\$HOME_NET",
+ "dnp3_client" => "\$HOME_NET", "modbus_server" => "\$HOME_NET", "modbus_client" => "\$HOME_NET",
+ "enip_server" => "\$HOME_NET", "enip_client" => "\$HOME_NET",
"aim_servers" => "64.12.24.0/23,64.12.28.0/23,64.12.161.0/24,64.12.163.0/24,64.12.200.0/24,205.188.3.0/24,205.188.5.0/24,205.188.7.0/24,205.188.9.0/24,205.188.153.0/24,205.188.179.0/24,205.188.248.0/24"
);
@@ -1318,11 +2017,11 @@ EOD;
"dce_rpc_2" => "dce2_preproc", "dns_preprocessor" => "dns_preproc", "ftp_preprocessor" => "ftptelnet_preproc", "imap_preproc" => "imap_preproc",
"pop_preproc" => "pop_preproc", "reputation_preproc" => "reputation_preproc", "sensitive_data" => "sdf_preproc",
"sip_preproc" => "sip_preproc", "smtp_preprocessor" => "smtp_preproc", "ssh_preproc" => "ssh_preproc",
- "ssl_preproc" => "ssl_preproc"
+ "ssl_preproc" => "ssl_preproc", "dnp3_preproc" => "dnp3_preproc", "modbus_preproc" => "modbus_preproc"
);
$snort_preproc = array (
"perform_stat", "http_inspect", "other_preprocs", "ftp_preprocessor", "smtp_preprocessor", "ssl_preproc",
- "sf_portscan", "dce_rpc_2", "dns_preprocessor", "sensitive_data", "pop_preproc", "imap_preproc"
+ "sf_portscan", "dce_rpc_2", "dns_preprocessor", "sensitive_data", "pop_preproc", "imap_preproc", "dnp3_preproc", "modbus_preproc"
);
$snort_preprocessors = "";
foreach ($snort_preproc as $preproc) {
@@ -1380,21 +2079,58 @@ EOD;
/* generate rule sections to load */
$selected_rules_sections = "";
$dynamic_rules_sections = "";
- if (!empty($snortcfg['rulesets'])) {
- $enabled_rulesets_array = explode("||", $snortcfg['rulesets']);
- foreach($enabled_rulesets_array as $enabled_item) {
- if (file_exists("{$snortdir}/rules/{$enabled_item}") && !file_exists("{$snortcfgdir}/rules/{$enabled_item}"))
- @copy("{$snortdir}/rules/{$enabled_item}", "{$snortcfgdir}/rules/{$enabled_item}");
- if (substr($enabled_item, 0, 5) == "snort" && substr($enabled_item, -9) == ".so.rules") {
- $slib = substr($enabled_item, 6, -6);
- if (!file_exists("{$snort_dirs['dynamicrules']}/{$slib}"))
- @copy("/usr/local/lib/snort/dynamicrules/{$slib}", "{$snort_dirs['dynamicrules']}/{$slib}");
- if (file_exists("{$snort_dirs['dynamicrules']}/{$slib}") &&
- file_exists("{$snortcfgdir}/rules/{$enabled_item}"))
- $selected_rules_sections .= "include \$RULE_PATH/{$enabled_item}\n";
- } else if (file_exists("{$snortcfgdir}/rules/{$enabled_item}"))
- $selected_rules_sections .= "include \$RULE_PATH/{$enabled_item}\n";
+ if (!empty($snortcfg['rulesets']) || $snortcfg['ips_policy_enable'] == 'on') {
+ $enabled_rules = array();
+ $enabled_files = array();
+
+ /* Remove any existing rules files (except custom rules) prior to building a new set. */
+ foreach (glob("{$snortcfgdir}/rules/*.rules") as $file) {
+ if (basename($file, ".rules") != "custom")
+ @unlink($file);
+ }
+
+ /* Create an array with the full path filenames of the enabled */
+ /* rule category files if we have any. */
+ if (!empty($snortcfg['rulesets'])) {
+ foreach (explode("||", $snortcfg['rulesets']) as $file)
+ $enabled_files[] = "{$snortdir}/rules/" . $file;
+
+ /* Load our rules map in preparation for writing the enforcing rules file. */
+ $enabled_rules = snort_load_rules_map($enabled_files);
+ }
+
+ /* Check if a pre-defined Snort VRT policy is selected. If so, */
+ /* add all the VRT policy rules to our enforcing rule set. */
+ if (!empty($snortcfg['ips_policy'])) {
+ $policy_rules = snort_load_vrt_policy($snortcfg['ips_policy']);
+ foreach (array_keys($policy_rules) as $k1) {
+ foreach (array_keys($policy_rules[$k1]) as $k2) {
+ $enabled_rules[$k1][$k2]['rule'] = $policy_rules[$k1][$k2]['rule'];
+ $enabled_rules[$k1][$k2]['category'] = $policy_rules[$k1][$k2]['category'];
+ $enabled_rules[$k1][$k2]['disabled'] = $policy_rules[$k1][$k2]['disabled'];
+ $enabled_rules[$k1][$k2]['flowbits'] = $policy_rules[$k1][$k2]['flowbits'];
+ }
+ }
+ unset($policy_rules);
}
+
+ /* Process any enablesid or disablesid modifications for the selected rules. */
+ snort_modify_sids($enabled_rules, $snortcfg);
+
+ /* Write the enforcing rules file to the Snort interface's "rules" directory. */
+ snort_write_enforcing_rules_file($enabled_rules, "{$snortcfgdir}/rules/{$snort_enforcing_rules_file}");
+ if (file_exists("{$snortcfgdir}/rules/{$snort_enforcing_rules_file}"))
+ $selected_rules_sections = "include \$RULE_PATH/{$snort_enforcing_rules_file}\n";
+
+ /* If auto-flowbit resolution is enabled, generate the dependent flowbits rules file. */
+ if ($snortcfg['autoflowbitrules'] == 'on') {
+ $enabled_files[] = "{$snortcfgdir}/rules/{$snort_enforcing_rules_file}";
+ snort_write_flowbit_rules_file(snort_resolve_flowbits($enabled_files), "{$snortcfgdir}/rules/{$flowbit_rules_file}");
+ }
+
+ /* If we have the depedent flowbits rules file, then include it. */
+ if (file_exists("{$snortcfgdir}/rules/{$flowbit_rules_file}"))
+ $selected_rules_sections .= "include \$RULE_PATH/{$flowbit_rules_file}\n";
}
if (!empty($snortcfg['customrules'])) {
@@ -1403,6 +2139,10 @@ EOD;
} else
@unlink("{$snortcfgdir}/rules/custom.rules");
+ /* Build a new sid-msg.map file from the enabled */
+ /* rules and copy it to the interface directory. */
+ build_sid_msg_map("{$snortcfgdir}/rules/", "{$snortcfgdir}/sid-msg.map");
+
$cksumcheck = "all";
if ($snortcfg['cksumcheck'] == 'on')
$cksumcheck = "none";
@@ -1437,23 +2177,37 @@ config disable_tcpopt_alerts
config disable_ipopt_alerts
config disable_decode_drops
+# Configure PCRE match limitations
+config pcre_match_limit: 3500
+config pcre_match_limit_recursion: 1500
+
# Configure the detection engine #
-config detection: search-method {$snort_performance} max_queue_events 5
-config event_queue: max_queue 8 log 3 order_events content_length
+config detection: search-method {$snort_performance} search-optimize max-pattern-len 20 max_queue_events 5
+config event_queue: max_queue 8 log 5 order_events content_length
-#Configure dynamic loaded libraries
+# Configure protocol aware flushing #
+# For more information see README.stream5 #
+config paf_max: 16000
+
+#Configure dynamically loaded libraries
dynamicpreprocessor directory {$snort_dirs['dynamicpreprocessor']}
dynamicengine directory {$snort_dirs['dynamicengine']}
dynamicdetection directory {$snort_dirs['dynamicrules']}
+# Inline packet normalization. For more information, see README.normalize
+preprocessor normalize_ip4
+preprocessor normalize_tcp: ips ecn stream
+preprocessor normalize_icmp4
+preprocessor normalize_ip6
+preprocessor normalize_icmp6
+
# Flow and stream #
-preprocessor frag3_global: max_frags 8192
-preprocessor frag3_engine: policy bsd detect_anomalies
+preprocessor frag3_global: max_frags 65536
+preprocessor frag3_engine: policy bsd detect_anomalies overlap_limit 10 min_fragment_length 100 timeout 180
-preprocessor stream5_global: track_tcp yes, track_udp yes, track_icmp yes
-preprocessor stream5_tcp: policy BSD, ports both all{$def_max_queued_bytes_type}{$def_max_queued_segs_type}
-preprocessor stream5_udp:
-preprocessor stream5_icmp:
+preprocessor stream5_global: track_tcp yes, track_udp yes, track_icmp no, max_tcp 262144, max_udp 131072, max_active_responses 2, min_response_seconds 5{$def_stream5_mem_cap}
+preprocessor stream5_tcp: policy BSD, overlap_limit 10, timeout 180, ports both all{$def_max_queued_bytes_type}{$def_max_queued_segs_type}
+preprocessor stream5_udp: timeout 180
{$snort_preprocessors}
diff --git a/config/snort/snort.xml b/config/snort/snort.xml
index 07603176..b18e66e1 100644..100755
--- a/config/snort/snort.xml
+++ b/config/snort/snort.xml
@@ -47,7 +47,7 @@
<faq>Currently there are no FAQ items provided.</faq>
<name>Snort</name>
<version>2.9.2.3</version>
- <title>Services:2.9.2.3 pkg v. 2.5.1</title>
+ <title>Services:2.9.2.3 pkg v. 2.5.3</title>
<include_file>/usr/local/pkg/snort/snort.inc</include_file>
<menu>
<name>Snort</name>
diff --git a/config/snort/snort_alerts.php b/config/snort/snort_alerts.php
index e6ebefeb..e6ebefeb 100644..100755
--- a/config/snort/snort_alerts.php
+++ b/config/snort/snort_alerts.php
diff --git a/config/snort/snort_check_for_rule_updates.php b/config/snort/snort_check_for_rule_updates.php
index 61479a15..6ec8a1d8 100644..100755
--- a/config/snort/snort_check_for_rule_updates.php
+++ b/config/snort/snort_check_for_rule_updates.php
@@ -50,6 +50,8 @@ $emergingthreats_filename = "emerging.rules.tar.gz";
$oinkid = $config['installedpackages']['snortglobal']['oinkmastercode'];
$snortdownload = $config['installedpackages']['snortglobal']['snortdownload'];
$emergingthreats = $config['installedpackages']['snortglobal']['emergingthreats'];
+$vrt_enabled = $config['installedpackages']['snortglobal']['snortdownload'];
+$et_enabled = $config['installedpackages']['snortglobal']['emergingthreats'];
/* Start of code */
conf_mount_rw();
@@ -65,7 +67,7 @@ ini_set("memory_limit","150M");
if (is_dir("{$tmpfname}"))
exec("/bin/rm -r {$tmpfname}");
-/* Make shure snortdir exits */
+/* Make sure snortdir exits */
exec("/bin/mkdir -p {$snortdir}/rules");
exec("/bin/mkdir -p {$snortdir}/signatures");
exec("/bin/mkdir -p {$tmpfname}");
@@ -74,11 +76,22 @@ exec("/bin/mkdir -p /usr/local/lib/snort/dynamicrules");
/* download md5 sig from snort.org */
if ($snortdownload == 'on') {
update_status(gettext("Downloading snort.org md5 file..."));
- $image = @file_get_contents("http://www.snort.org/pub-bin/oinkmaster.cgi/{$oinkid}/{$snort_filename_md5}");
+ $max_tries = 4;
+ while ($max_tries > 0) {
+ $image = @file_get_contents("http://www.snort.org/pub-bin/oinkmaster.cgi/{$oinkid}/{$snort_filename_md5}");
+ if (false === $image) {
+ $max_tries--;
+ if ($max_tries > 0)
+ sleep(30);
+ continue;
+ } else
+ break;
+ }
+ log_error("Snort MD5 Attempts: " . (4 - $max_tries + 1));
@file_put_contents("{$tmpfname}/{$snort_filename_md5}", $image);
if (0 == filesize("{$tmpfname}/{$snort_filename_md5}")) {
update_status(gettext("Please wait... You may only check for New Rules every 15 minutes..."));
- log_error("Please wait... You may only check for New Rules every 15 minutes...");
+ log_error(gettext("Please wait... You may only check for New Rules every 15 minutes..."));
update_output_window(gettext("Rules are released every month from snort.org. You may download the Rules at any time."));
$snortdownload = 'off';
} else
@@ -101,12 +114,24 @@ if ($snortdownload == 'on') {
/* download snortrules file */
if ($snortdownload == 'on') {
update_status(gettext("There is a new set of Snort.org rules posted. Downloading..."));
- log_error("There is a new set of Snort.org rules posted. Downloading...");
- download_file_with_progress_bar("http://www.snort.org/pub-bin/oinkmaster.cgi/{$oinkid}/{$snort_filename}", "{$tmpfname}/{$snort_filename}");
+ log_error(gettext("There is a new set of Snort.org rules posted. Downloading..."));
+ $max_tries = 4;
+ while ($max_tries > 0) {
+ download_file_with_progress_bar("http://www.snort.org/pub-bin/oinkmaster.cgi/{$oinkid}/{$snort_filename}", "{$tmpfname}/{$snort_filename}");
+ if (300000 > filesize("{$tmpfname}/$snort_filename")){
+ $max_tries--;
+ if ($max_tries > 0)
+ sleep(30);
+ continue;
+ } else
+ break;
+ }
update_status(gettext("Done downloading rules file."));
+ log_error("Snort Rules Attempts: " . (4 - $max_tries + 1));
if (300000 > filesize("{$tmpfname}/$snort_filename")){
- update_output_window(gettext("Snort rules file downloaded failed..."));
- log_error("Snort rules file downloaded failed...");
+ update_output_window(gettext("Snort rules file download failed..."));
+ log_error(gettext("Snort rules file download failed..."));
+ log_error("Failed Rules Filesize: " . filesize("{$tmpfname}/$snort_filename"));
$snortdownload = 'off';
}
}
@@ -114,7 +139,13 @@ if ($snortdownload == 'on') {
/* download md5 sig from emergingthreats.net */
if ($emergingthreats == 'on') {
update_status(gettext("Downloading emergingthreats md5 file..."));
- $image = @file_get_contents("http://rules.emergingthreats.net/open/snort-{$emerging_threats_version}/emerging.rules.tar.gz.md5");
+
+ /* If using Sourcefire VRT rules with ET, then we should use the open-nogpl ET rules. */
+ if ($vrt_enabled == "on")
+ $image = @file_get_contents("http://rules.emergingthreats.net/open-nogpl/snort-{$emerging_threats_version}/emerging.rules.tar.gz.md5");
+ else
+ $image = @file_get_contents("http://rules.emergingthreats.net/open/snort-{$emerging_threats_version}/emerging.rules.tar.gz.md5");
+
/* XXX: error checking */
@file_put_contents("{$tmpfname}/{$emergingthreats_filename_md5}", $image);
update_status(gettext("Done downloading emergingthreats md5"));
@@ -125,7 +156,7 @@ if ($emergingthreats == 'on') {
$emerg_md5_check_old = file_get_contents("{$snortdir}/{$emergingthreats_filename_md5}");
if ($emerg_md5_check_new == $emerg_md5_check_old) {
update_status(gettext("Emerging threat rules are up to date..."));
- log_error("Emerging threat rules are up to date...");
+ log_error(gettext("Emerging threat rules are up to date..."));
$emergingthreats = 'off';
}
}
@@ -134,27 +165,18 @@ if ($emergingthreats == 'on') {
/* download emergingthreats rules file */
if ($emergingthreats == "on") {
update_status(gettext("There is a new set of Emergingthreats rules posted. Downloading..."));
- log_error("There is a new set of Emergingthreats rules posted. Downloading...");
- download_file_with_progress_bar("http://rules.emergingthreats.net/open/snort-{$emerging_threats_version}/emerging.rules.tar.gz", "{$tmpfname}/{$emergingthreats_filename}");
+ log_error(gettext("There is a new set of Emergingthreats rules posted. Downloading..."));
+
+ /* If using Sourcefire VRT rules with ET, then we should use the open-nogpl ET rules. */
+ if ($vrt_enabled == "on")
+ download_file_with_progress_bar("http://rules.emergingthreats.net/open-nogpl/snort-{$emerging_threats_version}/emerging.rules.tar.gz", "{$tmpfname}/{$emergingthreats_filename}");
+ else
+ download_file_with_progress_bar("http://rules.emergingthreats.net/open/snort-{$emerging_threats_version}/emerging.rules.tar.gz", "{$tmpfname}/{$emergingthreats_filename}");
+
update_status(gettext('Done downloading Emergingthreats rules file.'));
log_error("Emergingthreats rules file update downloaded succsesfully");
}
-/* XXX: need to be verified */
-/* Compair md5 sig to file sig */
-//$premium_url_chk = $config['installedpackages']['snort']['config'][0]['subscriber'];
-//if ($premium_url_chk == on) {
-//$md5 = file_get_contents("{$tmpfname}/{$snort_filename_md5}");
-//$file_md5_ondisk = `/sbin/md5 {$tmpfname}/{$snort_filename} | /usr/bin/awk '{ print $4 }'`;
-// if ($md5 == $file_md5_ondisk) {
-// update_status(gettext("Valid md5 checksum pass..."));
-//} else {
-// update_status(gettext("The downloaded file does not match the md5 file...P is ON"));
-// update_output_window(gettext("Error md5 Mismatch..."));
-// return;
-// }
-//}
-
/* Normalize rulesets */
$sedcmd = "s/^#alert/# alert/g\n";
$sedcmd .= "s/^##alert/# alert/g\n";
@@ -168,7 +190,7 @@ $sedcmd .= "s/^[ \\t]*alert/alert/g\n";
if ($emergingthreats == 'on') {
safe_mkdir("{$snortdir}/tmp/emerging");
if (file_exists("{$tmpfname}/{$emergingthreats_filename}")) {
- update_status(gettext("Extracting rules..."));
+ update_status(gettext("Extracting EmergingThreats.org rules..."));
exec("/usr/bin/tar xzf {$tmpfname}/{$emergingthreats_filename} -C {$snortdir}/tmp/emerging rules/");
$files = glob("{$snortdir}/tmp/emerging/rules/*.rules");
@@ -176,27 +198,27 @@ if ($emergingthreats == 'on') {
$newfile = basename($file);
@copy($file, "{$snortdir}/rules/{$newfile}");
}
- /* IP lists */
+ /* IP lists for Emerging Threats rules */
$files = glob("{$snortdir}/tmp/emerging/rules/*.txt");
foreach ($files as $file) {
$newfile = basename($file);
@copy($file, "{$snortdir}/rules/{$newfile}");
}
- if ($snortdownload == 'off') {
- foreach (array("classification.config", "reference.config", "sid-msg.map", "unicode.map") as $file) {
- if (file_exists("{$snortdir}/tmp/emerging/rules/{$file}"))
- @copy("{$snortdir}/tmp/emerging/rules/{$file}", "{$snortdir}/{$file}");
- }
+ /* base etc files for Emerging Threats rules */
+ foreach (array("classification.config", "reference.config", "gen-msg.map", "unicode.map") as $file) {
+ if (file_exists("{$snortdir}/tmp/emerging/rules/{$file}"))
+ @copy("{$snortdir}/tmp/emerging/rules/{$file}", "{$snortdir}/ET_{$file}");
}
- /* make shure default rules are in the right format */
- exec("/usr/bin/sed -I '' -f {$snortdir}/tmp/sedcmd {$snortdir}/rules/emerging*.rules");
+// /* make sure default rules are in the right format */
+// exec("/usr/bin/sed -I '' -f {$snortdir}/tmp/sedcmd {$snortdir}/rules/emerging*.rules");
/* Copy emergingthreats md5 sig to snort dir */
if (file_exists("{$tmpfname}/$emergingthreats_filename_md5")) {
update_status(gettext("Copying md5 sig to snort directory..."));
@copy("{$tmpfname}/$emergingthreats_filename_md5", "{$snortdir}/$emergingthreats_filename_md5");
}
+ update_status(gettext("Extraction of EmergingThreats.org rules completed..."));
}
}
@@ -208,7 +230,7 @@ if ($snortdownload == 'on') {
else
$freebsd_version_so = 'FreeBSD-8-1';
- update_status(gettext("Extracting Snort.org rules..."));
+ update_status(gettext("Extracting Snort VRT rules..."));
/* extract snort.org rules and add prefix to all snort.org files*/
safe_mkdir("{$snortdir}/tmp/snortrules");
exec("/usr/bin/tar xzf {$tmpfname}/{$snort_filename} -C {$snortdir}/tmp/snortrules rules/");
@@ -226,6 +248,7 @@ if ($snortdownload == 'on') {
exec("rm -r {$snortdir}/tmp/snortrules");
/* extract so rules */
+ update_status(gettext("Extracting Snort VRT Shared Objects rules..."));
exec('/bin/mkdir -p /usr/local/lib/snort/dynamicrules/');
$snort_arch = php_uname("m");
$nosorules = false;
@@ -241,6 +264,7 @@ if ($snortdownload == 'on') {
if ($nosorules == false) {
/* extract so rules none bin and rename */
+ update_status(gettext("Copying Snort VRT Shared Objects rules..."));
exec("/usr/bin/tar xzf {$tmpfname}/{$snort_filename} -C {$snortdir}/tmp so_rules/");
$files = glob("{$snortdir}/tmp/so_rules/*.rules");
foreach ($files as $file) {
@@ -250,22 +274,23 @@ if ($snortdownload == 'on') {
exec("rm -r {$snortdir}/tmp/so_rules");
/* extract base etc files */
+ update_status(gettext("Extracting Snort VRT base config files..."));
exec("/usr/bin/tar xzf {$tmpfname}/{$snort_filename} -C {$snortdir}/tmp etc/");
- foreach (array("classification.config", "reference.config", "gen-msg.map", "sid-msg.map", "unicode.map") as $file) {
+ foreach (array("classification.config", "reference.config", "gen-msg.map", "unicode.map") as $file) {
if (file_exists("{$snortdir}/tmp/etc/{$file}"))
- @copy("{$snortdir}/tmp/etc/{$file}", "{$snortdir}/{$file}");
+ @copy("{$snortdir}/tmp/etc/{$file}", "{$snortdir}/VRT_{$file}");
}
exec("rm -r {$snortdir}/tmp/etc");
/* Untar snort signatures */
$signature_info_chk = $config['installedpackages']['snortglobal']['signatureinfo'];
if ($premium_url_chk == 'on') {
- update_status(gettext("Extracting Signatures..."));
+ update_status(gettext("Extracting Snort VRT Signatures..."));
exec("/usr/bin/tar xzf {$tmpfname}/{$snort_filename} -C {$snortdir} doc/signatures/");
update_status(gettext("Done extracting Signatures."));
if (is_dir("{$snortdir}/doc/signatures")) {
- update_status(gettext("Copying signatures..."));
+ update_status(gettext("Copying Snort VRT signatures..."));
exec("/bin/cp -r {$snortdir}/doc/signatures {$snortdir}/signatures");
update_status(gettext("Done copying signatures."));
}
@@ -276,135 +301,154 @@ if ($snortdownload == 'on') {
exec("/usr/bin/tar xzf {$tmpfname}/{$snort_filename} -C {$snortdir} preproc_rules/");
- /* make shure default rules are in the right format */
- exec("/usr/bin/sed -I '' -f {$snortdir}/tmp/sedcmd {$snortdir}/rules/snort_*.rules");
+// /* make sure default rules are in the right format */
+// exec("/usr/bin/sed -I '' -f {$snortdir}/tmp/sedcmd {$snortdir}/rules/snort_*.rules");
if (file_exists("{$tmpfname}/{$snort_filename_md5}")) {
update_status(gettext("Copying md5 sig to snort directory..."));
@copy("{$tmpfname}/$snort_filename_md5", "{$snortdir}/$snort_filename_md5");
}
}
+ update_status(gettext("Extraction of Snort VRT rules completed..."));
}
}
/* remove old $tmpfname files */
if (is_dir("{$snortdir}/tmp")) {
- update_status(gettext("Cleaning up..."));
+ update_status(gettext("Cleaning up after rules extraction..."));
exec("/bin/rm -r {$snortdir}/tmp");
}
function snort_apply_customizations($snortcfg, $if_real) {
- global $config, $g, $snortdir;
-
- if (empty($snortcfg['rulesets']))
- return;
- else {
- update_status(gettext("Your set of configured rules are being copied..."));
- log_error("Your set of configured rules are being copied...");
- $enabled_rulesets_array = explode("||", $snortcfg['rulesets']);
- foreach($enabled_rulesets_array as $enabled_item) {
- @copy("{$snortdir}/rules/{$enabled_item}", "{$snortdir}/snort_{$snortcfg['uuid']}_{$if_real}/rules/{$enabled_item}");
- if (substr($enabled_item, 0, 5) == "snort" && substr($enabled_item, -9) == ".so.rules") {
- $slib = substr($enabled_item, 6, -6);
- if (file_exists("/usr/local/lib/snort/dynamicrules/{$slib}"))
- @copy("/usr/local/lib/snort/dynamicrules/{$slib}", "{$snortdir}/snort_{$snortcfg['uuid']}_{$if_real}/dynamicrules/{$slib}");
-
- }
- }
+ global $snortdir, $snort_enforcing_rules_file, $flowbit_rules_file;
- @copy("{$snortdir}/classification.config", "{$snortdir}/snort_{$snortcfg['uuid']}_{$if_real}/classification.config");
- @copy("{$snortdir}/gen-msg.map", "{$snortdir}/snort_{$snortcfg['uuid']}_{$if_real}/gen-msg.map");
- if (is_dir("{$snortdir}/generators"))
- exec("/bin/cp -r {$snortdir}/generators {$snortdir}/snort_{$snortcfg['uuid']}_{$if_real}");
- @copy("{$snortdir}/reference.config", "{$snortdir}/snort_{$snortcfg['uuid']}_{$if_real}/reference.config");
- @copy("{$snortdir}/sid", "{$snortdir}/snort_{$snortcfg['uuid']}_{$if_real}/sid");
- @copy("{$snortdir}/sid-msg.map", "{$snortdir}/snort_{$snortcfg['uuid']}_{$if_real}/sid-msg.map");
- @copy("{$snortdir}/unicode.map", "{$snortdir}/snort_{$snortcfg['uuid']}_{$if_real}/unicode.map");
- }
+ if (!empty($snortcfg['rulesets']) || $snortcfg['ips_policy_enable'] == 'on') {
+ $enabled_rules = array();
+ $enabled_files = array();
- if (!empty($snortcfg['rule_sid_on']) || !empty($snortcfg['rule_sid_off'])) {
- if (!empty($snortcfg['rule_sid_on'])) {
- $enabled_sid_on_array = explode("||", trim($snortcfg['rule_sid_on']));
- $enabled_sids = array_flip($enabled_sid_on_array);
+ /* Remove any existing rules files (except custom rules) prior to building a new set. */
+ foreach (glob("{$snortdir}/snort_{$snortcfg['uuid']}_{$if_real}/rules/*.rules") as $file) {
+ if (basename($file, ".rules") != "custom")
+ @unlink($file);
}
- if (!empty($snortcfg['rule_sid_off'])) {
- $enabled_sid_off_array = explode("||", trim($snortcfg['rule_sid_off']));
- $disabled_sids = array_flip($enabled_sid_off_array);
- }
+ /* Create an array with the full path filenames of the enabled */
+ /* rule category files if we have any. */
+ if (!empty($snortcfg['rulesets'])) {
+ foreach (explode("||", $snortcfg['rulesets']) as $file)
+ $enabled_files[] = "{$snortdir}/rules/" . $file;
- $files = glob("{$snortdir}/snort_{$snortcfg}_{$if_real}/rules/*.rules");
- foreach ($files as $file) {
- $splitcontents = file($file);
- $changed = false;
- foreach ( $splitcontents as $counter => $value ) {
- $sid = snort_get_rule_part($value, 'sid:', ';', 0);
- if (!is_numeric($sid))
- continue;
- if (isset($enabled_sids["enablesid {$sid}"])) {
- if (substr($value, 0, 5) == "alert")
- /* Rule is already enabled */
- continue;
- if (substr($value, 0, 7) == "# alert") {
- /* Rule is disabled, change */
- $splitcontents[$counter] = substr($value, 2);
- $changed = true;
- } else if (substr($splitcontents[$counter - 1], 0, 5) == "alert") {
- /* Rule is already enabled */
- continue;
- } else if (substr($splitcontents[$counter - 1], 0, 7) == "# alert") {
- /* Rule is disabled, change */
- $splitcontents[$counter - 1] = substr($value, 2);
- $changed = true;
- }
- } else if (isset($disabled_sids["disablesid {$sid}"])) {
- if (substr($value, 0, 7) == "# alert")
- /* Rule is already disabled */
- continue;
- if (substr($value, 0, 5) == "alert") {
- /* Rule is enabled, change */
- $splitcontents[$counter] = "# {$value}";
- $changed = true;
- } else if (substr($splitcontents[$counter - 1], 0, 7) == "# alert") {
- /* Rule is already disabled */
- continue;
- } else if (substr($splitcontents[$counter - 1], 0, 5) == "alert") {
- /* Rule is enabled, change */
- $splitcontents[$counter - 1] = "# {$value}";
- $changed = true;
- }
+ /* Load our rules map in preparation for writing the enforcing rules file. */
+ $enabled_rules = snort_load_rules_map($enabled_files);
+ }
+ /* Check if a pre-defined Snort VRT policy is selected. If so, */
+ /* add all the VRT policy rules to our enforcing rules set. */
+ if (!empty($snortcfg['ips_policy'])) {
+ $policy_rules = snort_load_vrt_policy($snortcfg['ips_policy']);
+ foreach (array_keys($policy_rules) as $k1) {
+ foreach (array_keys($policy_rules[$k1]) as $k2) {
+ $enabled_rules[$k1][$k2]['rule'] = $policy_rules[$k1][$k2]['rule'];
+ $enabled_rules[$k1][$k2]['category'] = $policy_rules[$k1][$k2]['category'];
+ $enabled_rules[$k1][$k2]['disabled'] = $policy_rules[$k1][$k2]['disabled'];
+ $enabled_rules[$k1][$k2]['flowbits'] = $policy_rules[$k1][$k2]['flowbits'];
}
}
- if ($changed == true)
- @file_put_contents($file, implode("\n", $splitcontents));
+ unset($policy_rules);
+ }
+
+ /* Process any enablesid or disablesid modifications for the selected rules. */
+ snort_modify_sids($enabled_rules, $snortcfg);
+
+ /* Write the enforcing rules file to the Snort interface's "rules" directory. */
+ snort_write_enforcing_rules_file($enabled_rules, "{$snortdir}/snort_{$snortcfg['uuid']}_{$if_real}/rules/{$snort_enforcing_rules_file}");
+
+ /* If auto-flowbit resolution is enabled, generate the dependent flowbits rules file. */
+ if ($snortcfg['autoflowbitrules'] == "on") {
+ update_status(gettext('Resolving and auto-enabling flowbit required rules for ' . snort_get_friendly_interface($snortcfg['interface']) . '...'));
+ log_error('Resolving and auto-enabling flowbit required rules for ' . snort_get_friendly_interface($snortcfg['interface']) . '...');
+ $enabled_files[] = "{$snortdir}/snort_{$snortcfg['uuid']}_{$if_real}/rules/{$snort_enforcing_rules_file}";
+ snort_write_flowbit_rules_file(snort_resolve_flowbits($enabled_files), "{$snortdir}/snort_{$snortcfg['uuid']}_{$if_real}/rules/{$flowbit_rules_file}");
}
+
+ /* Build a new sid-msg.map file from the enabled rules. */
+ build_sid_msg_map("{$snortdir}/snort_{$snortcfg['uuid']}_{$if_real}/rules/", "{$snortdir}/snort_{$snortcfg['uuid']}_{$if_real}/sid-msg.map");
+
+ /* Copy the master *.config and other *.map files to the interface's directory */
+ @copy("{$snortdir}/classification.config", "{$snortdir}/snort_{$snortcfg['uuid']}_{$if_real}/classification.config");
+ @copy("{$snortdir}/gen-msg.map", "{$snortdir}/snort_{$snortcfg['uuid']}_{$if_real}/gen-msg.map");
+ @copy("{$snortdir}/reference.config", "{$snortdir}/snort_{$snortcfg['uuid']}_{$if_real}/reference.config");
+ @copy("{$snortdir}/unicode.map", "{$snortdir}/snort_{$snortcfg['uuid']}_{$if_real}/unicode.map");
}
}
if ($snortdownload == 'on' || $emergingthreats == 'on') {
- /* You are Not Up to date, always stop snort when updating rules for low end machines */;
- /* Start the proccess for every interface rule */
+ update_status(gettext('Copying new config and map files...'));
+
+ /* Determine which base etc file set to use for the master copy. */
+ /* If the Snort VRT rules are not enabled, then use Emerging Threats. */
+ if (($vrt_enabled == 'off') && (et_enabled == 'on')) {
+ foreach (array("classification.config", "reference.config", "gen-msg.map", "unicode.map") as $file) {
+ if (file_exists("{$snortdir}/ET_{$file}"))
+ @rename("{$snortdir}/ET_{$file}", "{$snortdir}/{$file}");
+ }
+ }
+ elseif (($vrt_enabled == 'on') && ($et_enabled == 'off')) {
+ foreach (array("classification.config", "reference.config", "gen-msg.map", "unicode.map") as $file) {
+ if (file_exists("{$snortdir}/VRT_{$file}"))
+ @rename("{$snortdir}/VRT_{$file}", "{$snortdir}/{$file}");
+ }
+ }
+ else {
+ /* Both VRT and ET rules are enabled, so build combined */
+ /* reference.config and classification.config files. */
+ $cfgs = glob("{$snortdir}/*reference.config");
+ snort_merge_reference_configs($cfgs, "{$snortdir}/reference.config");
+ $cfgs = glob("{$snortdir}/*classification.config");
+ snort_merge_classification_configs($cfgs, "{$snortdir}/classification.config");
+ }
+
+ /* Clean-up our temp versions of the config and map files. */
+ update_status(gettext('Cleaning up temp files...'));
+ $cfgs = glob("{$snortdir}/??*_*.config");
+ foreach ($cfgs as $file) {
+ if (file_exists($file)) {
+ $cmd = "/bin/rm -r " . $file;
+ exec($cmd);
+ }
+ }
+ $cfgs = glob("{$snortdir}/??*_*.map");
+ foreach ($cfgs as $file) {
+ if (file_exists($file)) {
+ $cmd = "/bin/rm -r " . $file;
+ exec($cmd);
+ }
+ }
+
+ /* Start the proccess for each configured interface */
if (is_array($config['installedpackages']['snortglobal']['rule'])) {
foreach ($config['installedpackages']['snortglobal']['rule'] as $id => $value) {
- $if_real = snort_get_real_interface($value['interface']);
- /* make oinkmaster.conf for each interface rule */
+ /* Create configuration for each active Snort interface */
+ $if_real = snort_get_real_interface($value['interface']);
+ $tmp = "Updating rules configuration for: " . snort_get_friendly_interface($value['interface']) . " ...";
+ update_status(gettext($tmp));
+ log_error($tmp);
snort_apply_customizations($value, $if_real);
}
}
-
- exec("/bin/sh /usr/local/etc/rc.d/snort.sh restart");
- sleep(10);
- if (!is_process_running("snort"))
- exec("/bin/sh /usr/local/etc/rc.d/snort.sh start");
- update_output_window(gettext("Snort has restarted with your new set of rules..."));
- log_error("Snort has restarted with your new set of rules...");
-
+ update_status(gettext('Restarting Snort to activate the new set of rules...'));
+ exec("/bin/sh /usr/local/etc/rc.d/snort.sh restart");
+ sleep(10);
+ if (!is_process_running("snort"))
+ exec("/bin/sh /usr/local/etc/rc.d/snort.sh start");
+ update_output_window(gettext("Snort has restarted with your new set of rules..."));
+ log_error("Snort has restarted with your new set of rules...");
}
-update_status(gettext("The Rules update finished..."));
+update_status(gettext("The Rules update has finished..."));
+log_error("The Rules update has finished...");
conf_mount_ro();
?>
diff --git a/config/snort/snort_define_servers.php b/config/snort/snort_define_servers.php
index 20917d00..ca153d68 100644..100755
--- a/config/snort/snort_define_servers.php
+++ b/config/snort/snort_define_servers.php
@@ -55,7 +55,9 @@ $snort_servers = array (
"www_servers" => "\$HOME_NET", "sql_servers" => "\$HOME_NET", "telnet_servers" => "\$HOME_NET",
"snmp_servers" => "\$HOME_NET", "ftp_servers" => "\$HOME_NET", "ssh_servers" => "\$HOME_NET",
"pop_servers" => "\$HOME_NET", "imap_servers" => "\$HOME_NET", "sip_proxy_ip" => "\$HOME_NET",
-"sip_servers" => "\$HOME_NET", "rpc_servers" => "\$HOME_NET",
+"sip_servers" => "\$HOME_NET", "rpc_servers" => "\$HOME_NET", "dnp3_server" => "\$HOME_NET",
+"dnp3_client" => "\$HOME_NET", "modbus_server" => "\$HOME_NET", "modbus_client" => "\$HOME_NET",
+"enip_server" => "\$HOME_NET", "enip_client" => "\$HOME_NET",
"aim_servers" => "64.12.24.0/23,64.12.28.0/23,64.12.161.0/24,64.12.163.0/24,64.12.200.0/24,205.188.3.0/24,205.188.5.0/24,205.188.7.0/24,205.188.9.0/24,205.188.153.0/24,205.188.179.0/24,205.188.248.0/24"
);
@@ -79,7 +81,7 @@ $snort_ports = array(
"DCERPC_NCACN_IP_TCP" => "139,445", "DCERPC_NCADG_IP_UDP" => "138,1024:",
"DCERPC_NCACN_IP_LONG" => "135,139,445,593,1024:", "DCERPC_NCACN_UDP_LONG" => "135,1024:",
"DCERPC_NCACN_UDP_SHORT" => "135,593,1024:", "DCERPC_NCACN_TCP" => "2103,2105,2107",
-"DCERPC_BRIGHTSTORE" => "6503,6504"
+"DCERPC_BRIGHTSTORE" => "6503,6504", "DNP3_PORTS" => "20000", "MODBUS_PORTS" => "502"
);
$pconfig = $a_nat[$id];
diff --git a/config/snort/snort_download_rules.php b/config/snort/snort_download_rules.php
index bbbf689c..bbbf689c 100644..100755
--- a/config/snort/snort_download_rules.php
+++ b/config/snort/snort_download_rules.php
diff --git a/config/snort/snort_download_updates.php b/config/snort/snort_download_updates.php
index 4c4202a8..0c879e44 100644..100755
--- a/config/snort/snort_download_updates.php
+++ b/config/snort/snort_download_updates.php
@@ -39,6 +39,7 @@ require_once("/usr/local/pkg/snort/snort.inc");
global $g;
$snortdir = SNORTDIR;
+$snort_upd_log = "/tmp/snort_update.log";
/* load only javascript that is needed */
$snort_load_jquery = 'yes';
@@ -57,7 +58,7 @@ if (file_exists("{$snortdir}/emerging.rules.tar.gz.md5"))
/* check for logfile */
$update_logfile_chk = 'no';
-if (file_exists("{$snortdir}/snort_update.log"))
+if (file_exists("{$snort_upd_log}"))
$update_logfile_chk = 'yes';
$pgtitle = "Services: Snort: Updates";
@@ -68,6 +69,21 @@ include_once("head.inc");
<?php include("fbegin.inc"); ?>
<?if($pfsense_stable == 'yes'){echo '<p class="pgtitle">' . $pgtitle . '</p>';}?>
+
+<script language="javascript" type="text/javascript">
+function popup(url)
+{
+ params = 'width='+screen.width;
+ params += ', height='+screen.height;
+ params += ', top=0, left=0'
+ params += ', fullscreen=yes';
+
+ newwin=window.open(url,'windowname4', params);
+ if (window.focus) {newwin.focus()}
+ return false;
+}
+</script>
+
<table width="100%" border="0" cellpadding="0" cellspacing="0">
<tr><td>
<?php
@@ -157,10 +173,10 @@ include_once("head.inc");
if ($update_logfile_chk == 'yes') {
echo "
- <button href='/snort/snort_rules_edit.php?openruleset={$snortdir}/snort_update.log'><span class='pwhitetxt'>" . gettext("Update Log") . "&nbsp;&nbsp;&nbsp;&nbsp;</span></button>\n";
+ <button href='/snort/snort_rules_edit.php?openruleset={$snort_upd_log}'><span class='pwhitetxt'>" . gettext("Update Log") . "&nbsp;&nbsp;&nbsp;&nbsp;</span></button>\n";
}else{
echo "
- <button disabled='disabled' href='/snort/snort_rules_edit.php?openruleset={$snortdir}/snort_update.log'><span class='pwhitetxt'>" . gettext("Update Log") . "&nbsp;&nbsp;&nbsp;&nbsp;</span></button>\n";
+ <button disabled='disabled' href='/snort/snort_rules_edit.php?openruleset={$snort_upd_log}'><span class='pwhitetxt'>" . gettext("Update Log") . "&nbsp;&nbsp;&nbsp;&nbsp;</span></button>\n";
}
?>
diff --git a/config/snort/snort_interfaces.php b/config/snort/snort_interfaces.php
index 1e155e82..e8e690a8 100644..100755
--- a/config/snort/snort_interfaces.php
+++ b/config/snort/snort_interfaces.php
@@ -206,7 +206,7 @@ if ($pfsense_stable == 'yes')
<td width="17"></td>
<td><a href="snort_interfaces_edit.php?id=<?php echo $id_gen;?>"><img
src="../themes/<?= $g['theme']; ?>/images/icons/icon_plus.gif"
- width="17" height="17" border="0"></a></td>
+ width="17" height="17" border="0" title="<?php echo gettext('add interface');?>"></a></td>
</tr>
</table>
</td>
@@ -300,7 +300,7 @@ if ($pfsense_stable == 'yes')
<tr>
<td><a href="snort_interfaces_edit.php?id=<?=$i;?>"><img
src="/themes/<?= $g['theme']; ?>/images/icons/icon_e.gif"
- width="17" height="17" border="0" title="<?php echo gettext('edit rule'); ?>"></a></td>
+ width="17" height="17" border="0" title="<?php echo gettext('edit interface'); ?>"></a></td>
</tr>
</table>
@@ -313,11 +313,11 @@ if ($pfsense_stable == 'yes')
<tr>
<td><?php if ($nnats == 0): ?><img
src="../themes/<?= $g['theme']; ?>/images/icons/icon_x_d.gif"
- width="17" height="17" title="<?php echo gettext("delete selected rules"); ?>" border="0"><?php else: ?><input
+ width="17" height="17" title="<?php echo gettext("delete selected interface"); ?>" border="0"><?php else: ?><input
name="del" type="image"
src="../themes/<?= $g['theme']; ?>/images/icons/icon_x.gif"
- width="17" height="17" title="<?php echo gettext("delete selected mappings"); ?>"
- onclick="return confirm('Do you really want to delete the selected Snort Rule?')"><?php endif; ?></td>
+ width="17" height="17" title="<?php echo gettext("delete selected interface"); ?>"
+ onclick="return confirm('Do you really want to delete the selected Snort mapping?')"><?php endif; ?></td>
</tr>
</table>
</td>
@@ -357,7 +357,7 @@ if ($pfsense_stable == 'yes')
<strong>Click</strong> on the <img
src="../themes/<?= $g['theme']; ?>/images/icons/icon_e.gif"
width="17" height="17" border="0" title="<?php echo gettext("Edit Icon"); ?>"> icon to edit a
- interface and settings.<strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Click</strong>
+ interface and settings.<strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Click</strong>
on the <img
src="../themes/<?= $g['theme']; ?>/images/icons/icon_block.gif"
width="13" height="13" border="0" title="<?php echo gettext("Stop Icon"); ?>"> icon to <strong>stop</strong>
diff --git a/config/snort/snort_interfaces_edit.php b/config/snort/snort_interfaces_edit.php
index f47a055e..cec43bb7a 100644..100755
--- a/config/snort/snort_interfaces_edit.php
+++ b/config/snort/snort_interfaces_edit.php
@@ -72,7 +72,7 @@ if (isset($_GET['dup']))
if ($_POST["Submit"]) {
if ($_POST['descr'] == '' && $pconfig['descr'] == '') {
- $input_errors[] = "Please enter a description for your reference.";
+ $input_errors[] = "Please enter a description for your reference.";
}
if (!$_POST['interface'])
@@ -154,7 +154,7 @@ function enable_blockoffenders() {
function enable_change(enable_change) {
endis = !(document.iform.enable.checked || enable_change);
- // make shure a default answer is called if this is envoked.
+ // make sure a default answer is called if this is invoked.
endis2 = (document.iform.enable);
document.iform.performance.disabled = endis;
document.iform.blockoffenders7.disabled = endis;
@@ -232,7 +232,7 @@ function enable_change(enable_change) {
<?php endforeach; ?>
</select><br>
<span class="vexpl"><?php echo gettext("Choose which interface this rule applies to."); ?><br/>
- <b><?php echo gettext("Hint:"); ?> </b><?php echo gettext("in most cases, you'll want to use WAN here."); ?></span><br/><br/></td>
+ <span class="red"><?php echo gettext("Hint:"); ?> </span><?php echo gettext("in most cases, you'll want to use WAN here."); ?></span><br/></td>
</tr>
<tr>
<td width="22%" valign="top" class="vncellreq"><?php echo gettext("Description"); ?></td>
@@ -240,8 +240,56 @@ function enable_change(enable_change) {
class="formfld" id="descr" size="40"
value="<?=htmlspecialchars($pconfig['descr']);?>"> <br/>
<span class="vexpl"><?php echo gettext("You may enter a description here for your " .
- "reference (not parsed)."); ?></span><br/><br/></td>
+ "reference (not parsed)."); ?></span><br/></td>
</tr>
+<tr>
+ <td colspan="2" valign="top" class="listtopic"><?php echo gettext("Alert Settings"); ?></td>
+</tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell"><?php echo gettext("Send alerts to main " .
+ "System logs"); ?></td>
+ <td width="78%" class="vtable"><input name="alertsystemlog"
+ type="checkbox" value="on"
+ <?php if ($pconfig['alertsystemlog'] == "on") echo "checked"; ?>
+ onClick="enable_change(false)"><br>
+ <?php echo gettext("Snort will send Alerts to the firewall's system logs."); ?></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell"><?php echo gettext("Block offenders"); ?></td>
+ <td width="78%" class="vtable">
+ <input name="blockoffenders7" id="blockoffenders7" type="checkbox" value="on"
+ <?php if ($pconfig['blockoffenders7'] == "on") echo "checked"; ?>
+ onClick="enable_blockoffenders()"><br>
+ <?php echo gettext("Checking this option will automatically block hosts that generate a " .
+ "Snort alert."); ?></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell"><?php echo gettext("Kill states"); ?></td>
+ <td width="78%" class="vtable">
+ <input name="blockoffenderskill" id="blockoffenderskill" type="checkbox" value="on" <?php if ($pconfig['blockoffenderskill'] == "on") echo "checked"; ?>>
+ <br/><?php echo gettext("Checking this option will kill firewall states for the blocked ip"); ?>
+ </td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell"><?php echo gettext("Which ip to block"); ?></td>
+ <td width="78%" class="vtable">
+ <select name="blockoffendersip" class="formselect" id="blockoffendersip">
+ <?php
+ foreach (array("src", "dst", "both") as $btype) {
+ if ($btype == $pconfig['blockoffendersip'])
+ echo "<option value='{$btype}' selected>";
+ else
+ echo "<option value='{$btype}'>";
+ echo htmlspecialchars($btype) . '</option>';
+ }
+ ?>
+ </select>
+ <br/><?php echo gettext("Which ip extracted from the packet you want to block"); ?>
+ </td>
+ </tr>
+<tr>
+ <td colspan="2" valign="top" class="listtopic"><?php echo gettext("Performance Settings"); ?></td>
+</tr>
<tr>
<td width="22%" valign="top" class="vncell"><?php echo gettext("Memory Performance"); ?></td>
<td width="78%" class="vtable">
@@ -254,14 +302,22 @@ function enable_change(enable_change) {
<?=htmlspecialchars($ifacename2);?></option>
<?php endforeach; ?>
</select><br>
- <span class="vexpl"><?php echo gettext("Lowmem and ac-bnfa are recommended for low end " .
- "systems, Ac: high memory, best performance, ac-std: moderate " .
- "memory,high performance, acs: small memory, moderateperformance, " .
- "ac-banded: small memory,moderate performance, ac-sparsebands: small " .
+ <span class="vexpl"><?php echo gettext("LOWMEM and AC-BNFA are recommended for low end " .
+ "systems, AC: high memory, best performance, AC-STD: moderate " .
+ "memory,high performance, ACS: small memory, moderate performance, " .
+ "AC-BANDED: small memory,moderate performance, AC-SPARSEBANDS: small " .
"memory, high performance."); ?>
</span><br/></td>
</tr>
<tr>
+ <td width="22%" valign="top" class="vncell"><?php echo gettext("Checksum Check Disable"); ?></td>
+ <td width="78%" class="vtable">
+ <input name="cksumcheck" id="cksumcheck" type="checkbox" value="on" <?php if ($pconfig['cksumcheck'] == "on") echo "checked"; ?>>
+ <br><?php echo gettext("If ticked, checksum checking on Snort will be disabled to improve performance."); ?>
+ <br><?php echo gettext("Most of this is already done at the firewall/filter level."); ?>
+ </td>
+ </tr>
+ <tr>
<td colspan="2" valign="top" class="listtopic"><?php echo gettext("Choose the networks " .
"snort should inspect and whitelist."); ?></td>
</tr>
@@ -316,39 +372,6 @@ function enable_change(enable_change) {
"setting at default."); ?><br/></td>
</tr>
<tr>
- <td width="22%" valign="top" class="vncell"><?php echo gettext("Block offenders"); ?></td>
- <td width="78%" class="vtable">
- <input name="blockoffenders7" id="blockoffenders7" type="checkbox" value="on"
- <?php if ($pconfig['blockoffenders7'] == "on") echo "checked"; ?>
- onClick="enable_blockoffenders()"><br>
- <?php echo gettext("Checking this option will automatically block hosts that generate a " .
- "Snort alert."); ?></td>
- </tr>
- <tr>
- <td width="22%" valign="top" class="vncell"><?php echo gettext("Kill states"); ?></td>
- <td width="78%" class="vtable">
- <input name="blockoffenderskill" id="blockoffenderskill" type="checkbox" value="on" <?php if ($pconfig['blockoffenderskill'] == "on") echo "checked"; ?>>
- <br/<?php echo gettext("Should firewall states be killed for the blocked ip"); ?>>
- </td>
- </tr>
- <tr>
- <td width="22%" valign="top" class="vncell"><?php echo gettext("Which ip to block"); ?></td>
- <td width="78%" class="vtable">
- <select name="blockoffendersip" class="formselect" id="blockoffendersip">
- <?php
- foreach (array("src", "dst", "both") as $btype) {
- if ($btype == $pconfig['blockoffendersip'])
- echo "<option value='{$btype}' selected>";
- else
- echo "<option value='{$btype}'>";
- echo htmlspecialchars($btype) . '</option>';
- }
- ?>
- </select>
- <br/><?php echo gettext("Which ip extracted from the packet you want to block"); ?>
- </td>
- </tr>
- <tr>
<td width="22%" valign="top" class="vncell"><?php echo gettext("Whitelist"); ?></td>
<td width="78%" class="vtable">
<select name="whitelistname" class="formselect" id="whitelistname">
@@ -372,6 +395,10 @@ function enable_change(enable_change) {
<span class="red"><?php echo gettext("Note:"); ?></span><br/>&nbsp;<?php echo gettext("This option will only be used when block offenders is on."); ?>
</td>
</tr>
+<tr>
+ <td colspan="2" valign="top" class="listtopic"><?php echo gettext("Choose a suppression or filtering " .
+ "file if desired."); ?></td>
+</tr>
<tr>
<td width="22%" valign="top" class="vncell"><?php echo gettext("Suppression and filtering"); ?></td>
<td width="78%" class="vtable">
@@ -392,29 +419,12 @@ function enable_change(enable_change) {
?>
</select><br>
<span class="vexpl"><?php echo gettext("Choose the suppression or filtering file you " .
- "will like this rule to use."); ?> </span><br/>&nbsp;<br/><span class="red"><?php echo gettext("Note:"); ?></span><br/>&nbsp;<?php echo gettext("Default " .
+ "will like this interface to use."); ?> </span><br/>&nbsp;<br/><span class="red"><?php echo gettext("Note:"); ?></span><br/>&nbsp;<?php echo gettext("Default " .
"option disables suppression and filtering."); ?></td>
</tr>
- <tr>
- <td width="22%" valign="top" class="vncell"><?php echo gettext("Checksum checking"); ?></td>
- <td width="78%" class="vtable">
- <input name="cksumcheck" id="cksumcheck" type="checkbox" value="on" <?php if ($pconfig['cksumcheck'] == "on") echo "checked"; ?>>
- <br/<?php echo gettext("If ticked checksum checking on snort will be disabled to improve performance."); ?>>
- <br/<?php echo gettext("Most of this is already done on the firewall/filter level"); ?>>
- </td>
- </tr>
- <tr>
- <td width="22%" valign="top" class="vncell"><?php echo gettext("Send alerts to main " .
- "lSystem logs"); ?></td>
- <td width="78%" class="vtable"><input name="alertsystemlog"
- type="checkbox" value="on"
- <?php if ($pconfig['alertsystemlog'] == "on") echo "checked"; ?>
- onClick="enable_change(false)"><br>
- <?php echo gettext("Snort will send Alerts to the firewall's system logs."); ?></td>
- </tr>
<tr>
<td colspan="2" valign="top" class="listtopic"><?php echo gettext("Arguments here will " .
- "be automatically inserted into the snort configuration."); ?></td>
+ "be automatically inserted into the Snort configuration."); ?></td>
</tr>
<tr>
<td width="22%" valign="top" class="vncell"><?php echo gettext("Advanced configuration pass through"); ?></td>
@@ -432,7 +442,6 @@ function enable_change(enable_change) {
<tr>
<td width="22%" valign="top">&nbsp;</td>
<td width="78%"><span class="vexpl"><span class="red"><strong><?php echo gettext("Note:"); ?></strong></span><br/>
- <br>
<?php echo gettext("Please save your settings before you click start."); ?>
</td>
</tr>
diff --git a/config/snort/snort_preprocessors.php b/config/snort/snort_preprocessors.php
index d59af640..25e176cb 100644..100755
--- a/config/snort/snort_preprocessors.php
+++ b/config/snort/snort_preprocessors.php
@@ -55,10 +55,13 @@ if (isset($id) && $a_nat[$id]) {
/* new options */
$pconfig['perform_stat'] = $a_nat[$id]['perform_stat'];
- $pconfig['flow_depth'] = $a_nat[$id]['flow_depth'];
+ $pconfig['server_flow_depth'] = $a_nat[$id]['server_flow_depth'];
+ $pconfig['client_flow_depth'] = $a_nat[$id]['client_flow_depth'];
$pconfig['max_queued_bytes'] = $a_nat[$id]['max_queued_bytes'];
$pconfig['max_queued_segs'] = $a_nat[$id]['max_queued_segs'];
+ $pconfig['stream5_mem_cap'] = $a_nat[$id]['stream5_mem_cap'];
$pconfig['http_inspect'] = $a_nat[$id]['http_inspect'];
+ $pconfig['noalert_http_inspect'] = $a_nat[$id]['noalert_http_inspect'];
$pconfig['other_preprocs'] = $a_nat[$id]['other_preprocs'];
$pconfig['ftp_preprocessor'] = $a_nat[$id]['ftp_preprocessor'];
$pconfig['smtp_preprocessor'] = $a_nat[$id]['smtp_preprocessor'];
@@ -69,6 +72,8 @@ if (isset($id) && $a_nat[$id]) {
$pconfig['ssl_preproc'] = $a_nat[$id]['ssl_preproc'];
$pconfig['pop_preproc'] = $a_nat[$id]['pop_preproc'];
$pconfig['imap_preproc'] = $a_nat[$id]['imap_preproc'];
+ $pconfig['dnp3_preproc'] = $a_nat[$id]['dnp3_preproc'];
+ $pconfig['modbus_preproc'] = $a_nat[$id]['modbus_preproc'];
}
if ($_POST) {
@@ -78,12 +83,15 @@ if ($_POST) {
/* if no errors write to conf */
if (!$input_errors) {
/* post new options */
- if ($_POST['flow_depth'] != "") { $natent['flow_depth'] = $_POST['flow_depth']; }else{ $natent['flow_depth'] = ""; }
+ if ($_POST['server_flow_depth'] != "") { $natent['server_flow_depth'] = $_POST['server_flow_depth']; }else{ $natent['server_flow_depth'] = ""; }
+ if ($_POST['client_flow_depth'] != "") { $natent['client_flow_depth'] = $_POST['client_flow_depth']; }else{ $natent['client_flow_depth'] = ""; }
if ($_POST['max_queued_bytes'] != "") { $natent['max_queued_bytes'] = $_POST['max_queued_bytes']; }else{ $natent['max_queued_bytes'] = ""; }
if ($_POST['max_queued_segs'] != "") { $natent['max_queued_segs'] = $_POST['max_queued_segs']; }else{ $natent['max_queued_segs'] = ""; }
+ if ($_POST['stream5_mem_cap'] != "") { $natent['stream5_mem_cap'] = $_POST['stream5_mem_cap']; }else{ $natent['stream5_mem_cap'] = ""; }
$natent['perform_stat'] = $_POST['perform_stat'] ? 'on' : 'off';
$natent['http_inspect'] = $_POST['http_inspect'] ? 'on' : 'off';
+ $natent['noalert_http_inspect'] = $_POST['noalert_http_inspect'] ? 'on' : 'off';
$natent['other_preprocs'] = $_POST['other_preprocs'] ? 'on' : 'off';
$natent['ftp_preprocessor'] = $_POST['ftp_preprocessor'] ? 'on' : 'off';
$natent['smtp_preprocessor'] = $_POST['smtp_preprocessor'] ? 'on' : 'off';
@@ -94,6 +102,8 @@ if ($_POST) {
$natent['ssl_preproc'] = $_POST['ssl_preproc'] ? 'on' : 'off';
$natent['pop_preproc'] = $_POST['pop_preproc'] ? 'on' : 'off';
$natent['imap_preproc'] = $_POST['imap_preproc'] ? 'on' : 'off';
+ $natent['dnp3_preproc'] = $_POST['dnp3_preproc'] ? 'on' : 'off';
+ $natent['modbus_preproc'] = $_POST['modbus_preproc'] ? 'on' : 'off';
if (isset($id) && $a_nat[$id])
$a_nat[$id] = $natent;
@@ -175,7 +185,7 @@ include_once("head.inc");
<td width="78%" class="vtable"><input name="perform_stat"
type="checkbox" value="on"
<?php if ($pconfig['perform_stat']=="on") echo "checked"; ?>
- onClick="enable_change(false)"> <?php echo gettext("Performance Statistics for this interface."); ?></td>
+ onClick="enable_change(false)"> <?php echo gettext("Collect Performance Statistics for this interface."); ?></td>
</tr>
<tr>
<td colspan="2" valign="top" class="listtopic"><?php echo gettext("HTTP Inspect Settings"); ?></td>
@@ -193,20 +203,46 @@ include_once("head.inc");
<td class="vtable">
<table cellpadding="0" cellspacing="0">
<tr>
- <td><input name="flow_depth" type="text" class="formfld"
- id="flow_depth" size="5"
- value="<?=htmlspecialchars($pconfig['flow_depth']);?>"> <?php echo gettext("<strong>-1</strong> " .
- "to <strong>1460</strong> (<strong>-1</strong> disables HTTP " .
+ <td><input name="server_flow_depth" type="text" class="formfld"
+ id="flow_depth" size="6"
+ value="<?=htmlspecialchars($pconfig['server_flow_depth']);?>"> <?php echo gettext("<strong>-1</strong> " .
+ "to <strong>65535</strong> (<strong>-1</strong> disables HTTP " .
"inspect, <strong>0</strong> enables all HTTP inspect)"); ?></td>
</tr>
</table>
<?php echo gettext("Amount of HTTP server response payload to inspect. Snort's " .
"performance may increase by adjusting this value."); ?><br>
<?php echo gettext("Setting this value too low may cause false negatives. Values above 0 " .
- "are specified in bytes. Default value is <strong>0</strong>"); ?><br>
+ "are specified in bytes. Recommended setting is maximum (65535). Default value is <strong>300</strong>"); ?><br>
</td>
</tr>
<tr>
+ <td valign="top" class="vncell"><?php echo gettext("HTTP client flow depth"); ?></td>
+ <td class="vtable">
+ <table cellpadding="0" cellspacing="0">
+ <tr>
+ <td><input name="client_flow_depth" type="text" class="formfld"
+ id="flow_depth" size="6"
+ value="<?=htmlspecialchars($pconfig['client_flow_depth']);?>"> <?php echo gettext("<strong>-1</strong> " .
+ "to <strong>1460</strong> (<strong>-1</strong> disables HTTP " .
+ "inspect, <strong>0</strong> enables all HTTP inspect)"); ?></td>
+ </tr>
+ </table>
+ <?php echo gettext("Amount of raw HTTP client request payload to inspect. Snort's " .
+ "performance may increase by adjusting this value."); ?><br>
+ <?php echo gettext("Setting this value too low may cause false negatives. Values above 0 " .
+ "are specified in bytes. Recommended setting is maximum (1460). Default value is <strong>300</strong>"); ?><br>
+ </td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell"><?php echo gettext("Disable HTTP Alerts"); ?></td>
+ <td width="78%" class="vtable"><input name="noalert_http_inspect"
+ type="checkbox" value="on"
+ <?php if ($pconfig['noalert_http_inspect']=="on") echo "checked"; ?>
+ onClick="enable_change(false)"> <?php echo gettext("Tick to turn off alerts from the HTTP Inspect " .
+ "preprocessor. This has no effect on HTTP rules in the rule set."); ?></td>
+ </tr>
+ <tr>
<td colspan="2" valign="top" class="listtopic"><?php echo gettext("Stream5 Settings"); ?></td>
</tr>
<tr>
@@ -215,7 +251,7 @@ include_once("head.inc");
<table cellpadding="0" cellspacing="0">
<tr>
<td><input name="max_queued_bytes" type="text" class="formfld"
- id="max_queued_bytes" size="5"
+ id="max_queued_bytes" size="6"
value="<?=htmlspecialchars($pconfig['max_queued_bytes']);?>">
<?php echo gettext("Minimum is <strong>1024</strong>, Maximum is <strong>1073741824</strong> " .
"( default value is <strong>1048576</strong>, <strong>0</strong> " .
@@ -232,7 +268,7 @@ include_once("head.inc");
<table cellpadding="0" cellspacing="0">
<tr>
<td><input name="max_queued_segs" type="text" class="formfld"
- id="max_queued_segs" size="5"
+ id="max_queued_segs" size="6"
value="<?=htmlspecialchars($pconfig['max_queued_segs']);?>">
<?php echo gettext("Minimum is <strong>2</strong>, Maximum is <strong>1073741824</strong> " .
"( default value is <strong>2621</strong>, <strong>0</strong> means " .
@@ -244,6 +280,22 @@ include_once("head.inc");
</td>
</tr>
<tr>
+ <td valign="top" class="vncell"><?php echo gettext("Memory Cap"); ?></td>
+ <td class="vtable">
+ <table cellpadding="0" cellspacing="0">
+ <tr>
+ <td><input name="stream5_mem_cap" type="text" class="formfld"
+ id="stream5_mem_cap" size="6"
+ value="<?=htmlspecialchars($pconfig['stream5_mem_cap']);?>">
+ <?php echo gettext("Minimum is <strong>32768</strong>, Maximum is <strong>1073741824</strong> " .
+ "( default value is <strong>8388608</strong>) "); ?></td>
+ </tr>
+ </table>
+ <?php echo gettext("The memory cap in bytes for TCP packet storage " .
+ "in RAM. Default value is <strong>8388608</strong> (8 MB)"); ?><br>
+ </td>
+ </tr>
+ <tr>
<td colspan="2" valign="top" class="listtopic"><?php echo gettext("General Preprocessor Settings"); ?></td>
</tr>
<tr>
@@ -266,7 +318,7 @@ include_once("head.inc");
</tr>
<tr>
<td width="22%" valign="top" class="vncell"><?php echo gettext("Enable"); ?> <br>
- <?php echo gettext("SMTP Normalizer"); ?></td>
+ <?php echo gettext("POP Normalizer"); ?></td>
<td width="78%" class="vtable"><input name="pop_preproc"
type="checkbox" value="on"
<?php if ($pconfig['pop_preproc']=="on") echo "checked"; ?>
@@ -275,7 +327,7 @@ include_once("head.inc");
</tr>
<tr>
<td width="22%" valign="top" class="vncell"><?php echo gettext("Enable"); ?> <br>
- <?php echo gettext("SMTP Normalizer"); ?></td>
+ <?php echo gettext("IMAP Normalizer"); ?></td>
<td width="78%" class="vtable"><input name="imap_preproc"
type="checkbox" value="on"
<?php if ($pconfig['imap_preproc']=="on") echo "checked"; ?>
@@ -333,7 +385,30 @@ include_once("head.inc");
<input name="sensitive_data" type="checkbox" value="on"
<?php if ($pconfig['sensitive_data']=="on") echo "checked"; ?>
onClick="enable_change(false)"><br>
- <?php echo gettext("Sensisitive data searches for CC or SS# in data"); ?>
+ <?php echo gettext("Sensitive data searches for credit card or Social Security numbers in data"); ?>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2" valign="top" class="listtopic"><?php echo gettext("SCADA Preprocessor Settings"); ?></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell"><?php echo gettext("Enable"); ?> <br> <?php echo gettext("Modbus Detection"); ?></td>
+ <td width="78%" class="vtable">
+ <input name="modbus_preproc" type="checkbox" value="on"
+ <?php if ($pconfig['modbus_preproc']=="on") echo "checked"; ?>
+ onClick="enable_change(false)"><br>
+ <?php echo gettext("Modbus is a protocol used in SCADA networks. The default port is TCP 502. If your network does " .
+ "not contain Modbus-enabled devices, you should leave this preprocessor disabled."); ?>
+ </td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell"><?php echo gettext("Enable"); ?> <br> <?php echo gettext("DNP3 Detection"); ?></td>
+ <td width="78%" class="vtable">
+ <input name="dnp3_preproc" type="checkbox" value="on"
+ <?php if ($pconfig['dnp3_preproc']=="on") echo "checked"; ?>
+ onClick="enable_change(false)"><br>
+ <?php echo gettext("DNP3 is a protocol used in SCADA networks. The default port is TCP 20000. If your network does " .
+ "not contain DNP3-enabled devices, you should leave this preprocessor disabled."); ?>
</td>
</tr>
<tr>
diff --git a/config/snort/snort_rules.php b/config/snort/snort_rules.php
index c8a38ddb..63c1f851 100644..100755
--- a/config/snort/snort_rules.php
+++ b/config/snort/snort_rules.php
@@ -33,9 +33,10 @@
require_once("guiconfig.inc");
require_once("/usr/local/pkg/snort/snort.inc");
-global $g;
+global $g, $flowbit_rules_file;
$snortdir = SNORTDIR;
+$rules_map = array();
if (!is_array($config['installedpackages']['snortglobal']['rule']))
$config['installedpackages']['snortglobal']['rule'] = array();
@@ -57,13 +58,17 @@ if (isset($id) && $a_rule[$id]) {
$pconfig['customrules'] = base64_decode($a_rule[$id]['customrules']);
}
-function load_rule_file($incoming_file)
-{
- //read file into string, and get filesize
- $contents = @file_get_contents($incoming_file);
-
- //split the contents of the string file into an array using the delimiter
- return explode("\n", $contents);
+function truncate($string, $length) {
+
+ /********************************
+ * This function truncates the *
+ * passed string to the length *
+ * specified adding ellipsis if *
+ * truncation was necessary. *
+ ********************************/
+ if (strlen($string) > $length)
+ $string = substr($string, 0, ($length - 3)) . "...";
+ return $string;
}
/* convert fake interfaces to real */
@@ -80,66 +85,124 @@ else if ($_POST['openruleset'])
else
$currentruleset = $categories[0];
-$ruledir = "{$snortdir}/snort_{$snort_uuid}_{$if_real}/rules";
+if (empty($categories[0]) && ($currentruleset != "custom.rules")) {
+ if (!empty($a_rule[$id]['ips_policy']))
+ $currentruleset = "IPS Policy - " . ucfirst($a_rule[$id]['ips_policy']);
+ else
+ $currentruleset = "custom.rules";
+}
+
+$ruledir = "{$snortdir}/rules";
$rulefile = "{$ruledir}/{$currentruleset}";
if ($currentruleset != 'custom.rules') {
-if (!file_exists($rulefile)) {
- $input_errors[] = "{$currentruleset} seems to be missing!!! Please go to the Category tab and save again the rule to regenerate it.";
- $splitcontents = array();
-} else
- //Load the rule file
- $splitcontents = load_rule_file($rulefile);
+ // Read the current rules file into our rules map array.
+ // Test for the special case of an IPS Policy file.
+ if (substr($currentruleset, 0, 10) == "IPS Policy")
+ $rules_map = snort_load_vrt_policy($a_rule[$id]['ips_policy']);
+ elseif (!file_exists($rulefile))
+ $input_errors[] = "{$currentruleset} seems to be missing!!! Please go to the Category tab and save again the rule to regenerate it.";
+ else
+ $rules_map = snort_load_rules_map($rulefile);
+}
+
+/* Load up our enablesid and disablesid arrays with enabled or disabled SIDs */
+$enablesid = snort_load_sid_mods($a_rule[$id]['rule_sid_on'], "enablesid");
+$disablesid = snort_load_sid_mods($a_rule[$id]['rule_sid_off'], "disablesid");
+
+if ($_GET['act'] == "toggle" && $_GET['ids'] && !empty($rules_map)) {
+
+ // Get the SID tag embedded in the clicked rule icon.
+ $sid= $_GET['ids'];
+
+ // See if the target SID is in our list of modified SIDs,
+ // and toggle it if present; otherwise, add it to the
+ // appropriate list.
+ if (isset($enablesid[$sid])) {
+ unset($enablesid[$sid]);
+ if (!isset($disablesid[$sid]))
+ $disablesid[$sid] = "disablesid";
+ }
+ elseif (isset($disablesid[$sid])) {
+ unset($disablesid[$sid]);
+ if (!isset($enablesid[$sid]))
+ $enablesid[$sid] = "enablesid";
+ }
+ else {
+ if ($rules_map[1][$sid]['disabled'] == 1)
+ $enablesid[$sid] = "enablesid";
+ else
+ $disablesid[$sid] = "disablesid";
+ }
+
+ // Write the updated enablesid and disablesid values to the config file.
+ $tmp = "";
+ foreach ($enablesid as $k => $v) {
+ $tmp .= "||{$v} {$k}";
+ }
+ if (!empty($tmp))
+ $a_rule[$id]['rule_sid_on'] = $tmp;
+ else
+ unset($a_rule[$id]['rule_sid_on']);
+ $tmp = "";
+ foreach ($disablesid as $k => $v) {
+ $tmp .= "||{$v} {$k}";
+ }
+ if (!empty($tmp))
+ $a_rule[$id]['rule_sid_off'] = $tmp;
+ else
+ unset($a_rule[$id]['rule_sid_off']);
+
+ /* Update the config.xml file. */
+ write_config();
+
+ header("Location: /snort/snort_rules.php?id={$id}&openruleset={$currentruleset}");
+ exit;
}
-if ($_GET['act'] == "toggle" && $_GET['ids'] && !empty($splitcontents)) {
-
- $lineid= $_GET['ids'];
-
- //copy rule contents from array into string
- $tempstring = $splitcontents[$lineid];
-
- //explode rule contents into an array, (delimiter is space)
- $rule_content = explode(' ', $tempstring);
-
- $findme = "# alert"; //find string for disabled alerts
- $disabled = strstr($tempstring, $findme);
-
- //if find alert is false, then rule is disabled
- if ($disabled !== false) {
- //rule has been enabled
- $tempstring = substr($tempstring, 2);
- } else
- $tempstring = "# ". $tempstring;
-
- //copy string into array for writing
- $splitcontents[$lineid] = $tempstring;
-
- //write the new .rules file
- @file_put_contents($rulefile, implode("\n", $splitcontents));
-
- //write disable/enable sid to config.xml
- $sid = snort_get_rule_part($tempstring, 'sid:', ";", 0);
- if (is_numeric($sid)) {
- // rule_sid_on registers
- $sidon = explode("||", $a_rule[$id]['rule_sid_on']);
- if (!empty($sidon))
- $sidon = @array_flip($sidon);
- $sidoff = explode("||", $a_rule[$id]['rule_sid_off']);
- if (!empty($sidoff))
- $sidoff = @array_flip($sidoff);
- if ($disabled) {
- unset($sidoff["disablesid {$sid}"]);
- $sidon["enablesid {$sid}"] = count($sidon);
- } else {
- unset($sidon["enablesid {$sid}"]);
- $sidoff["disablesid {$sid}"] = count($sidoff);
+if ($_GET['act'] == "resetcategory" && !empty($rules_map)) {
+
+ // Reset any modified SIDs in the current rule category to their defaults.
+ foreach (array_keys($rules_map) as $k1) {
+ foreach (array_keys($rules_map[$k1]) as $k2) {
+ if (isset($enablesid[$k2]))
+ unset($enablesid[$k2]);
+ if (isset($disablesid[$k2]))
+ unset($disablesid[$k2]);
}
-
- $a_rule[$id]['rule_sid_on'] = implode("||", array_flip($sidon));
- $a_rule[$id]['rule_sid_off'] = implode("||", array_flip($sidoff));
- write_config();
}
+ // Write the updated enablesid and disablesid values to the config file.
+ $tmp = "";
+ foreach ($enablesid as $k => $v) {
+ $tmp .= "||{$v} {$k}";
+ }
+ if (!empty($tmp))
+ $a_rule[$id]['rule_sid_on'] = $tmp;
+ else
+ unset($a_rule[$id]['rule_sid_on']);
+ $tmp = "";
+ foreach ($disablesid as $k => $v) {
+ $tmp .= "||{$v} {$k}";
+ }
+ if (!empty($tmp))
+ $a_rule[$id]['rule_sid_off'] = $tmp;
+ else
+ unset($a_rule[$id]['rule_sid_off']);
+ write_config();
+
+ header("Location: /snort/snort_rules.php?id={$id}&openruleset={$currentruleset}");
+ exit;
+}
+
+if ($_GET['act'] == "resetall" && !empty($rules_map)) {
+
+ // Remove all modified SIDs from config.xml and save the changes.
+ unset($a_rule[$id]['rule_sid_on']);
+ unset($a_rule[$id]['rule_sid_off']);
+
+ /* Update the config.xml file. */
+ write_config();
+
header("Location: /snort/snort_rules.php?id={$id}&openruleset={$currentruleset}");
exit;
}
@@ -233,19 +296,24 @@ function popup(url)
<table class="tabcont" width="100%" border="0" cellpadding="0" cellspacing="0">
<tr>
<td width="3%" class="list">&nbsp;</td>
- <td class="listhdr" colspan="7">
+ <td class="listhdr" colspan="4">
<br/>Category:
<select id="selectbox" name="selectbox" class="formselect" onChange="go()">
<option value='?id=<?=$id;?>&openruleset=custom.rules'>custom.rules</option>
<?php
$files = explode("||", $pconfig['rulesets']);
+ if ($a_rule[$id]['ips_policy_enable'] == 'on')
+ $files[] = "IPS Policy - " . ucfirst($a_rule[$id]['ips_policy']);
+ natcasesort($files);
foreach ($files as $value) {
- if ($snortdownload != 'on' && strstr($value, "snort"))
+ if ($snortdownload != 'on' && substr($value, 0, 6) == "snort_")
+ continue;
+ if ($emergingdownload != 'on' && substr($value, 0, 8) == "emerging")
continue;
- if ($emergingdownload != 'on' && strstr($value, "emerging"))
+ if (empty($value))
continue;
echo "<option value='?id={$id}&openruleset={$value}' ";
- if ($value === $currentruleset)
+ if ($value == $currentruleset)
echo "selected";
echo ">{$value}</option>\n";
}
@@ -253,131 +321,140 @@ function popup(url)
</select>
<br/>
</td>
- <td width="5%" class="list">&nbsp;</td>
+ <td class="listhdr" colspan="3" valign="middle">
+<?php if ($currentruleset != 'custom.rules'): ?>
+ <?php echo "<a href='?id={$id}&openruleset={$currentruleset}&act=resetcategory'>
+ <img src=\"../themes/{$g['theme']}/images/icons/icon_x.gif\"
+ onmouseout='this.src=\"../themes/{$g['theme']}/images/icons/icon_x.gif\"'
+ onmouseover='this.src=\"../themes/{$g['theme']}/images/icons/icon_x_mo.gif\"' border='0'
+ title='" . gettext("Click to remove enable/disable changes for rules in the selected category only") . "'></a>"?>
+ &nbsp;<?php echo gettext("Remove Enable/Disable changes in the current Category");?><br>
+ <?php echo "<a href='?id={$id}&openruleset={$currentruleset}&act=resetall'>
+ <img src=\"../themes/{$g['theme']}/images/icons/icon_x.gif\"
+ onmouseout='this.src=\"../themes/{$g['theme']}/images/icons/icon_x.gif\"'
+ onmouseover='this.src=\"../themes/{$g['theme']}/images/icons/icon_x_mo.gif\"' border='0'
+ title='" . gettext("Click to remove all enable/disable changes for rules in all categories") . "'></a>"?>
+ &nbsp;<?php echo gettext("Remove all Enable/Disable changes in all Categories");?>
+<?php endif;?>
+ &nbsp;</td>
+ <td width="3%" class="list">&nbsp;</td>
</tr>
-<?php if ($currentruleset == 'custom.rules' || empty($pconfig['rulesets'])): ?>
+<?php if ($currentruleset == 'custom.rules'): ?>
<tr>
<td width="3%" class="list">&nbsp;</td>
- <td valign="top" class="vtable">
+ <td colspan="7" valign="top" class="vtable">
<input type='hidden' name='openruleset' value='custom.rules'>
<input type='hidden' name='id' value='<?=$id;?>'>
- <textarea wrap="on" cols="90" rows="50" name="customrules"><?=$pconfig['customrules'];?></textarea>
+ <textarea wrap="on" cols="85" rows="40" name="customrules"><?=$pconfig['customrules'];?></textarea>
</td>
+ <td width="3%" class="list">&nbsp;</td>
</tr>
<tr>
<td width="3%" class="list">&nbsp;</td>
- <td class="vtable">
+ <td colspan="7" class="vtable">
<input name="Submit" type="submit" class="formbtn" value="Save">
<input type="button" class="formbtn" value="Cancel" onclick="history.back()">
</td>
+ <td width="3%" class="list">&nbsp;</td>
</tr>
<?php else: ?>
<tr>
<td width="3%" class="list">&nbsp;</td>
<td colspan="7" class="listhdr" >&nbsp;</td>
- <td width="5%" class="list">&nbsp;</td>
+ <td width="3%" align="center" valign="middle" class="list"><a href="javascript: void(0)"
+ onclick="popup('snort_rules_edit.php?id=<?=$id;?>&openruleset=<?=$currentruleset;?>')">
+ <img src="../themes/<?= $g['theme']; ?>/images/icons/icon_service_restart.gif" <?php
+ echo "onmouseover='this.src=\"../themes/{$g['theme']}/images/icons/icon_services_restart_mo.gif\"'
+ onmouseout='this.src=\"../themes/{$g['theme']}/images/icons/icon_service_restart.gif\"' ";?>
+ title="<?php echo gettext("Click to view all rules"); ?>" width="17" height="17" border="0"></a></td>
</tr>
<tr id="frheader">
<td width="3%" class="list">&nbsp;</td>
- <td width="7%" class="listhdr"><?php echo gettext("SID"); ?></td>
- <td width="4%" class="listhdrr"><?php echo gettext("Proto"); ?></td>
- <td width="15%" class="listhdrr"><?php echo gettext("Source"); ?></td>
- <td width="10%" class="listhdrr"><?php echo gettext("Port"); ?></td>
- <td width="15%" class="listhdrr"><?php echo gettext("Destination"); ?></td>
- <td width="10%" class="listhdrr"><?php echo gettext("Port"); ?></td>
- <td width="30%" class="listhdrr"><?php echo gettext("Message"); ?></td>
- <td width="5%" class="list">&nbsp;</td>
+ <td width="9%" class="listhdr"><?php echo gettext("SID"); ?></td>
+ <td width="2%" class="listhdrr"><?php echo gettext("Proto"); ?></td>
+ <td width="14%" class="listhdrr"><?php echo gettext("Source"); ?></td>
+ <td width="12%" class="listhdrr"><?php echo gettext("Port"); ?></td>
+ <td width="14%" class="listhdrr"><?php echo gettext("Destination"); ?></td>
+ <td width="12%" class="listhdrr"><?php echo gettext("Port"); ?></td>
+ <td width="31%" class="listhdrr"><?php echo gettext("Message"); ?></td>
+ <td width="3%" class="list">&nbsp;</td>
</tr>
<?php
- foreach ( $splitcontents as $counter => $value )
- {
- $disabled = "False";
- $comments = "False";
- $findme = "# alert"; //find string for disabled alerts
- $disabled_pos = strstr($value, $findme);
-
- $counter2 = 1;
- $sid = snort_get_rule_part($value, 'sid:', ';', 0);
- //check to see if the sid is numberical
- if (!is_numeric($sid))
- continue;
-
- //if find alert is false, then rule is disabled
- if ($disabled_pos !== false){
- $counter2 = $counter2+1;
- $textss = "<span class=\"gray\">";
- $textse = "</span>";
- $iconb = "icon_block_d.gif";
-
- $ischecked = "";
- } else {
- $textss = $textse = "";
- $iconb = "icon_block.gif";
-
- $ischecked = "checked";
- }
+ foreach (array_keys($rules_map) as $k1) {
+ foreach (array_keys($rules_map[$k1]) as $k2) {
+ $sid = snort_get_sid($rules_map[$k1][$k2]['rule']);
+ if (isset($disablesid[$sid])) {
+ $textss = "<span class=\"gray\">";
+ $textse = "</span>";
+ $iconb = "icon_reject_d.gif";
+ }
+ elseif (($rules_map[$k1][$k2]['disabled'] == 1) && (!isset($enablesid[$sid]))) {
+ $textss = "<span class=\"gray\">";
+ $textse = "</span>";
+ $iconb = "icon_block_d.gif";
+ }
+ elseif (isset($enablesid[$sid])) {
+ $textss = $textse = "";
+ $iconb = "icon_reject.gif";
+ }
+ else {
+ $textss = $textse = "";
+ $iconb = "icon_block.gif";
+ }
- $rule_content = explode(' ', $value);
-
- $protocol = $rule_content[$counter2];//protocol location
- $counter2++;
- $source = substr($rule_content[$counter2], 0, 20) . "...";//source location
- $counter2++;
- $source_port = $rule_content[$counter2];//source port location
- $counter2 = $counter2+2;
- $destination = substr($rule_content[$counter2], 0, 20) . "...";//destination location
- $counter2++;
- $destination_port = $rule_content[$counter2];//destination port location
-
- if (strstr($value, 'msg: "'))
- $message = snort_get_rule_part($value, 'msg: "', '";', 0);
- else if (strstr($value, 'msg:"'))
- $message = snort_get_rule_part($value, 'msg:"', '";', 0);
-
- echo "<tr><td width='3%' class='listt'> $textss
- <a href='?id={$id}&openruleset={$currentruleset}&act=toggle&ids={$counter}'>
- <img src='../themes/{$g['theme']}/images/icons/{$iconb}'
- width='10' height='10' border='0'
- title='" . gettext("click to toggle enabled/disabled status") . "'></a>
- $textse
- </td>
- <td width='7%' class=\"listlr\">
+ // Pick off the first section of the rule (prior to the start of the MSG field),
+ // and then use a REGX split to isolate the remaining fields into an array.
+ $tmp = substr($rules_map[$k1][$k2]['rule'], 0, strpos($rules_map[$k1][$k2]['rule'], "("));
+ $tmp = trim(preg_replace('/^\s*#+\s*/', '', $tmp));
+ $rule_content = preg_split('/[\s]+/', $tmp);
+
+ $protocol = truncate($rule_content[1], 5); //protocol location
+ $source = truncate($rule_content[2], 13); //source location
+ $source_port = truncate($rule_content[3], 11); //source port location
+ $destination = truncate($rule_content[5], 13); //destination location
+ $destination_port = truncate($rule_content[6], 11); //destination port location
+ $message = snort_get_msg($rules_map[$k1][$k2]['rule']);
+
+ echo "<tr><td width=\"3%\" class=\"listt\" align=\"center\" valign=\"middle\"> $textss
+ <a href='?id={$id}&openruleset={$currentruleset}&act=toggle&ids={$sid}'>
+ <img src=\"../themes/{$g['theme']}/images/icons/{$iconb}\"
+ width=\"10\" height=\"10\" border=\"0\"
+ title='" . gettext("Click to toggle enabled/disabled state") . "'></a>
+ $textse
+ </td>
+ <td width=\"9%\" class=\"listlr\">
$textss $sid $textse
</td>
- <td width='4%' class=\"listlr\">
+ <td width=\"2%\" class=\"listlr\">
$textss $protocol $textse
</td>
- <td width='15%' class=\"listlr\">
+ <td width=\"14%\" class=\"listlr\">
$textss $source $textse
</td>
- <td width='10%' class=\"listlr\">
+ <td width=\"12%\" class=\"listlr\">
$textss $source_port $textse
</td>
- <td width='15%' class=\"listlr\">
+ <td width=\"14%\" class=\"listlr\">
$textss $destination $textse
</td>
- <td width='10%' class=\"listlr\">
+ <td width=\"12%\" class=\"listlr\">
$textss $destination_port $textse
</td>
- <td width='30%' class=\"listbg\"><font color=\"white\">
+ <td width=\"31%\" class=\"listbg\" style=\"word-break:break-all;\"><font color=\"white\">
$textss $message $textse
</td>";
?>
- <td width='5%' valign="middle" nowrap class="list">
- <table border="0" cellspacing="0" cellpadding="1">
- <tr>
- <td><a href="javascript: void(0)"
- onclick="popup('snort_rules_edit.php?id=<?=$id;?>&openruleset=<?=$currentruleset;?>')"><img
- src="../themes/<?= $g['theme']; ?>/images/icons/icon_right.gif"
- title="<?php echo gettext("edit rule"); ?>" width="17" height="17" border="0"></a></td>
- <!-- Codes by Quackit.com -->
- </tr>
- </table>
+ <td width="3%" align="center" valign="middle" nowrap class="list">
+ <a href="javascript: void(0)"
+ onclick="popup('snort_rules_edit.php?id=<?=$id;?>&openruleset=<?=$currentruleset;?>&ids=<?=$sid;?>')"><img
+ src="../themes/<?= $g['theme']; ?>/images/icons/icon_right.gif"
+ title="<?php echo gettext("Click to view rule"); ?>" width="17" height="17" border="0"></a>
+ <!-- Codes by Quackit.com -->
</td>
</tr>
<?php
-
+ }
}
?>
@@ -387,25 +464,34 @@ function popup(url)
<?php endif;?>
<tr>
<td colspan="9">
- <table class="tabcont" width="100%" border="0" cellspacing="0" cellpadding="0">
+<?php if ($currentruleset != 'custom.rules'): ?>
+ <table class="tabcont" width="100%" border="0" cellspacing="0" cellpadding="1">
<tr>
<td width="16"><img
src="../themes/<?= $g['theme']; ?>/images/icons/icon_block.gif"
width="11" height="11"></td>
- <td><?php echo gettext("Rule Enabled"); ?></td>
+ <td><?php echo gettext("Rule default is Enabled"); ?></td>
</tr>
<tr>
<td><img
src="../themes/<?= $g['theme']; ?>/images/icons/icon_block_d.gif"
width="11" height="11"></td>
- <td nowrap><?php echo gettext("Rule Disabled"); ?></td>
+ <td nowrap><?php echo gettext("Rule default is Disabled"); ?></td>
</tr>
<tr>
- <td colspan="10">
- <p><!--<strong><span class="red">Warning:<br/> </span></strong>Editing these r</p>-->
- </td>
+ <td><img
+ src="../themes/<?= $g['theme']; ?>/images/icons/icon_reject.gif"
+ width="11" height="11"></td>
+ <td nowrap><?php echo gettext("Rule changed to Enabled by user"); ?></td>
+ </tr>
+ <tr>
+ <td><img
+ src="../themes/<?= $g['theme']; ?>/images/icons/icon_reject_d.gif"
+ width="11" height="11"></td>
+ <td nowrap><?php echo gettext("Rule changed to Disabled by user"); ?></td>
</tr>
</table>
+<?php endif;?>
</td>
</tr>
</table>
diff --git a/config/snort/snort_rules_edit.php b/config/snort/snort_rules_edit.php
index 809832ea..c123c032 100644..100755
--- a/config/snort/snort_rules_edit.php
+++ b/config/snort/snort_rules_edit.php
@@ -37,6 +37,7 @@
require_once("guiconfig.inc");
require_once("/usr/local/pkg/snort/snort.inc");
+global $flowbit_rules_file;
$snortdir = SNORTDIR;
if (!is_array($config['installedpackages']['snortglobal']['rule'])) {
@@ -60,20 +61,39 @@ if (isset($id) && $a_rule[$id]) {
$if_real = snort_get_real_interface($pconfig['interface']);
$snort_uuid = $a_rule[$id]['uuid'];
$file = $_GET['openruleset'];
-
-//read file into string, and get filesize also chk for empty files
$contents = '';
-if (file_exists("{$snortdir}/snort_{$snort_uuid}_{$if_real}/rules/{$file}"))
- $contents = file_get_contents("{$snortdir}/snort_{$snort_uuid}_{$if_real}/rules/{$file}");
-else {
+
+// Read the current rules file.
+// Test for the special case of an IPS Policy file.
+if (substr($file, 0, 10) == "IPS Policy") {
+ $rules_map = snort_load_vrt_policy($a_rule[$id]['ips_policy']);
+ if (isset($_GET['ids']))
+ $contents = $rules_map[1][trim($_GET['ids'])]['rule'];
+ else {
+ $contents = "# Snort IPS Policy - " . ucfirst($a_rule[$id]['ips_policy']) . "\n\n";
+ foreach (array_keys($rules_map) as $k1) {
+ foreach (array_keys($rules_map[$k1]) as $k2) {
+ $contents .= "# Category: " . $rules_map[$k1][$k2]['category'] . " SID: {$k2}\n";
+ $contents .= $rules_map[$k1][$k2]['rule'] . "\n";
+ }
+ }
+ }
+ unset($rules_map);
+}
+elseif (isset($_GET['ids'])) {
+ $rules_map = snort_load_rules_map("{$snortdir}/rules/{$file}");
+ $contents = $rules_map[1][trim($_GET['ids'])]['rule'];
+}
+elseif ($file == $flowbit_rules_file)
+ $contents = file_get_contents("{$snortdir}/snort_{$snort_uuid}_{$if_real}/rules/{$flowbit_rules_file}");
+elseif (!file_exists("{$snortdir}/rules/{$file}")) {
header("Location: /snort/snort_rules.php?id={$id}&openruleset={$file}");
exit;
}
+else
+ $contents = file_get_contents("{$snortdir}/rules/{$file}");
-//split the contents of the string file into an array using the delimiter
-$splitcontents = explode("\n", $contents);
-
-$pgtitle = array(gettext("Advanced"), gettext("File Editor"));
+$pgtitle = array(gettext("Advanced"), gettext("File Viewer"));
?>
@@ -90,7 +110,7 @@ $pgtitle = array(gettext("Advanced"), gettext("File Editor"));
<table width="100%" cellpadding="0" cellspacing="6" bgcolor="#eeeeee">
<tr>
<td>
- <input type="button" class="formbtn" value="Cancel" onclick="window.close()">
+ <input type="button" class="formbtn" value="Return" onclick="window.close()">
</td>
</tr>
<tr>
diff --git a/config/snort/snort_rulesets.php b/config/snort/snort_rulesets.php
index cfaa7d18..b9aa2647 100644..100755
--- a/config/snort/snort_rulesets.php
+++ b/config/snort/snort_rulesets.php
@@ -32,7 +32,7 @@
require_once("guiconfig.inc");
require_once("/usr/local/pkg/snort/snort.inc");
-global $g;
+global $g, $flowbit_rules_file;
$snortdir = SNORTDIR;
@@ -49,44 +49,13 @@ if (is_null($id)) {
exit;
}
-function snort_remove_rules($files, $snortdir, $snort_uuid, $if_real) {
-
- if (empty($files))
- return;
-
- conf_mount_rw();
- foreach ($files as $file) {
- @unlink("{$snortdir}/snort_{$snort_uuid}_{$if_real}/rules/{$file}");
- if (substr($file, -9) == ".so.rules") {
- $slib = substr($file, 6, -6);
- @unlink("{$snortdir}/snort_{$snort_uuid}_{$if_real}/dynamicrules/{$slib}");
- }
- }
- conf_mount_ro();
-}
-
-function snort_copy_rules($files, $snortdir, $snort_uuid, $if_real) {
-
- if (empty($files))
- return;
-
- conf_mount_rw();
- foreach ($files as $file) {
- if (!file_exists("{$snortdir}/snort_{$snort_uuid}_{$if_real}/rules/{$file}"))
- @copy("{$snortdir}/rules/{$file}", "{$snortdir}/snort_{$snort_uuid}_{$if_real}/rules/{$file}");
- if (substr($file, -9) == ".so.rules") {
- $slib = substr($enabled_item, 6, -6);
- if (!file_exists("{$snortdir}/snort_{$snort_uuid}_{$if_real}/dynamicrules/{$slib}"))
- @copy("/usr/local/lib/snort/dynamicrules/{$file}", "{$snortdir}/snort_{$snort_uuid}_{$if_real}/dynamicrules/{$slib}");
- }
- }
- conf_mount_ro();
-}
-
if (isset($id) && $a_nat[$id]) {
$pconfig['enable'] = $a_nat[$id]['enable'];
$pconfig['interface'] = $a_nat[$id]['interface'];
$pconfig['rulesets'] = $a_nat[$id]['rulesets'];
+ $pconfig['autoflowbitrules'] = $a_nat[$id]['autoflowbitrules'];
+ $pconfig['ips_policy_enable'] = $a_nat[$id]['ips_policy_enable'];
+ $pconfig['ips_policy'] = $a_nat[$id]['ips_policy'];
}
$if_real = snort_get_real_interface($pconfig['interface']);
@@ -94,20 +63,60 @@ $snort_uuid = $a_nat[$id]['uuid'];
$snortdownload = $config['installedpackages']['snortglobal']['snortdownload'];
$emergingdownload = $config['installedpackages']['snortglobal']['emergingthreats'];
+if (($snortdownload == 'off') || ($a_nat[$id]['ips_policy_enable'] != 'on'))
+ $policy_select_disable = "disabled";
+
+if ($a_nat[$id]['autoflowbitrules'] == 'on') {
+ if (file_exists("{$snortdir}/snort_{$snort_uuid}_{$if_real}/rules/{$flowbit_rules_file}"))
+ $btn_view_flowb_rules = "";
+ else
+ $btn_view_flowb_rules = " disabled";
+}
+else
+ $btn_view_flowb_rules = " disabled";
+
+// If a Snort VRT policy is enabled and selected, remove all Snort VRT
+// rules from the configured rule sets to allow automatic selection.
+if ($a_nat[$id]['ips_policy_enable'] == 'on') {
+ if (isset($a_nat[$id]['ips_policy'])) {
+ $disable_vrt_rules = "disabled";
+ $enabled_sets = explode("||", $a_nat[$id]['rulesets']);
+
+ foreach ($enabled_sets as $k => $v) {
+ if (substr($v, 0, 6) == "snort_")
+ unset($enabled_sets[$k]);
+ }
+ $a_nat[$id]['rulesets'] = implode("||", $enabled_sets);
+ }
+}
+else
+ $disable_vrt_rules = "";
+
/* alert file */
if ($_POST["Submit"]) {
+
+ if ($_POST['ips_policy_enable'] == "on")
+ $a_nat[$id]['ips_policy_enable'] = 'on';
+ else
+ $a_nat[$id]['ips_policy_enable'] = 'off';
+
+ $a_nat[$id]['ips_policy'] = $_POST['ips_policy'];
+
$enabled_items = "";
if (is_array($_POST['toenable']))
$enabled_items = implode("||", $_POST['toenable']);
else
$enabled_items = $_POST['toenable'];
- $oenabled = explode("||", $a_nat[$id]['rulesets']);
- $nenabled = explode("||", $enabled_items);
- $tormv = array_diff($oenabled, $nenabled);
- snort_remove_rules($tormv, $snortdir, $snort_uuid, $if_real);
$a_nat[$id]['rulesets'] = $enabled_items;
- snort_copy_rules(explode("||", $enabled_items), $snortdir, $snort_uuid, $if_real);
+
+ if ($_POST['autoflowbits'] == "on")
+ $a_nat[$id]['autoflowbitrules'] = 'on';
+ else {
+ $a_nat[$id]['autoflowbitrules'] = 'off';
+ if (file_exists("{$snortdir}/snort_{$snort_uuid}_{$if_real}/rules/{$flowbit_rules_file}"))
+ @unlink("{$snortdir}/snort_{$snort_uuid}_{$if_real}/rules/{$flowbit_rules_file}");
+ }
write_config();
sync_snort_package_config();
@@ -117,9 +126,6 @@ if ($_POST["Submit"]) {
}
if ($_POST['unselectall']) {
- if (!empty($pconfig['rulesets']))
- snort_remove_rules(explode("||", $pconfig['rulesets']), $snortdir, $snort_uuid, $if_real);
-
$a_nat[$id]['rulesets'] = "";
write_config();
@@ -141,7 +147,6 @@ if ($_POST['selectall']) {
foreach ($files as $file)
$rulesets[] = basename($file);
}
- snort_copy_rules($rulesets, $snortdir, $snort_uuid, $if_real);
$a_nat[$id]['rulesets'] = implode("||", $rulesets);
@@ -177,6 +182,33 @@ if ($savemsg) {
?>
+<script language="javascript" type="text/javascript">
+function popup(url)
+{
+ params = 'width='+screen.width;
+ params += ', height='+screen.height;
+ params += ', top=0, left=0'
+ params += ', fullscreen=yes';
+
+ newwin=window.open(url,'windowname4', params);
+ if (window.focus) {newwin.focus()}
+ return false;
+}
+function enable_change()
+{
+ var endis = !(document.iform.ips_policy_enable.checked);
+ document.iform.ips_policy.disabled=endis;
+
+ for (var i = 0; i < document.iform.elements.length; i++) {
+ if (document.iform.elements[i].type == 'checkbox') {
+ var str = document.iform.elements[i].value;
+ if (str.substr(0,6) == "snort_")
+ document.iform.elements[i].disabled = !(endis);
+ }
+ }
+}
+</script>
+
<form action="snort_rulesets.php" method="post" name="iform" id="iform">
<input type="hidden" name="id" id="id" value="<?=$id;?>" />
<table width="99%" border="0" cellpadding="0" cellspacing="0">
@@ -205,7 +237,7 @@ if ($savemsg) {
<tr>
<td>
<?php printf(gettext("# The rules directory is empty. %s/rules"), $snortdir); ?> <br/>
- <?php echo gettext("Please go to the updates page to download/fetch the rules configured."); ?>
+ <?php echo gettext("Please go to the Updates tab to download/fetch the rules configured."); ?>
</td>
</tr>
<?php else:
@@ -221,18 +253,90 @@ if ($savemsg) {
<table id="sortabletable1" class="sortable" width="100%" border="0"
cellpadding="0" cellspacing="0">
<tr>
- <td colspan="6" class="listtopic"><?php echo gettext("Check the rulesets that you would like Snort to load at startup."); ?><br/><br/></td>
+ <td colspan="6" class="listtopic"><?php echo gettext("Automatic flowbit resolution"); ?><br/></td>
+ </tr>
+ <tr>
+ <td colspan="6" valign="center" class="listn">
+ <table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr>
+ <td width="15%" class="listn"><?php echo gettext("Resolve Flowbits"); ?></td>
+ <td width="85%"><input name="autoflowbits" id="autoflowbitrules" type="checkbox" value="on" <?php if ($a_nat[$id]['autoflowbitrules'] == "on") echo "checked"; ?>/></td>
+ </tr>
+ <tr>
+ <td width="15%" class="vncell">&nbsp;</td>
+ <td width="85%" class="vtable">
+ <?php echo gettext("If ticked, Snort will examine the enabled rules in your chosen " .
+ "rule categories for checked flowbits. Any rules that set these dependent flowbits will " .
+ "be automatically enabled and added to the list of files in the interface rules directory."); ?><br/><br/></td>
+ </tr>
+ <tr>
+ <td width="15%" class="listn"><?php echo gettext("Auto Flowbit Rules"); ?></td>
+ <td width="85%"><input type="button" class="formbtn" value="View" onclick="popup('snort_rules_edit.php?id=<?=$id;?>&openruleset=<?=$flowbit_rules_file;?>')" <?php echo $btn_view_flowb_rules; ?>/></td>
+ </tr>
+ <tr>
+ <td width="15%">&nbsp;</td>
+ <td width="85%">
+ <?php echo gettext("Click to view auto-enabled rules required to satisfy flowbit " .
+ "dependencies from the selected rule categories below. Auto-enabled rules generating unwanted alerts " .
+ "should have their GID:SID added to the Suppression List for the interface."); ?><br/><br/></td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="6" class="listtopic"><?php echo gettext("Snort IPS Policy Selection"); ?><br/></td>
+ </tr>
+ <tr>
+ <td colspan="6" valign="center" class="listn">
+ <table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr>
+ <td width="15%" class="listn"><?php echo gettext("Use IPS Policy"); ?></td>
+ <td width="85%"><input name="ips_policy_enable" id="ips_policy_enable" type="checkbox" value="on" <?php if ($a_nat[$id]['ips_policy_enable'] == "on") echo "checked"; ?>
+ <?php if ($snortdownload == "off") echo "disabled" ?> onClick="enable_change()"/></td>
+ </tr>
+ <tr>
+ <td width="15%" class="vncell">&nbsp;</td>
+ <td width="85%" class="vtable">
+ <?php echo gettext("If ticked, Snort will use rules from the pre-defined IPS policy " .
+ "selected below. You must be using the Snort VRT rules to use this option."); ?><br/>
+ <?php echo gettext("Selecting this option disables manual selection of Snort VRT categories in the list below, " .
+ "although Emerging Threats categories may still be selected if enabled on the Global Settings tab. " .
+ "These will be added to the pre-defined Snort IPS policy rules from the Snort VRT."); ?><br><br/></td>
+ </tr>
+ <tr>
+ <td width="15%" class="listn"><?php echo gettext("IPS Policy"); ?></td>
+ <td width="85%"><select name="ips_policy" class="formselect" <?=$policy_select_disable?> >
+ <option value="connectivity" <?php if ($pconfig['ips_policy'] == "connected") echo "selected"; ?>><?php echo gettext("Connectivity"); ?></option>
+ <option value="balanced" <?php if ($pconfig['ips_policy'] == "balanced") echo "selected"; ?>><?php echo gettext("Balanced"); ?></option>
+ <option value="security" <?php if ($pconfig['ips_policy'] == "security") echo "selected"; ?>><?php echo gettext("Security"); ?></option>
+ </select>
+ </td>
+ </tr>
+ <tr>
+ <td width="15%">&nbsp;</td>
+ <td width="85%">
+ <?php echo gettext("Snort IPS policies are: Connectivity, Balanced or Security. " .
+ "Connectivity blocks most major threats with few or no false positives. Balanced is a good starter policy. It " .
+ "is speedy, has good base coverage level, and covers most threats of the day. It includes all rules in Connectivity. " .
+ "Security is a stringent policy. It contains everything in the first two plus policy-type rules such as Flash in an Excel file."); ?><br/><br/></td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="6" class="listtopic"><?php echo gettext("Check the rulesets that you would like Snort to load at startup."); ?><br/></td>
</tr>
<tr>
- <td colspan="2" valign="center"><br/><input value="Save" type="submit" name="Submit" id="Submit" /><br/<br/></td>
- <td colspan="2" valign="center"><br/><input value="Select All" type="submit" name="selectall" id="selectall" /><br/<br/></td>
- <td colspan="2" valign="center"><br/><input value="Unselect All" type="submit" name="unselectall" id="selectall" /><br/<br/></td>
+ <td colspan="1" align="middle" valign="center"><br/><input value="Select All" type="submit" name="selectall" id="selectall" /><br/></td>
+ <td colspan="1" align="middle" valign="center"><br/><input value="Unselect All" type="submit" name="unselectall" id="selectall" /><br/></td>
+ <td colspan="1" align="middle" valign="center"><br/><input value="Save" class="formbtn" type="submit" name="Submit" id="Submit" /></td>
+ <td colspan="3" valign="center"><?php echo gettext("Click to save changes and auto-resolve flowbit rules (if option is selected above)"); ?><br/></td>
</tr>
<tr> <td colspan="6">&nbsp;</td> </tr>
<tr id="frheader">
<?php if ($emergingdownload == 'on'): ?>
<td width="5%" class="listhdrr"><?php echo gettext("Enabled"); ?></td>
- <td width="25%" class="listhdrr"><?php echo gettext('Ruleset: Emerging Threats.');?></td>
+ <td width="25%" class="listhdrr"><?php echo gettext('Ruleset: Emerging Threats');?></td>
<?php else: ?>
<td colspan="2" width="30%" class="listhdrr"><?php echo gettext("Emerging rules have not been enabled"); ?></td>
<?php endif; ?>
@@ -302,7 +406,9 @@ if ($savemsg) {
$file = $snortrules[$j];
echo "<td class='listr' width='5%' align=\"center\" valign=\"top\">";
if(is_array($enabled_rulesets_array)) {
- if(in_array($file, $enabled_rulesets_array))
+ if (!empty($disable_vrt_rules))
+ $CHECKED = $disable_vrt_rules;
+ elseif(in_array($file, $enabled_rulesets_array))
$CHECKED = " checked=\"checked\"";
else
$CHECKED = "";
@@ -311,7 +417,7 @@ if ($savemsg) {
echo " \n<input type='checkbox' name='toenable[]' value='{$file}' {$CHECKED} />\n";
echo "</td>\n";
echo "<td class='listr' width='25%' >\n";
- if (empty($CHECKED))
+ if (empty($CHECKED) || $CHECKED == "disabled")
echo $file;
else
echo "<a href='snort_rules.php?id={$id}&openruleset=" . urlencode($file) . "'>{$file}</a>\n";
@@ -322,7 +428,9 @@ if ($savemsg) {
$file = $snortsorules[$j];
echo "<td class='listr' width='5%' align=\"center\" valign=\"top\">";
if(is_array($enabled_rulesets_array)) {
- if(in_array($file, $enabled_rulesets_array))
+ if (!empty($disable_vrt_rules))
+ $CHECKED = $disable_vrt_rules;
+ elseif(in_array($file, $enabled_rulesets_array))
$CHECKED = " checked=\"checked\"";
else
$CHECKED = "";
@@ -342,8 +450,12 @@ if ($savemsg) {
</td>
</tr>
<tr>
-<td colspan="6">&nbsp;</td>
+<td colspan="6" class="vtable">&nbsp;<br/></td>
</tr>
+ <tr>
+ <td colspan="2" align="middle" valign="center"><br/><input value="Save" type="submit" name="Submit" id="Submit" class="formbtn" /></td>
+ <td colspan="4" valign="center">&nbsp;<br><br/></td>
+ </tr>
<?php endif; ?>
</table>
</div>