diff options
-rwxr-xr-x[-rw-r--r--] | config/snort/snort.inc | 884 | ||||
-rwxr-xr-x[-rw-r--r--] | config/snort/snort.xml | 2 | ||||
-rwxr-xr-x[-rw-r--r--] | config/snort/snort_alerts.php | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | config/snort/snort_check_for_rule_updates.php | 308 | ||||
-rwxr-xr-x[-rw-r--r--] | config/snort/snort_define_servers.php | 6 | ||||
-rwxr-xr-x[-rw-r--r--] | config/snort/snort_download_rules.php | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | config/snort/snort_download_updates.php | 22 | ||||
-rwxr-xr-x[-rw-r--r--] | config/snort/snort_interfaces.php | 12 | ||||
-rwxr-xr-x[-rw-r--r--] | config/snort/snort_interfaces_edit.php | 131 | ||||
-rwxr-xr-x[-rw-r--r--] | config/snort/snort_preprocessors.php | 101 | ||||
-rwxr-xr-x[-rw-r--r--] | config/snort/snort_rules.php | 394 | ||||
-rwxr-xr-x[-rw-r--r--] | config/snort/snort_rules_edit.php | 40 | ||||
-rwxr-xr-x[-rw-r--r--] | config/snort/snort_rulesets.php | 220 |
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") . " </span></button>\n"; + <button href='/snort/snort_rules_edit.php?openruleset={$snort_upd_log}'><span class='pwhitetxt'>" . gettext("Update Log") . " </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") . " </span></button>\n"; + <button disabled='disabled' href='/snort/snort_rules_edit.php?openruleset={$snort_upd_log}'><span class='pwhitetxt'>" . gettext("Update Log") . " </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> Click</strong> + interface and settings.<strong> 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/> <?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/> <br/><span class="red"><?php echo gettext("Note:"); ?></span><br/> <?php echo gettext("Default " . + "will like this interface to use."); ?> </span><br/> <br/><span class="red"><?php echo gettext("Note:"); ?></span><br/> <?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"> </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"> </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"> </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>"?> + <?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>"?> + <?php echo gettext("Remove all Enable/Disable changes in all Categories");?> +<?php endif;?> + </td> + <td width="3%" class="list"> </td> </tr> -<?php if ($currentruleset == 'custom.rules' || empty($pconfig['rulesets'])): ?> +<?php if ($currentruleset == 'custom.rules'): ?> <tr> <td width="3%" class="list"> </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"> </td> </tr> <tr> <td width="3%" class="list"> </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"> </td> </tr> <?php else: ?> <tr> <td width="3%" class="list"> </td> <td colspan="7" class="listhdr" > </td> - <td width="5%" class="list"> </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"> </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"> </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"> </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"> </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%"> </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"> </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%"> </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"> </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"> </td> +<td colspan="6" class="vtable"> <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"> <br><br/></td> + </tr> <?php endif; ?> </table> </div> |