"{$snortlibdir}/dynamicrules", "dynamicengine" => "{$snortlibdir}/dynamicengine", "dynamicpreprocessor" => "{$snortcfgdir}/dynamicpreprocessor" ); foreach ($snort_dirs as $dir) { if (!is_dir($dir)) safe_mkdir($dir); } /********************************************************************/ /* For fail-safe on an initial startup following installation, and */ /* before a rules update has occurred, copy the default config */ /* files to the interface directory. If files already exist in */ /* the interface directory, or they are newer, that means a rule */ /* update has been done and we should leave the customized files */ /* put in place by the rules update process. */ /********************************************************************/ $snort_files = array("gen-msg.map", "classification.config", "reference.config", "attribute_table.dtd", "sid-msg.map", "unicode.map", "threshold.conf", "preproc_rules/preprocessor.rules", "preproc_rules/decoder.rules", "preproc_rules/sensitive-data.rules" ); foreach ($snort_files as $file) { if (file_exists("{$snortdir}/{$file}")) { $ftime = filemtime("{$snortdir}/{$file}"); if (!file_exists("{$snortcfgdir}/{$file}") || ($ftime > filemtime("{$snortcfgdir}/{$file}"))) @copy("{$snortdir}/{$file}", "{$snortcfgdir}/{$file}"); } } /* define alertsystemlog */ $alertsystemlog_type = ""; if ($snortcfg['alertsystemlog'] == "on") $alertsystemlog_type = "output alert_syslog: log_alert"; /* define snortunifiedlog */ $snortunifiedlog_type = ""; if ($snortcfg['snortunifiedlog'] == "on") $snortunifiedlog_type = "output unified2: filename snort_{$snort_uuid}_{$if_real}.u2, limit 128"; /* define spoink */ $spoink_type = ""; if ($snortcfg['blockoffenders7'] == "on") { $pfkill = ""; if ($snortcfg['blockoffenderskill'] == "on") $pfkill = "kill"; $spoink_wlist = snort_build_list($snortcfg, $snortcfg['whitelistname'], true); /* write whitelist */ @file_put_contents("{$snortcfgdir}/{$snortcfg['whitelistname']}", implode("\n", $spoink_wlist)); $spoink_type = "output alert_pf: {$snortcfgdir}/{$snortcfg['whitelistname']},snort2c,{$snortcfg['blockoffendersip']},{$pfkill}"; } /* define selected suppress file */ $suppress_file_name = ""; $suppress = snort_find_list($snortcfg['suppresslistname'], 'suppress'); if (!empty($suppress)) { $suppress_data = str_replace("\r", "", base64_decode($suppress['suppresspassthru'])); @file_put_contents("{$snortcfgdir}/supp{$snortcfg['suppresslistname']}", $suppress_data); $suppress_file_name = "include {$snortcfgdir}/supp{$snortcfg['suppresslistname']}"; } /* set the snort performance model */ $snort_performance = "ac-bnfa"; if(!empty($snortcfg['performance'])) $snort_performance = $snortcfg['performance']; /* if user has defined a custom ssh port, use it */ if(is_array($config['system']['ssh']) && isset($config['system']['ssh']['port'])) $ssh_port = $config['system']['ssh']['port']; else $ssh_port = "22"; /* Define an array of default values for the various preprocessor ports */ $snort_ports = array( "dns_ports" => "53", "smtp_ports" => "25", "mail_ports" => "25,465,587,691", "http_ports" => "36,80,81,82,83,84,85,86,87,88,89,90,311,383,591,593,631,901,1220,1414,1533,1741,1830,2301,2381,2809,3037,3057,3128,3443,3702,4343,4848,5250,6080,6988,7000,7001,7144,7145,7510,7777,7779,8000,8008,8014,8028,8080,8081,8082,8085,8088,8090,8118,8123,8180,8181,8222,8243,8280,8300,8500,8800,8888,8899,9000,9060,9080,9090,9091,9443,9999,10000,11371,15489,29991,33300,34412,34443,34444,41080,44440,50000,50002,51423,55555,56712", "oracle_ports" => "1024:", "mssql_ports" => "1433", "telnet_ports" => "23", "snmp_ports" => "161", "ftp_ports" => "21,2100,3535", "ssh_ports" => $ssh_port, "pop2_ports" => "109", "pop3_ports" => "110", "imap_ports" => "143", "sip_ports" => "5060,5061,5600", "auth_ports" => "113", "finger_ports" => "79", "irc_ports" => "6665,6666,6667,6668,6669,7000", "smb_ports" => "139,445", "nntp_ports" => "119", "rlogin_ports" => "513", "rsh_ports" => "514", "ssl_ports" => "443,465,563,636,989,992,993,994,995,7801,7802,7900,7901,7902,7903,7904,7905,7906,7907,7908,7909,7910,7911,7912,7913,7914,7915,7916,7917,7918,7919,7920", "file_data_ports" => "\$HTTP_PORTS,110,143", "shellcode_ports" => "!80", "sun_rpc_ports" => "111,32770,32771,32772,32773,32774,32775,32776,32777,32778,32779", "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", "DNP3_PORTS" => "20000", "MODBUS_PORTS" => "502", "GTP_PORTS" => "2123,2152,3386" ); /* Check for defined Aliases that may override default port settings as we build the portvars array */ $portvardef = ""; foreach ($snort_ports as $alias => $avalue) { if (!empty($snortcfg["def_{$alias}"]) && is_alias($snortcfg["def_{$alias}"])) $snort_ports[$alias] = trim(filter_expand_alias($snortcfg["def_{$alias}"])); $snort_ports[$alias] = preg_replace('/\s+/', ',', trim($snort_ports[$alias])); $portvardef .= "portvar " . strtoupper($alias) . " [" . $snort_ports[$alias] . "]\n"; } /* Define the default ports for the Stream5 preprocessor (formatted for easier reading in the snort.conf file) */ $stream5_ports_client = "21 22 23 25 42 53 70 79 109 110 111 113 119 135 136 137 \\\n"; $stream5_ports_client .= "\t 139 143 161 445 513 514 587 593 691 1433 1521 1741 \\\n"; $stream5_ports_client .= "\t 2100 3306 6070 6665 6666 6667 6668 6669 7000 8181 \\\n"; $stream5_ports_client .= "\t 32770 32771 32772 32773 32774 32775 32776 32777 \\\n"; $stream5_ports_client .= "\t 32778 32779"; $stream5_ports_both = "80 81 82 83 84 85 86 87 88 89 90 110 311 383 443 465 563 \\\n"; $stream5_ports_both .= "\t 591 593 631 636 901 989 992 993 994 995 1220 1414 1533 \\\n"; $stream5_ports_both .= "\t 1830 2301 2381 2809 3037 3057 3128 3443 3702 4343 4848 \\\n"; $stream5_ports_both .= "\t 5250 6080 6988 7907 7000 7001 7144 7145 7510 7802 7777 \\\n"; $stream5_ports_both .= "\t 7779 7801 7900 7901 7902 7903 7904 7905 7906 7908 7909 \\\n"; $stream5_ports_both .= "\t 7910 7911 7912 7913 7914 7915 7916 7917 7918 7919 7920 \\\n"; $stream5_ports_both .= "\t 8000 8008 8014 8028 8080 8081 8082 8085 8088 8090 8118 \\\n"; $stream5_ports_both .= "\t 8123 8180 8222 8243 8280 8300 8500 8800 8888 8899 9000 \\\n"; $stream5_ports_both .= "\t 9060 9080 9090 9091 9443 9999 10000 11371 15489 29991 \\\n"; $stream5_ports_both .= "\t 33300 34412 34443 34444 41080 44440 50000 50002 51423 \\\n"; $stream5_ports_both .= "\t 55555 56712"; ///////////////////////////// /* preprocessor code */ /* def perform_stat */ $perform_stat = << '0') { $ftp_telnet_protocol .= " \\\n\tayt_attack_thresh "; if ($snortcfg['ftp_telnet_ayt_attack_threshold'] != "") $ftp_telnet_protocol .= $snortcfg['ftp_telnet_ayt_attack_threshold']; else $ftp_telnet_protocol .= "20"; } // Setup the standard FTP commands used for all FTP Server engines $ftp_cmds = << \ cmd_validity STRU < char FRP > \ cmd_validity ALLO < int [ char R int ] > \ cmd_validity TYPE < { char AE [ char NTC ] | char I | char L [ number ] } > \ cmd_validity MDTM < [ date nnnnnnnnnnnnnn[.n[n[n]]] ] string > \ cmd_validity PORT < host_port > EOD; // Configure all the FTP_Telnet FTP protocol options // Iterate and configure the FTP Client engines $ftp_default_client_engine = array( "name" => "default", "bind_to" => "all", "max_resp_len" => 256, "telnet_cmds" => "no", "ignore_telnet_erase_cmds" => "yes", "bounce" => "yes", "bounce_to_net" => "", "bounce_to_port" => "" ); if (!is_array($snortcfg['ftp_client_engine']['item'])) $snortcfg['ftp_client_engine']['item'] = array(); // If no FTP client engine is configured, use the default // to keep from breaking Snort. if (empty($snortcfg['ftp_client_engine']['item'])) $snortcfg['ftp_client_engine']['item'][] = $ftp_default_client_engine; $ftp_client_engine = ""; foreach ($snortcfg['ftp_client_engine']['item'] as $f => $v) { $buffer = "preprocessor ftp_telnet_protocol: ftp client "; if ($v['name'] == "default" && $v['bind_to'] == "all") $buffer .= "default \\\n"; elseif (is_alias($v['bind_to'])) { $tmp = trim(filter_expand_alias($v['bind_to'])); if (!empty($tmp)) { $tmp = preg_replace('/\s+/', ' ', $tmp); $buffer .= "{$tmp} \\\n"; } else { log_error("[snort] ERROR: unable to resolve IP Address Alias '{$v['bind_to']}' for FTP client '{$v['name']}' ... skipping entry."); continue; } } else { log_error("[snort] ERROR: unable to resolve IP Address Alias '{$v['bind_to']}' for FTP client '{$v['name']}' ... skipping entry."); continue; } if ($v['max_resp_len'] == "") $buffer .= "\tmax_resp_len 256 \\\n"; else $buffer .= "\tmax_resp_len {$v['max_resp_len']} \\\n"; $buffer .= "\ttelnet_cmds {$v['telnet_cmds']} \\\n"; $buffer .= "\tignore_telnet_erase_cmds {$v['ignore_telnet_erase_cmds']} \\\n"; if ($v['bounce'] == "yes") { if (is_alias($v['bounce_to_net']) && is_alias($v['bounce_to_port'])) { $net = trim(filter_expand_alias($v['bounce_to_net'])); $port = trim(filter_expand_alias($v['bounce_to_port'])); if (!empty($net) && !empty($port) && snort_is_single_addr_alias($v['bounce_to_net']) && (is_port($port) || is_portrange($port))) { $port = preg_replace('/\s+/', ',', $port); // Change port range delimiter to comma for ftp_telnet client preprocessor if (is_portrange($port)) $port = str_replace(":", ",", $port); $buffer .= "\tbounce yes \\\n"; $buffer .= "\tbounce_to { {$net},{$port} }\n"; } else { // One or both of the BOUNCE_TO alias values is not right, // so figure out which and log an appropriate error. if (empty($net) || !snort_is_single_addr_alias($v['bounce_to_net'])) log_error("[snort] ERROR: illegal value for bounce_to Address Alias [{$v['bounce_to_net']}] for FTP client engine [{$v['name']}] ... omitting 'bounce_to' option for this client engine."); if (empty($port) || !(is_port($port) || is_portrange($port))) log_error("[snort] ERROR: illegal value for bounce_to Port Alias [{$v['bounce_to_port']}] for FTP client engine [{$v['name']}] ... omitting 'bounce_to' option for this client engine."); $buffer .= "\tbounce yes\n"; } } else $buffer .= "\tbounce yes\n"; } else $buffer .= "\tbounce no\n"; // Add this FTP client engine to the master string $ftp_client_engine .= "{$buffer}\n"; } // Trim final trailing newline rtrim($ftp_client_engine); // Iterate and configure the FTP Server engines $ftp_default_server_engine = array( "name" => "default", "bind_to" => "all", "ports" => "default", "telnet_cmds" => "no", "ignore_telnet_erase_cmds" => "yes", "ignore_data_chan" => "no", "def_max_param_len" => 100 ); if (!is_array($snortcfg['ftp_server_engine']['item'])) $snortcfg['ftp_server_engine']['item'] = array(); // If no FTP server engine is configured, use the default // to keep from breaking Snort. if (empty($snortcfg['ftp_server_engine']['item'])) $snortcfg['ftp_server_engine']['item'][] = $ftp_default_server_engine; $ftp_server_engine = ""; foreach ($snortcfg['ftp_server_engine']['item'] as $f => $v) { $buffer = "preprocessor ftp_telnet_protocol: ftp server "; if ($v['name'] == "default" && $v['bind_to'] == "all") $buffer .= "default \\\n"; elseif (is_alias($v['bind_to'])) { $tmp = trim(filter_expand_alias($v['bind_to'])); if (!empty($tmp)) { $tmp = preg_replace('/\s+/', ' ', $tmp); $buffer .= "{$tmp} \\\n"; } else { log_error("[snort] ERROR: unable to resolve IP Address Alias '{$v['bind_to']}' for FTP server '{$v['name']}' ... skipping entry."); continue; } } else { log_error("[snort] ERROR: unable to resolve IP Address Alias '{$v['bind_to']}' for FTP server '{$v['name']}' ... skipping entry."); continue; } if ($v['def_max_param_len'] == "") $buffer .= "\tdef_max_param_len 100 \\\n"; elseif ($v['def_max_param_len'] <> '0') $buffer .= "\tdef_max_param_len {$v['def_max_param_len']} \\\n"; if ($v['ports'] == "default" || !is_alias($v['ports']) || empty($v['ports'])) $buffer .= "\tports { {$ftp_ports} } \\\n"; elseif (is_alias($v['ports'])) { $tmp = trim(filter_expand_alias($v['ports'])); if (!empty($tmp)) { $tmp = preg_replace('/\s+/', ' ', $tmp); $tmp = snort_expand_port_range($tmp, ' '); $buffer .= "\tports { {$tmp} } \\\n"; } else { log_error("[snort] ERROR: unable to resolve Port Alias '{$v['ports']}' for FTP server '{$v['name']}' ... reverting to defaults."); $buffer .= "\tports { {$ftp_ports} } \\\n"; } } $buffer .= "\ttelnet_cmds {$v['telnet_cmds']} \\\n"; $buffer .= "\tignore_telnet_erase_cmds {$v['ignore_telnet_erase_cmds']} \\\n"; if ($v['ignore_data_chan'] == "yes") $buffer .= "\tignore_data_chan yes \\\n"; $buffer .= "{$ftp_cmds}\n"; // Add this FTP server engine to the master string $ftp_server_engine .= $buffer; } // Remove trailing newlines rtrim($ftp_server_engine); $ftp_preprocessor = << "\$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", "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" ); // Change old name from "var" to new name of "ipvar" for IP variables because // Snort is deprecating the old "var" name in newer versions. $ipvardef = ""; foreach ($snort_servers as $alias => $avalue) { if (!empty($snortcfg["def_{$alias}"]) && is_alias($snortcfg["def_{$alias}"])) { $avalue = trim(filter_expand_alias($snortcfg["def_{$alias}"])); $avalue = preg_replace('/\s+/', ',', trim($avalue)); } $ipvardef .= "ipvar " . strtoupper($alias) . " [{$avalue}]\n"; } $snort_preproc_libs = array( "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", "gtp_preproc" => "gtp_preproc", "smtp_preprocessor" => "smtp_preproc", "ssh_preproc" => "ssh_preproc", "ssl_preproc" => "ssl_preproc", "dnp3_preproc" => "dnp3_preproc", "modbus_preproc" => "modbus_preproc" ); $snort_preproc = array ( "perform_stat", "other_preprocs", "ftp_preprocessor", "smtp_preprocessor", "ssl_preproc", "sip_preproc", "gtp_preproc", "ssh_preproc", "sf_portscan", "dce_rpc_2", "dns_preprocessor", "sensitive_data", "pop_preproc", "imap_preproc", "dnp3_preproc", "modbus_preproc" ); $default_disabled_preprocs = array( "sf_portscan", "gtp_preproc", "sensitive_data", "dnp3_preproc", "modbus_preproc" ); $snort_preprocessors = ""; foreach ($snort_preproc as $preproc) { if ($snortcfg[$preproc] == 'on' || empty($snortcfg[$preproc]) ) { /* If preprocessor is not explicitly "on" or "off", then default to "off" if in our default disabled list */ if (empty($snortcfg[$preproc]) && in_array($preproc, $default_disabled_preprocs)) continue; /* NOTE: The $$ is not a bug. It is an advanced feature of php */ if (!empty($snort_preproc_libs[$preproc])) { $preproclib = "libsf_" . $snort_preproc_libs[$preproc]; if (!file_exists($snort_dirs['dynamicpreprocessor'] . "{$preproclib}.so")) { if (file_exists("{$snortlibdir}/dynamicpreprocessor/{$preproclib}.so")) { @copy("{$snortlibdir}/dynamicpreprocessor/{$preproclib}.so", "{$snort_dirs['dynamicpreprocessor']}/{$preproclib}.so"); $snort_preprocessors .= $$preproc; $snort_preprocessors .= "\n"; } else log_error("Could not find the {$preproclib} file. Snort might error out!"); } else { $snort_preprocessors .= $$preproc; $snort_preprocessors .= "\n"; } } else { $snort_preprocessors .= $$preproc; $snort_preprocessors .= "\n"; } } } // Remove final trailing newline $snort_preprocessors = rtrim($snort_preprocessors); $snort_misc_include_rules = ""; if (file_exists("{$snortcfgdir}/reference.config")) $snort_misc_include_rules .= "include {$snortcfgdir}/reference.config\n"; if (file_exists("{$snortcfgdir}/classification.config")) $snort_misc_include_rules .= "include {$snortcfgdir}/classification.config\n"; if (is_dir("{$snortcfgdir}/preproc_rules")) { if ($snortcfg['sensitive_data'] == 'on' && $protect_preproc_rules == "off") { $sedcmd = '/^#alert.*classtype:sdf/s/^#//'; if (file_exists("{$snortcfgdir}/preproc_rules/sensitive-data.rules")){ $snort_misc_include_rules .= "include \$PREPROC_RULE_PATH/sensitive-data.rules\n"; #enable only selected sensitive data if (file_exists(SNORTDIR."/preproc_rules/sensitive-data.rules")){ $sdf_alert_pattern="(".preg_replace("/,/","|",$snortcfg['sdf_alert_data_type']).")"; $sd_tmp_file=file(SNORTDIR."/preproc_rules/sensitive-data.rules"); $sd_tmp_new_file=""; foreach ($sd_tmp_file as $sd_tmp_line) $sd_tmp_new_file.=preg_match("/$sdf_alert_pattern/i",$sd_tmp_line) ? $sd_tmp_line : ""; file_put_contents("{$snortcfgdir}/preproc_rules/sensitive-data.rules",$sd_tmp_new_file,LOCK_EX); } } } else $sedcmd = '/^alert.*classtype:sdf/s/^/#/'; if (file_exists("{$snortcfgdir}/preproc_rules/decoder.rules") && file_exists("{$snortcfgdir}/preproc_rules/preprocessor.rules") && $protect_preproc_rules == "off") { @file_put_contents("{$g['tmp_path']}/sedcmd", $sedcmd); mwexec("/usr/bin/sed -I '' -f {$g['tmp_path']}/sedcmd {$snortcfgdir}/preproc_rules/preprocessor.rules"); mwexec("/usr/bin/sed -I '' -f {$g['tmp_path']}/sedcmd {$snortcfgdir}/preproc_rules/decoder.rules"); @unlink("{$g['tmp_path']}/sedcmd"); $snort_misc_include_rules .= "include \$PREPROC_RULE_PATH/decoder.rules\n"; $snort_misc_include_rules .= "include \$PREPROC_RULE_PATH/preprocessor.rules\n"; } else if (file_exists("{$snortcfgdir}/preproc_rules/decoder.rules") && file_exists("{$snortcfgdir}/preproc_rules/preprocessor.rules") && $protect_preproc_rules == "on") { $snort_misc_include_rules .= "include \$PREPROC_RULE_PATH/decoder.rules\n"; $snort_misc_include_rules .= "include \$PREPROC_RULE_PATH/preprocessor.rules\n"; } else { $snort_misc_include_rules .= "config autogenerate_preprocessor_decoder_rules\n"; log_error("[Snort] Seems preprocessor/decoder rules are missing, enabling autogeneration of them"); } } else { $snort_misc_include_rules .= "config autogenerate_preprocessor_decoder_rules\n"; log_error("[Snort] Seems preprocessor/decoder rules are missing, enabling autogeneration of them"); } /* generate rule sections to load */ /* The files are always configured so the update process is easier */ $selected_rules_sections = "include \$RULE_PATH/{$snort_enforcing_rules_file}\n"; $selected_rules_sections .= "include \$RULE_PATH/{$flowbit_rules_file}\n"; $selected_rules_sections .= "include \$RULE_PATH/custom.rules\n"; // Remove trailing newlines $snort_misc_include_rules = rtrim($snort_misc_include_rules); $selected_rules_sections = rtrim($selected_rules_sections); /* Create the actual rules files and save in the interface directory */ snort_prepare_rule_files($snortcfg, $snortcfgdir); $cksumcheck = "all"; if ($snortcfg['cksumcheck'] == 'on') $cksumcheck = "none"; /* Pull in user-configurable detection config options */ $cfg_detect_settings = "search-method {$snort_performance} max-pattern-len 20 max_queue_events 5"; if ($snortcfg['fpm_split_any_any'] == "on") $cfg_detect_settings .= " split-any-any"; if ($snortcfg['fpm_search_optimize'] == "on") $cfg_detect_settings .= " search-optimize"; if ($snortcfg['fpm_no_stream_inserts'] == "on") $cfg_detect_settings .= " no_stream_inserts"; /* Pull in user-configurable options for Frag3 preprocessor settings */ /* Get global Frag3 options first and put into a string */ $frag3_global = "preprocessor frag3_global: "; if (!empty($snortcfg['frag3_memcap']) || $snortcfg['frag3_memcap'] == "0") $frag3_global .= "memcap {$snortcfg['frag3_memcap']}, "; else $frag3_global .= "memcap 4194304, "; if (!empty($snortcfg['frag3_max_frags'])) $frag3_global .= "max_frags {$snortcfg['frag3_max_frags']}"; else $frag3_global .= "max_frags 8192"; if ($snortcfg['frag3_detection'] == "off") $frag3_global .= ", disabled"; $frag3_default_tcp_engine = array( "name" => "default", "bind_to" => "all", "policy" => "bsd", "timeout" => 60, "min_ttl" => 1, "detect_anomalies" => "on", "overlap_limit" => 0, "min_frag_len" => 0 ); $frag3_engine = ""; // Now iterate configured Frag3 engines and write them to a string if enabled if ($snortcfg['frag3_detection'] == "on") { if (!is_array($snortcfg['frag3_engine']['item'])) $snortcfg['frag3_engine']['item'] = array(); // If no frag3 tcp engine is configured, use the default if (empty($snortcfg['frag3_engine']['item'])) $snortcfg['frag3_engine']['item'][] = $frag3_default_tcp_engine; foreach ($snortcfg['frag3_engine']['item'] as $f => $v) { $frag3_engine .= "preprocessor frag3_engine: "; $frag3_engine .= "policy {$v['policy']}"; if ($v['bind_to'] <> "all") { $tmp = trim(filter_expand_alias($v['bind_to'])); if (!empty($tmp)) { $tmp = preg_replace('/\s+/', ',', $tmp); if (strpos($tmp, ",") !== false) $frag3_engine .= " \\\n\tbind_to [{$tmp}]"; else $frag3_engine .= " \\\n\tbind_to {$tmp}"; } else log_error("[snort] WARNING: unable to resolve IP List Alias '{$v['bind_to']}' for Frag3 engine '{$v['name']}' ... using 0.0.0.0 failsafe."); } $frag3_engine .= " \\\n\ttimeout {$v['timeout']}"; $frag3_engine .= " \\\n\tmin_ttl {$v['min_ttl']}"; if ($v['detect_anomalies'] == "on") { $frag3_engine .= " \\\n\tdetect_anomalies"; $frag3_engine .= " \\\n\toverlap_limit {$v['overlap_limit']}"; $frag3_engine .= " \\\n\tmin_fragment_length {$v['min_frag_len']}"; } // Add newlines to terminate this engine $frag3_engine .= "\n\n"; } // Remove trailing newline $frag3_engine = rtrim($frag3_engine); } // Grab any user-customized value for Protocol Aware Flushing (PAF) max PDUs $paf_max_pdu_config = "config paf_max: "; if (empty($snortcfg['max_paf']) || $snortcfg['max_paf'] == '0') $paf_max_pdu_config .= "0"; else $paf_max_pdu_config .= $snortcfg['max_paf']; // Pull in user-configurable options for Stream5 preprocessor settings // Get global options first and put into a string $stream5_global = "preprocessor stream5_global: \\\n"; if ($snortcfg['stream5_reassembly'] == "off") $stream5_global .= "\tdisabled, \\\n"; if ($snortcfg['stream5_track_tcp'] == "off") $stream5_global .= "\ttrack_tcp no,"; else { $stream5_global .= "\ttrack_tcp yes,"; if (!empty($snortcfg['stream5_max_tcp'])) $stream5_global .= " \\\n\tmax_tcp {$snortcfg['stream5_max_tcp']},"; else $stream5_global .= " \\\n\tmax_tcp 262144,"; } if ($snortcfg['stream5_track_udp'] == "off") $stream5_global .= " \\\n\ttrack_udp no,"; else { $stream5_global .= " \\\n\ttrack_udp yes,"; if (!empty($snortcfg['stream5_max_udp'])) $stream5_global .= " \\\n\tmax_udp {$snortcfg['stream5_max_udp']},"; else $stream5_global .= " \\\n\tmax_udp 131072,"; } if ($snortcfg['stream5_track_icmp'] == "on") { $stream5_global .= " \\\n\ttrack_icmp yes,"; if (!empty($snortcfg['stream5_max_icmp'])) $stream5_global .= " \\\n\tmax_icmp {$snortcfg['stream5_max_icmp']},"; else $stream5_global .= " \\\n\tmax_icmp 65536,"; } else $stream5_global .= " \\\n\ttrack_icmp no,"; if (!empty($snortcfg['stream5_mem_cap'])) $stream5_global .= " \\\n\tmemcap {$snortcfg['stream5_mem_cap']},"; else $stream5_global .= " \\\n\tmemcap 8388608,"; if (!empty($snortcfg['stream5_prune_log_max']) || $snortcfg['stream5_prune_log_max'] == '0') $stream5_global .= " \\\n\tprune_log_max {$snortcfg['stream5_prune_log_max']}"; else $stream5_global .= " \\\n\tprune_log_max 1048576"; if ($snortcfg['stream5_flush_on_alert'] == "on") $stream5_global .= ", \\\n\tflush_on_alert"; $stream5_default_tcp_engine = array( "name" => "default", "bind_to" => "all", "policy" => "bsd", "timeout" => 30, "max_queued_bytes" => 1048576, "detect_anomalies" => "off", "overlap_limit" => 0, "max_queued_segs" => 2621, "require_3whs" => "off", "startup_3whs_timeout" => 0, "no_reassemble_async" => "off", "dont_store_lg_pkts" => "off", "max_window" => 0, "use_static_footprint_sizes" => "off", "check_session_hijacking" => "off", "ports_client" => "default", "ports_both" => "default", "ports_server" => "none" ); $stream5_tcp_engine = ""; // Now iterate configured Stream5 TCP engines and write them to a string if enabled if ($snortcfg['stream5_reassembly'] == "on") { if (!is_array($snortcfg['stream5_tcp_engine']['item'])) $snortcfg['stream5_tcp_engine']['item'] = array(); // If no stream5 tcp engine is configured, use the default if (empty($snortcfg['stream5_tcp_engine']['item'])) $snortcfg['stream5_tcp_engine']['item'][] = $stream5_default_tcp_engine; foreach ($snortcfg['stream5_tcp_engine']['item'] as $f => $v) { $buffer = "preprocessor stream5_tcp: "; $buffer .= "policy {$v['policy']},"; if ($v['bind_to'] <> "all") { $tmp = trim(filter_expand_alias($v['bind_to'])); if (!empty($tmp)) { $tmp = preg_replace('/\s+/', ',', $tmp); if (strpos($tmp, ",") !== false) $buffer .= " \\\n\tbind_to [{$tmp}],"; else $buffer .= " \\\n\tbind_to {$tmp},"; } else { log_error("[snort] WARNING: unable to resolve IP Address Alias [{$v['bind_to']}] for Stream5 TCP engine '{$v['name']}' ... skipping this engine."); continue; } } $stream5_tcp_engine .= $buffer; $stream5_tcp_engine .= " \\\n\ttimeout {$v['timeout']},"; $stream5_tcp_engine .= " \\\n\toverlap_limit {$v['overlap_limit']},"; $stream5_tcp_engine .= " \\\n\tmax_window {$v['max_window']},"; $stream5_tcp_engine .= " \\\n\tmax_queued_bytes {$v['max_queued_bytes']},"; $stream5_tcp_engine .= " \\\n\tmax_queued_segs {$v['max_queued_segs']}"; if ($v['use_static_footprint_sizes'] == "on") $stream5_tcp_engine .= ", \\\n\tuse_static_footprint_sizes"; if ($v['check_session_hijacking'] == "on") $stream5_tcp_engine .= ", \\\n\tcheck_session_hijacking"; if ($v['dont_store_lg_pkts'] == "on") $stream5_tcp_engine .= ", \\\n\tdont_store_large_packets"; if ($v['no_reassemble_async'] == "on") $stream5_tcp_engine .= ", \\\n\tdont_reassemble_async"; if ($v['detect_anomalies'] == "on") $stream5_tcp_engine .= ", \\\n\tdetect_anomalies"; if ($v['require_3whs'] == "on") $stream5_tcp_engine .= ", \\\n\trequire_3whs {$v['startup_3whs_timeout']}"; if (!empty($v['ports_client'])) { $stream5_tcp_engine .= ", \\\n\tports client"; if ($v['ports_client'] == " all") $stream5_tcp_engine .= " all"; elseif ($v['ports_client'] == "default") $stream5_tcp_engine .= " {$stream5_ports_client}"; else { $tmp = trim(filter_expand_alias($v['ports_client'])); if (!empty($tmp)) $stream5_tcp_engine .= " " . trim(preg_replace('/\s+/', ' ', $tmp)); else { $stream5_tcp_engine .= " {$stream5_ports_client}"; log_error("[snort] WARNING: unable to resolve Ports Client Alias [{$v['ports_client']}] for Stream5 TCP engine '{$v['name']}' ... using default value."); } } } if (!empty($v['ports_both'])) { $stream5_tcp_engine .= ", \\\n\tports both"; if ($v['ports_both'] == " all") $stream5_tcp_engine .= " all"; elseif ($v['ports_both'] == "default") $stream5_tcp_engine .= " {$stream5_ports_both}"; else { $tmp = trim(filter_expand_alias($v['ports_both'])); if (!empty($tmp)) $stream5_tcp_engine .= " " . trim(preg_replace('/\s+/', ' ', $tmp)); else { $stream5_tcp_engine .= " {$stream5_ports_both}"; log_error("[snort] WARNING: unable to resolve Ports Both Alias [{$v['ports_both']}] for Stream5 TCP engine '{$v['name']}' ... using default value."); } } } if (!empty($v['ports_server']) && $v['ports_server'] <> "none" && $v['ports_server'] <> "default") { if ($v['ports_server'] == " all") { $stream5_tcp_engine .= ", \\\n\tports server"; $stream5_tcp_engine .= " all"; } else { $tmp = trim(filter_expand_alias($v['ports_server'])); if (!empty($tmp)) { $stream5_tcp_engine .= ", \\\n\tports server"; $stream5_tcp_engine .= " " . trim(preg_replace('/\s+/', ' ', $tmp)); } else log_error("[snort] WARNING: unable to resolve Ports Server Alias [{$v['ports_server']}] for Stream5 TCP engine '{$v['name']}' ... defaulting to none."); } } // Make sure the "ports" parameter is set, or else default to a safe value if (strpos($stream5_tcp_engine, "ports ") === false) $stream5_tcp_engine .= ", \\\n\tports both all"; // Add a pair of newlines to terminate this engine $stream5_tcp_engine .= "\n\n"; } // Trim off the final trailing newline $stream5_tcp_engine = rtrim($stream5_tcp_engine); } // Configure the Stream5 UDP engine if it and Stream5 reassembly are enabled if ($snortcfg['stream5_track_udp'] == "off" || $snortcfg['stream5_reassembly'] == "off") $stream5_udp_engine = ""; else { $stream5_udp_engine = "preprocessor stream5_udp: "; if (!empty($snortcfg['stream5_udp_timeout'])) $stream5_udp_engine .= "timeout {$snortcfg['stream5_udp_timeout']}"; else $stream5_udp_engine .= "timeout 30"; } // Configure the Stream5 ICMP engine if it and Stream5 reassembly are enabled if ($snortcfg['stream5_track_icmp'] == "on" && $snortcfg['stream5_reassembly'] == "on") { $stream5_icmp_engine = "preprocessor stream5_icmp: "; if (!empty($snortcfg['stream5_icmp_timeout'])) $stream5_icmp_engine .= "timeout {$snortcfg['stream5_icmp_timeout']}"; else $stream5_icmp_engine .= "timeout 30"; } else $stream5_icmp_engine = ""; // Check for and configure Host Attribute Table if enabled $host_attrib_config = ""; if ($snortcfg['host_attribute_table'] == "on" && !empty($snortcfg['host_attribute_data'])) { file_put_contents("{$snortcfgdir}/host_attributes", base64_decode($snortcfg['host_attribute_data'])); $host_attrib_config = "# Host Attribute Table #\n"; $host_attrib_config .= "attribute_table filename {$snortcfgdir}/host_attributes\n"; if (!empty($snortcfg['max_attribute_hosts'])) $host_attrib_config .= "config max_attribute_hosts: {$snortcfg['max_attribute_hosts']}\n"; if (!empty($snortcfg['max_attribute_services_per_host'])) $host_attrib_config .= "config max_attribute_services_per_host: {$snortcfg['max_attribute_services_per_host']}"; } // Configure the HTTP_INSPECT preprocessor // Get global options first and put into a string $http_inspect_global = "preprocessor http_inspect: global "; if ($snortcfg['http_inspect'] == "off") $http_inspect_global .= "disabled "; $http_inspect_global .= "\\\n\tiis_unicode_map unicode.map 1252 \\\n"; $http_inspect_global .= "\tcompress_depth 65535 \\\n"; $http_inspect_global .= "\tdecompress_depth 65535 \\\n"; if (!empty($snortcfg['http_inspect_memcap'])) $http_inspect_global .= "\tmemcap {$snortcfg['http_inspect_memcap']} \\\n"; else $http_inspect_global .= "\tmemcap 150994944 \\\n"; if (!empty($snortcfg['http_inspect_max_gzip_mem'])) $http_inspect_global .= "\tmax_gzip_mem {$snortcfg['http_inspect_max_gzip_mem']}"; else $http_inspect_global .= "\tmax_gzip_mem 838860"; if ($snortcfg['http_inspect_proxy_alert'] == "on") $http_inspect_global .= " \\\n\tproxy_alert"; $http_inspect_default_engine = array( "name" => "default", "bind_to" => "all", "server_profile" => "all", "enable_xff" => "off", "log_uri" => "off", "log_hostname" => "off", "server_flow_depth" => 65535, "enable_cookie" => "on", "client_flow_depth" => 1460, "extended_response_inspection" => "on", "no_alerts" => "off", "unlimited_decompress" => "on", "inspect_gzip" => "on", "normalize_cookies" =>"on", "normalize_headers" => "on", "normalize_utf" => "on", "normalize_javascript" => "on", "allow_proxy_use" => "off", "inspect_uri_only" => "off", "max_javascript_whitespaces" => 200, "post_depth" => -1, "max_headers" => 0, "max_spaces" => 0, "max_header_length" => 0, "ports" => "default" ); $http_ports = str_replace(",", " ", snort_expand_port_range($snort_ports['http_ports'])); $http_inspect_servers = ""; // Iterate configured HTTP_INSPECT servers and write them to string if HTTP_INSPECT enabled if ($snortcfg['http_inspect'] <> "off") { if (!is_array($snortcfg['http_inspect_engine']['item'])) $snortcfg['http_inspect_engine']['item'] = array(); // If no http_inspect_engine is configured, use the default if (empty($snortcfg['http_inspect_engine']['item'])) $snortcfg['http_inspect_engine']['item'][] = $http_inspect_default_engine; foreach ($snortcfg['http_inspect_engine']['item'] as $f => $v) { $buffer = "preprocessor http_inspect_server: \\\n"; if ($v['name'] == "default") $buffer .= "\tserver default \\\n"; elseif (is_alias($v['bind_to'])) { $tmp = trim(filter_expand_alias($v['bind_to'])); if (!empty($tmp)) { $tmp = preg_replace('/\s+/', ' ', $tmp); $buffer .= "\tserver { {$tmp} } \\\n"; } else { log_error("[snort] WARNING: unable to resolve IP Address Alias [{$v['bind_to']}] for HTTP_INSPECT server '{$v['name']}' ... skipping this server engine."); continue; } } else { log_error("[snort] WARNING: unable to resolve IP Address Alias [{$v['bind_to']}] for HTTP_INSPECT server '{$v['name']}' ... skipping this server engine."); continue; } $http_inspect_servers .= $buffer; $http_inspect_servers .= "\tprofile {$v['server_profile']} \\\n"; if ($v['no_alerts'] == "on") $http_inspect_servers .= "\tno_alerts \\\n"; if ($v['ports'] == "default" || empty($v['ports'])) $http_inspect_servers .= "\tports { {$http_ports} } \\\n"; elseif (is_alias($v['ports'])) { $tmp = trim(filter_expand_alias($v['ports'])); if (!empty($tmp)) { $tmp = preg_replace('/\s+/', ' ', $tmp); $tmp = snort_expand_port_range($tmp, ' '); $http_inspect_servers .= "\tports { {$tmp} } \\\n"; } else { log_error("[snort] WARNING: unable to resolve Ports Alias [{$v['ports']}] for HTTP_INSPECT server '{$v['name']}' ... using safe default instead."); $http_inspect_servers .= "\tports { {$http_ports} } \\\n"; } } else { log_error("[snort] WARNING: unable to resolve Ports Alias [{$v['ports']}] for HTTP_INSPECT server '{$v['name']}' ... using safe default instead."); $http_inspect_servers .= "\tports { {$http_ports} } \\\n"; } $http_inspect_servers .= "\tserver_flow_depth {$v['server_flow_depth']} \\\n"; $http_inspect_servers .= "\tclient_flow_depth {$v['client_flow_depth']} \\\n"; $http_inspect_servers .= "\thttp_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 } \\\n"; $http_inspect_servers .= "\tpost_depth {$v['post_depth']} \\\n"; $http_inspect_servers .= "\tmax_headers {$v['max_headers']} \\\n"; $http_inspect_servers .= "\tmax_header_length {$v['max_header_length']} \\\n"; $http_inspect_servers .= "\tmax_spaces {$v['max_spaces']}"; if ($v['enable_xff'] == "on") $http_inspect_servers .= " \\\n\tenable_xff"; if ($v['enable_cookie'] == "on") $http_inspect_servers .= " \\\n\tenable_cookie"; if ($v['normalize_cookies'] == "on") $http_inspect_servers .= " \\\n\tnormalize_cookies"; if ($v['normalize_headers'] == "on") $http_inspect_servers .= " \\\n\tnormalize_headers"; if ($v['normalize_utf'] == "on") $http_inspect_servers .= " \\\n\tnormalize_utf"; if ($v['allow_proxy_use'] == "on") $http_inspect_servers .= " \\\n\tallow_proxy_use"; if ($v['inspect_uri_only'] == "on") $http_inspect_servers .= " \\\n\tinspect_uri_only"; if ($v['extended_response_inspection'] == "on") { $http_inspect_servers .= " \\\n\textended_response_inspection"; if ($v['inspect_gzip'] == "on") { $http_inspect_servers .= " \\\n\tinspect_gzip"; if ($v['unlimited_decompress'] == "on") $http_inspect_servers .= " \\\n\tunlimited_decompress"; } if ($v['normalize_javascript'] == "on") { $http_inspect_servers .= " \\\n\tnormalize_javascript"; $http_inspect_servers .= " \\\n\tmax_javascript_whitespaces {$v['max_javascript_whitespaces']}"; } } if ($v['log_uri'] == "on") $http_inspect_servers .= " \\\n\tlog_uri"; if ($v['log_hostname'] == "on") $http_inspect_servers .= " \\\n\tlog_hostname"; // Add a pair of trailing newlines to terminate this server config $http_inspect_servers .= "\n\n"; } /* Trim off the final trailing newline */ $http_inspect_server = rtrim($http_inspect_server); } // Finally, build the Snort configuration file $snort_conf_text = << "console") $snort_gui_include = true; include "/usr/local/pkg/snort/snort_check_for_rule_updates.php"; update_status(gettext("Generating snort.conf configuration file from saved settings...")); $rebuild_rules = true; /* Create the snort.conf files for each enabled interface */ $snortconf = $config['installedpackages']['snortglobal']['rule']; foreach ($snortconf as $value) { $if_real = snort_get_real_interface($value['interface']); /* create a snort.conf file for interface */ snort_build_new_conf($value); /* create barnyard2.conf file for interface */ if ($value['barnyard_enable'] == 'on') snort_create_barnyard2_conf($value, $if_real); } /* create snort bootup file snort.sh */ snort_create_rc(); /* Set Log Limit, Block Hosts Time and Rules Update Time */ snort_snortloglimit_install_cron($config['installedpackages']['snortglobal']['snortloglimit'] == 'on' ? true : false); snort_rm_blocked_install_cron($config['installedpackages']['snortglobal']['rm_blocked'] != "never_b" ? true : false); snort_rules_up_install_cron($config['installedpackages']['snortglobal']['autorulesupdate7'] != "never_up" ? true : false); /* Add the recurring jobs created above to crontab */ configure_cron(); conf_mount_ro(); $rebuild_rules = false; update_output_window(gettext("Finished rebuilding Snort configuration files...")); log_error(gettext("[Snort] Finished rebuilding installation from saved settings...")); /* Only try to start Snort if not in reboot */ if (!$g['booting']) { update_status(gettext("Starting Snort using rebuilt configuration...")); update_output_window(gettext("Please wait... while Snort is started...")); log_error(gettext("[Snort] Starting Snort using rebuilt configuration...")); start_service("snort"); update_output_window(gettext("Snort has been started using the rebuilt configuration...")); } } /* Done with post-install, so clear flag */ unset($g['snort_postinstall']); log_error(gettext("[Snort] Package post-installation tasks completed...")); return true; ?>