advanced features */ $bpfbufsize = $config['installedpackages']['snortadvanced']['config'][0]['bpfbufsize']; $bpfmaxbufsize = $config['installedpackages']['snortadvanced']['config'][0]['bpfmaxbufsize']; $bpfmaxinsns = $config['installedpackages']['snortadvanced']['config'][0]['bpfmaxinsns']; /* set the snort performance model */ if($config['installedpackages']['snort']['config'][0]['performance']) $snort_performance = $config['installedpackages']['snort']['config'][0]['performance']; else $snort_performance = "ac-bnfa"; conf_mount_rw(); /* create a few directories and ensure the sample files are in place */ exec("/bin/mkdir -p /usr/local/etc/snort"); exec("/bin/mkdir -p /var/log/snort"); exec("/bin/mkdir -p /usr/local/etc/snort/rules"); exec("/bin/cp /usr/local/etc/snort/unicode.map-sample /usr/local/etc/snort/unicode.map"); exec("/bin/cp /usr/local/etc/snort/classification.config-sample /usr/local/etc/snort/classification.config"); exec("/bin/cp /usr/local/etc/snort/gen-msg.map-sample /usr/local/etc/snort/gen-msg.map"); exec("/bin/cp /usr/local/etc/snort/generators-sample /usr/local/etc/snort/generators"); exec("/bin/cp /usr/local/etc/snort/reference.config-sample /usr/local/etc/snort/reference.config"); exec("/bin/cp /usr/local/etc/snort/sid-msg.map-sample /usr/local/etc/snort/sid-msg.map"); exec("/bin/cp /usr/local/etc/snort/sid-sample /usr/local/etc/snort/sid"); exec("/bin/cp /usr/local/etc/snort/threshold.conf-sample /usr/local/etc/snort/threshold.conf"); exec("/bin/cp /usr/local/etc/snort/unicode.map-sample /usr/local/etc/snort/unicode.map"); exec("/bin/rm -f /usr/local/etc/rc.d/snort"); $first = 0; $snortInterfaces = array(); /* -gtm */ $if_list = $config['installedpackages']['snort']['config'][0]['iface_array']; $if_array = split(',', $if_list); //print_r($if_array); if($if_array) { foreach($if_array as $iface) { $if = convert_friendly_interface_to_real_interface_name($iface); if($config['interfaces'][$iface]['ipaddr'] == "pppoe") { $if = "ng0"; } /* build a list of user specified interfaces -gtm */ if($if){ array_push($snortInterfaces, $if); $first = 1; } } if (count($snortInterfaces) < 1) { log_error("Snort will not start. You must select an interface for it to listen on."); return; } } //print_r($snortInterfaces); /* create log directory */ $start = "/bin/mkdir -p /var/log/snort\n"; /* snort advanced features - bpf tuning */ if($bpfbufsize) $start .= "sysctl net.bpf.bufsize={$bpfbufsize}\n"; if($bpfmaxbufsize) $start .= "sysctl net.bpf.maxbufsize={$bpfmaxbufsize}\n"; if($bpfmaxinsns) $start .= "sysctl net.bpf.maxinsns={$bpfmaxinsns}\n"; /* go ahead and issue bpf changes */ if($bpfbufsize) mwexec_bg("sysctl net.bpf.bufsize={$bpfbufsize}"); if($bpfmaxbufsize) mwexec_bg("sysctl net.bpf.maxbufsize={$bpfmaxbufsize}"); if($bpfmaxinsns) mwexec_bg("sysctl net.bpf.maxinsns={$bpfmaxinsns}"); /* always stop snort2c before starting snort -gtm */ $start .= "/usr/bin/killall barnyard2\n"; /* start a snort process for each interface -gtm */ /* Note the sleep delay. Seems to help getting mult interfaces to start -gtm */ /* snort start options are; config file, log file, demon, interface, packet flow, alert type, quiet */ /* TODO; get snort to start under nologin shell */ foreach($snortInterfaces as $snortIf) { $start .= "sleep 8\n"; $start .= "snort -c /usr/local/etc/snort/snort.conf -l /var/log/snort -D -i {$snortIf} -q\n"; /* define snortbarnyardlog_chk */ $snortbarnyardlog_info_chk = $config['installedpackages']['snortadvanced']['config'][0]['snortbarnyardlog']; if ($snortbarnyardlog_info_chk == on) $start .= "\nsleep 4;barnyard2 -c /usr/local/etc/barnyard2.conf -d /var/log/snort -f snort.u2 -w /usr/local/etc/snort/barnyard2.waldo -D -q\n"; } // /* if block offenders is checked, start snort2c */ // if($_POST['blockoffenders']) { // $start .= "\nsleep 8\n"; // $start .= "snort2c -w /var/db/whitelist -a /var/log/snort/alert\n"; // } $if_snort_pid = "\nif ls /tmp/snort.sh.pid > /dev/null\nthen\n echo \"snort.sh is running\"\n exit 0\nelse\n echo \"snort.sh is not running\"\nfi\n"; $echo_snort_sh_pid = "\necho \"snort.sh run\" > /tmp/snort.sh.pid\n"; $echo_snort_sh_startup_log = "\necho \"snort.sh run\" >> /tmp/snort.sh_startup.log\n"; $sample_before = "\nBEFORE_MEM=`top | grep Free | grep Wired | awk '{print \$10}'`\n"; $sample_after = "\nAFTER_MEM=`top | grep Free | grep Wired | awk '{print \$10}'`\n"; $sleep_before_final = "\necho \"Sleeping before final memory sampling...\"\nsleep 17"; $total_free_after = "\nTOTAL_USAGE=`top | grep snort | grep -v grep | awk '{ print \$6 }'`\n"; $echo_usage = "\necho \"Ram free BEFORE starting Snort: \${BEFORE_MEM} -- Ram free AFTER starting Snort: \${AFTER_MEM}\" -- Mode {$snort_performance} -- Snort memory usage: \$TOTAL_USAGE | logger -p daemon.info -i -t SnortStartup\n"; $rm_snort_sh_pid = "\nrm /tmp/snort.sh.pid\n"; /* write out rc.d start/stop file */ write_rcfile(array( "file" => "snort.sh", "start" => "{$if_snort_pid}{$echo_snort_sh_pid}{$echo_snort_sh_startup_log}{$sample_before}{$start}{$sleep_before_final}{$sample_after}{$echo_usage}{$rm_snort_sh_pid}", "stop" => "/usr/bin/killall snort; killall snort2c" ) ); /* create snort configuration file */ create_snort_conf(); /* create barnyard2 configuration file */ $snortbarnyardlog_info_chk = $config['installedpackages']['snortadvanced']['config'][0]['snortbarnyardlog']; if ($snortbarnyardlog_info_chk == on) create_barnyard2_conf(); /* start snort service */ conf_mount_ro(); start_service("snort"); } /* open barnyard2.conf for writing */ function create_barnyard2_conf() { global $bconfig, $bg; /* write out barnyard2_conf */ $barnyard2_conf_text = generate_barnyard2_conf(); // conf_mount_rw(); $bconf = fopen("/usr/local/etc/barnyard2.conf", "w"); if(!$bconf) { log_error("Could not open /usr/local/etc/barnyard2.conf for writing."); exit; } fwrite($bconf, $barnyard2_conf_text); fclose($bconf); // conf_mount_ro(); } /* open barnyard2.conf for writing" */ function generate_barnyard2_conf() { global $config, $g; conf_mount_rw(); /* define snortbarnyardlog */ $snortbarnyardlog_database_info_chk = $config['installedpackages']['snortadvanced']['config'][0]['snortbarnyardlog_database']; $barnyard2_conf_text = << \ 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 > preprocessor ftp_telnet_protocol: ftp client default \ max_resp_len 256 \ bounce yes \ telnet_cmds yes ##################### # # SMTP preprocessor # # ##################### preprocessor SMTP: \ ports { 25 465 691 } \ inspection_type stateful \ normalize cmds \ 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 \ 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 } \ max_header_line_len 1000 \ max_response_line_len 512 \ alt_max_command_line_len 260 { MAIL } \ alt_max_command_line_len 300 { RCPT } \ alt_max_command_line_len 500 { HELP HELO ETRN EHLO } \ alt_max_command_line_len 255 { EXPN VRFY ATRN SIZE BDAT DEBUG EMAL ESAM ESND ESOM EVFY IDENT NOOP RSET } \ 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 } ################ # # sf Portscan # # ################ preprocessor sfportscan: scan_type { all } \ proto { all } \ memcap { 10000000 } \ sense_level { medium } \ ignore_scanners { \$HOME_NET } ############################ # # OLD # # preprocessor dcerpc: \ # # autodetect \ # # max_frag_size 3000 \ # # memcap 100000 # # ############################ ############### # # NEW # # DCE/RPC 2 # # ############### preprocessor dcerpc2: memcap 102400, events [smb, co, cl] preprocessor dcerpc2_server: default, policy WinXP, \ detect [smb [139,445], tcp 135, udp 135, rpc-over-http-server 593], \ autodetect [tcp 1025:, udp 1025:, rpc-over-http-server 1025:], \ smb_max_chain 3 #################### # # DNS preprocessor # # #################### preprocessor dns: \ ports { 53 } \ enable_rdata_overflow ############################## # # NEW # # Ignore SSL and Encryption # # ############################## preprocessor ssl: ports { 443 465 563 636 989 992 993 994 995 }, trustservers, noinspect_encrypted ##################### # # Snort Output Logs # # ##################### $snortalertlogtype_type $alertsystemlog_type $tcpdumplog_type $snortmysqllog_info_chk $snortunifiedlog_type $spoink_type ################# # # Misc Includes # # ################# include /usr/local/etc/snort/reference.config include /usr/local/etc/snort/classification.config include /usr/local/etc/snort/threshold.conf # Snort user pass through configuration {$snort_config_pass_thru} ################### # # Rules Selection # # ################### {$selected_rules_sections} EOD; return $snort_conf_text; } /* check downloaded text from snort.org to make sure that an error did not occur * for example, if you are not a premium subscriber you can only download rules * so often, etc. */ function check_for_common_errors($filename) { global $snort_filename, $snort_filename_md5, $console_mode; ob_flush(); $contents = file_get_contents($filename); if(stristr($contents, "You don't have permission")) { if(!$console_mode) { update_all_status("An error occured while downloading {$filename}."); hide_progress_bar_status(); } else { log_error("An error occured. Scroll down to inspect it's contents."); echo "An error occured. Scroll down to inspect it's contents."; } if(!$console_mode) { update_output_window(strip_tags("$contents")); } else { $contents = strip_tags($contents); log_error("Error downloading snort rules: {$contents}"); echo "Error downloading snort rules: {$contents}"; } scroll_down_to_bottom_of_page(); exit; } } /* force browser to scroll all the way down */ function scroll_down_to_bottom_of_page() { global $snort_filename, $console_mode; ob_flush(); if(!$console_mode) echo "\n"; } /* ensure downloaded file looks sane */ function verify_downloaded_file($filename) { global $snort_filename, $snort_filename_md5, $console_mode; ob_flush(); if(filesize($filename)<9500) { if(!$console_mode) { update_all_status("Checking {$filename}..."); check_for_common_errors($filename); } } update_all_status("Verifying {$filename}..."); if(!file_exists($filename)) { if(!$console_mode) { update_all_status("Could not fetch snort rules ({$filename}). Check oinkid key and dns and try again."); hide_progress_bar_status(); } else { log_error("Could not fetch snort rules ({$filename}). Check oinkid key and dns and try again."); echo "Could not fetch snort rules ({$filename}). Check oinkid key and dns and try again."; } exit; } update_all_status("Verifyied {$filename}."); } /* extract rules */ function extract_snort_rules_md5($tmpfname) { global $snort_filename, $snort_filename_md5, $console_mode; ob_flush(); if(!$console_mode) { $static_output = gettext("Extracting snort rules..."); update_all_status($static_output); } if(!is_dir("/usr/local/etc/snort/rules/")) mkdir("/usr/local/etc/snort/rules/"); $cmd = "/usr/bin/tar xzf {$tmpfname}/{$snort_filename} -C /usr/local/etc/snort/ rules/"; $handle = popen("{$cmd} 2>&1", 'r'); while(!feof($handle)) { $buffer = fgets($handle); update_output_window($buffer); } pclose($handle); if(!$console_mode) { $static_output = gettext("Snort rules extracted."); update_all_status($static_output); } else { log_error("Snort rules extracted."); echo "Snort rules extracted."; } } /* verify MD5 against downloaded item */ function verify_snort_rules_md5($tmpfname) { global $snort_filename, $snort_filename_md5, $console_mode; ob_flush(); if(!$console_mode) { $static_output = gettext("Verifying md5 signature..."); update_all_status($static_output); } $md555 = file_get_contents("{$tmpfname}/{$snort_filename_md5}"); $md5 = `/bin/echo "{$md555}" | /usr/bin/awk '{ print $4 }'`; $file_md5_ondisk = `/sbin/md5 {$tmpfname}/{$snort_filename} | /usr/bin/awk '{ print $4 }'`; if($md5 == $file_md5_ondisk) { if(!$console_mode) { $static_output = gettext("snort rules: md5 signature of rules mismatch."); update_all_status($static_output); hide_progress_bar_status(); } else { log_error("snort rules: md5 signature of rules mismatch."); echo "snort rules: md5 signature of rules mismatch."; } exit; } } /* hide progress bar */ function hide_progress_bar_status() { global $snort_filename, $snort_filename_md5, $console_mode; ob_flush(); if(!$console_mode) echo "\n"; } /* unhide progress bar */ function unhide_progress_bar_status() { global $snort_filename, $snort_filename_md5, $console_mode; ob_flush(); if(!$console_mode) echo "\n"; } /* update both top and bottom text box during an operation */ function update_all_status($status) { global $snort_filename, $snort_filename_md5, $console_mode; ob_flush(); if(!$console_mode) { update_status($status); update_output_window($status); } } /* obtain alert description for an ip address */ function get_snort_alert($ip) { global $snort_alert_file_split, $snort_config; if(!file_exists("/var/log/snort/alert")) return; if(!$snort_config) $snort_config = read_snort_config_cache(); if($snort_config[$ip]) return $snort_config[$ip]; if(!$snort_alert_file_split) $snort_alert_file_split = split("\n", file_get_contents("/var/log/snort/alert")); foreach($snort_alert_file_split as $fileline) { if (preg_match("/\[\*\*\] (\[.*\]) (.*) (\[\*\*\])/", $fileline, $matches)) $alert_title = $matches[2]; if (preg_match("/(\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b)/", $fileline, $matches)) $alert_ip = $matches[0]; if($alert_ip == $ip) { if(!$snort_config[$ip]) $snort_config[$ip] = $alert_title; return $alert_title; } } return "n/a"; } function make_clickable($buffer) { global $config, $g; /* if clickable urls is disabled, simply return buffer back to caller */ $clickablalerteurls = $config['installedpackages']['snort']['config'][0]['oinkmastercode']; if(!$clickablalerteurls) return $buffer; $buffer = eregi_replace("(^|[ \n\r\t])((http(s?)://)(www\.)?([a-z0-9_-]+(\.[a-z0-9_-]+)+)(/[^/ \n\r]*)*)","\\1\\2", $buffer); $buffer = eregi_replace("(^|[ \n\r\t])((ftp://)(www\.)?([a-z0-9_-]+(\.[a-z0-9_-]+)+)(/[^/ \n\r]*)*)","\\1\\2", $buffer); $buffer = eregi_replace("([a-z_-][a-z0-9\._-]*@[a-z0-9_-]+(\.[a-z0-9_-]+)+)","\\1", $buffer); $buffer = eregi_replace("(^|[ \n\r\t])(www\.([a-z0-9_-]+(\.[a-z0-9_-]+)+)(/[^/ \n\r]*)*)","\\1\\2", $buffer); $buffer = eregi_replace("(^|[ \n\r\t])(ftp\.([a-z0-9_-]+(\.[a-z0-9_-]+)+)(/[^/ \n\r]*)*)","\\1\\2", $buffer); return $buffer; } function read_snort_config_cache() { global $g, $config, $snort_config; if($snort_config) return $snort_config; if(file_exists($g['tmp_path'] . '/snort_config.cache')) { $snort_config = unserialize(file_get_contents($g['tmp_path'] . '/snort_config.cache')); return $snort_config; } return; } function write_snort_config_cache($snort_config) { global $g, $config; conf_mount_rw(); $configcache = fopen($g['tmp_path'] . '/snort_config.cache', "w"); if(!$configcache) { log_error("Could not open {$g['tmp_path']}/snort_config.cache for writing."); return false; } fwrite($configcache, serialize($snort_config)); fclose($configcache); conf_mount_ro(); return true; } function snort_advanced() { global $g, $config; sync_package_snort(); } function snort_define_servers() { global $g, $config; sync_package_snort(); } ?>