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(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 update_status(gettext("Done downloading snort.org md5")); } /* Check if were up to date snort.org */ if ($snortdownload == 'on') { if (file_exists("{$snortdir}/{$snort_filename_md5}")) { $md5_check_new = file_get_contents("{$tmpfname}/{$snort_filename_md5}"); $md5_check_old = file_get_contents("{$snortdir}/{$snort_filename_md5}"); if ($md5_check_new == $md5_check_old) { update_status(gettext("Snort rules are up to date...")); log_error("Snort rules are up to date..."); $snortdownload = 'off'; } } } /* download snortrules file */ if ($snortdownload == 'on') { update_status(gettext("There is a new set of Snort.org rules posted. Downloading...")); 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 download failed...")); log_error(gettext("Snort rules file download failed...")); log_error("Failed Rules Filesize: " . filesize("{$tmpfname}/$snort_filename")); $snortdownload = 'off'; } } /* 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"); /* XXX: error checking */ @file_put_contents("{$tmpfname}/{$emergingthreats_filename_md5}", $image); update_status(gettext("Done downloading emergingthreats md5")); if (file_exists("{$snortdir}/{$emergingthreats_filename_md5}")) { /* Check if were up to date emergingthreats.net */ $emerg_md5_check_new = file_get_contents("{$tmpfname}/{$emergingthreats_filename_md5}"); $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(gettext("Emerging threat rules are up to date...")); $emergingthreats = 'off'; } } } /* download emergingthreats rules file */ if ($emergingthreats == "on") { update_status(gettext("There is a new set of Emergingthreats rules posted. Downloading...")); log_error(gettext("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}"); update_status(gettext('Done downloading Emergingthreats rules file.')); log_error("Emergingthreats rules file update downloaded succsesfully"); } /* Normalize rulesets */ $sedcmd = "s/^#alert/# alert/g\n"; $sedcmd .= "s/^##alert/# alert/g\n"; $sedcmd .= "s/^#[ \\t#]*alert/# alert/g\n"; $sedcmd .= "s/^##\\talert/# alert/g\n"; $sedcmd .= "s/^\\talert/alert/g\n"; $sedcmd .= "s/^[ \\t]*alert/alert/g\n"; @file_put_contents("{$snortdir}/tmp/sedcmd", $sedcmd); /* Untar emergingthreats rules to tmp */ if ($emergingthreats == 'on') { safe_mkdir("{$snortdir}/tmp/emerging"); if (file_exists("{$tmpfname}/{$emergingthreats_filename}")) { 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"); foreach ($files as $file) { $newfile = basename($file); @copy($file, "{$snortdir}/rules/{$newfile}"); } /* 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}"); } /* 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 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...")); } } /* Untar snort rules file individually to help people with low system specs */ if ($snortdownload == 'on') { if (file_exists("{$tmpfname}/{$snort_filename}")) { if ($pfsense_stable == 'yes') $freebsd_version_so = 'FreeBSD-7-2'; else $freebsd_version_so = 'FreeBSD-8-1'; 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/"); $files = glob("{$snortdir}/tmp/snortrules/rules/*.rules"); foreach ($files as $file) { $newfile = basename($file); @copy($file, "{$snortdir}/rules/snort_{$newfile}"); } /* IP lists */ $files = glob("{$snortdir}/tmp/snortrules/rules/*.txt"); foreach ($files as $file) { $newfile = basename($file); @copy($file, "{$snortdir}/rules/{$newfile}"); } 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; if ($snort_arch == 'i386'){ exec("/usr/bin/tar xzf {$tmpfname}/{$snort_filename} -C {$snortdir}/tmp so_rules/precompiled/$freebsd_version_so/i386/{$snort_version}/"); exec("/bin/cp {$snortdir}/tmp/so_rules/precompiled/$freebsd_version_so/i386/{$snort_version}/* /usr/local/lib/snort/dynamicrules/"); } else if ($snort_arch == 'amd64') { exec("/usr/bin/tar xzf {$tmpfname}/{$snort_filename} -C {$snortdir}/tmp so_rules/precompiled/$freebsd_version_so/x86-64/{$snort_version}/"); exec("/bin/cp {$snortdir}/tmp/so_rules/precompiled/$freebsd_version_so/x86-64/{$snort_version}/* /usr/local/lib/snort/dynamicrules/"); } else $nosorules = true; exec("rm -r {$snortdir}/tmp/so_rules"); 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) { $newfile = basename($file, ".rules"); @copy($file, "{$snortdir}/rules/snort_{$newfile}.so.rules"); } 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", "unicode.map") as $file) { if (file_exists("{$snortdir}/tmp/etc/{$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 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 Snort VRT signatures...")); exec("/bin/cp -r {$snortdir}/doc/signatures {$snortdir}/signatures"); update_status(gettext("Done copying signatures.")); } } foreach (glob("/usr/local/lib/snort/dynamicrules/*example*") as $file) @unlink($file); exec("/usr/bin/tar xzf {$tmpfname}/{$snort_filename} -C {$snortdir} preproc_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 after rules extraction...")); exec("/bin/rm -r {$snortdir}/tmp"); } function build_sid_msg_map($rules_dir, $sid_file) { $sidMap = array(); /* Normalize the supplied rules path to have a trailing */ /* slash in the directory name. */ $my_rules_dir = ((strrpos($rules_dir, '/') + 1) == strlen($rules_dir)) ? $rules_dir : $rules_dir . "/"; /* Read the rule files into an array, then iterate the list */ foreach (glob($my_rules_dir . "*.rules") 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; /* Skip disabled rules or comment lines. */ if (preg_match('/^\s*#/', $rule)) 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) { $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) { $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_apply_customizations($snortcfg, $if_real) { global $snortdir; if (empty($snortcfg['rulesets'])) return; else { $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}"); } } @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['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); } if (!empty($snortcfg['rule_sid_off'])) { $enabled_sid_off_array = explode("||", trim($snortcfg['rule_sid_off'])); $disabled_sids = array_flip($enabled_sid_off_array); } $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; } } } if ($changed == true) @file_put_contents($file, implode("\n", $splitcontents)); } } } if ($snortdownload == 'on' || $emergingthreats == 'on') { /* Build a new sid-msg.map file from downloaded and enabled rules. */ update_status(gettext('Generating new sid-msg map file...')); build_sid_msg_map("{$snortdir}/rules/", "{$snortdir}/sid-msg.map"); 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) { /* Create configuration for each active Snort interface */ $if_real = snort_get_real_interface($value['interface']); $tmp = "Updating rules configuration for: "; if (!empty($value['descr'])) $tmp += $value['descr']; else $tmp += $value['interface']; $tmp += " ..."; 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("The Rules update finished...")); log_error("The Rules update finished..."); conf_mount_ro(); ?>