$val){ $offset = 0; $found = false; foreach ($temp_array as $tmp_key => $tmp_val) { if (!$found and strtolower($val[$subkey]) > strtolower($tmp_val[$subkey])) { $temp_array = array_merge((array)array_slice($temp_array,0,$offset), array($key => $val), array_slice($temp_array,$offset)); $found = true; }; $offset++; }; if (!$found) $temp_array = array_merge($temp_array, array($key => $val)); }; if ($sort_ascending) { $array = array_reverse($temp_array); } else $array = $temp_array; /* below is the complement for empty array test */ return true; }; /* check if suricata widget variable is set */ $suri_nentries = $config['widgets']['widget_suricata_display_lines']; if (!isset($suri_nentries) || $suri_nentries < 0) $suri_nentries = 5; // Called by Ajax to update alerts table contents if (isset($_GET['getNewAlerts'])) { $response = ""; $suri_alerts = suricata_widget_get_alerts(); $counter = 0; foreach ($suri_alerts as $a) { $response .= $a['instanceid'] . " " . $a['dateonly'] . "||" . $a['timeonly'] . "||" . $a['src'] . "||"; $response .= $a['dst'] . "||" . $a['msg'] . "\n"; $counter++; if($counter >= $suri_nentries) break; } echo $response; return; } if(isset($_POST['widget_suricata_display_lines'])) { $config['widgets']['widget_suricata_display_lines'] = $_POST['widget_suricata_display_lines']; write_config("Saved Suricata Alerts Widget Displayed Lines Parameter via Dashboard"); header("Location: ../../index.php"); } // Read "$suri_nentries" worth of alerts from the top of the alerts.log file function suricata_widget_get_alerts() { global $config, $a_instance, $suri_nentries; $suricata_alerts = array(); /* read log file(s) */ $counter=0; foreach ($a_instance as $instanceid => $instance) { $suricata_uuid = $a_instance[$instanceid]['uuid']; $if_real = get_real_interface($a_instance[$instanceid]['interface']); // make sure alert file exists, then grab the most recent {$suri_nentries} from it // and write them to a temp file. if (file_exists("/var/log/suricata/suricata_{$if_real}{$suricata_uuid}/alerts.log")) { exec("tail -{$suri_nentries} -r /var/log/suricata/suricata_{$if_real}{$suricata_uuid}/alerts.log > /tmp/surialerts_{$suricata_uuid}"); if (file_exists("/tmp/surialerts_{$suricata_uuid}")) { /*************** FORMAT without CSV patch -- ALERT -- ***********************************************************************************/ /* Line format: timestamp action[**] [gid:sid:rev] msg [**] [Classification: class] [Priority: pri] {proto} src:srcport -> dst:dstport */ /* 0 1 2 3 4 5 6 7 8 9 10 11 12 */ /****************************************************************************************************************************************/ /**************** FORMAT without CSV patch -- DECODER EVENT -- **************************************************************************/ /* Line format: timestamp action[**] [gid:sid:rev] msg [**] [Classification: class] [Priority: pri] [**] [Raw pkt: ...] */ /* 0 1 2 3 4 5 6 7 */ /************** *************************************************************************************************************************/ if (!$fd = fopen("/tmp/surialerts_{$suricata_uuid}", "r")) { log_error(gettext("[Suricata Widget] Failed to open file /tmp/surialerts_{$suricata_uuid}")); continue; } $buf = ""; while (($buf = fgets($fd)) !== FALSE) { $fields = array(); $tmp = array(); // Parse alert log entry to find the parts we want to display $fields[0] = substr($buf, 0, strpos($buf, ' ')); // The regular expression match below returns an array as follows: // [2] => GID, [3] => SID, [4] => REV, [5] => MSG, [6] => CLASSIFICATION, [7] = PRIORITY preg_match('/\[\*{2}\]\s\[((\d+):(\d+):(\d+))\]\s(.*)\[\*{2}\]\s\[Classification:\s(.*)\]\s\[Priority:\s(\d+)\]\s/', $buf, $tmp); $fields['gid'] = trim($tmp[2]); $fields['sid'] = trim($tmp[3]); $fields['rev'] = trim($tmp[4]); $fields['msg'] = trim($tmp[5]); $fields['class'] = trim($tmp[6]); $fields['priority'] = trim($tmp[7]); // The regular expression match below looks for the PROTO, SRC and DST fields // and returns an array as follows: // [1] = PROTO, [2] => SRC:SPORT [3] => DST:DPORT if (preg_match('/\{(.*)\}\s(.*)\s->\s(.*)/', $buf, $tmp)) { // Get SRC $fields['src'] = trim(substr($tmp[2], 0, strrpos($tmp[2], ':'))); if (is_ipaddrv6($fields['src'])) $fields['src'] = inet_ntop(inet_pton($fields['src'])); // Get SPORT $fields['sport'] = trim(substr($tmp[2], strrpos($tmp[2], ':') + 1)); // Get DST $fields['dst'] = trim(substr($tmp[3], 0, strrpos($tmp[3], ':'))); if (is_ipaddrv6($fields['dst'])) $fields['dst'] = inet_ntop(inet_pton($fields['dst'])); // Get DPORT $fields['dport'] = trim(substr($tmp[3], strrpos($tmp[3], ':') + 1)); } else { // If no PROTO and IP ADDR, then this is a DECODER EVENT $fields['src'] = gettext("Decoder Event"); $fields['sport'] = ""; $fields['dst'] = ""; $fields['dport'] = ""; } // Create a DateTime object from the event timestamp that // we can use to easily manipulate output formats. $event_tm = date_create_from_format("m/d/Y-H:i:s.u", $fields[0]); // Check the 'CATEGORY' field for the text "(null)" and // substitute "No classtype defined". if ($fields['class'] == "(null)") $fields['class'] = "No classtype assigned"; $suricata_alerts[$counter]['instanceid'] = strtoupper(convert_friendly_interface_to_friendly_descr($a_instance[$instanceid]['interface'])); $suricata_alerts[$counter]['timestamp'] = strval(date_timestamp_get($event_tm)); $suricata_alerts[$counter]['timeonly'] = date_format($event_tm, "H:i:s"); $suricata_alerts[$counter]['dateonly'] = date_format($event_tm, "M d"); $suricata_alerts[$counter]['msg'] = $fields['msg']; // Add square brackets around any IPv6 address if (is_ipaddrv6($fields['src'])) $suricata_alerts[$counter]['src'] = "[" . $fields['src'] . "]"; else $suricata_alerts[$counter]['src'] = $fields['src']; // Add the SRC PORT if not null if (!empty($fields['sport']) || $fields['sport'] == '0') $suricata_alerts[$counter]['src'] .= ":" . $fields['sport']; // Add square brackets around any IPv6 address if (is_ipaddrv6($fields['dst'])) $suricata_alerts[$counter]['dst'] = "[" . $fields['dst'] . "]"; else $suricata_alerts[$counter]['dst'] = $fields['dst']; // Add the DST PORT if not null if (!empty($fields['dport']) || $fields['dport'] == '0') $suricata_alerts[$counter]['dst'] .= ":" . $fields['dport']; $counter++; }; fclose($fd); @unlink("/tmp/surialerts_{$suricata_uuid}"); }; }; }; // Sort the alerts array if (isset($config['syslog']['reverse'])) { suricata_sksort($suricata_alerts, 'timestamp', false); } else { suricata_sksort($suricata_alerts, 'timestamp', true); } return $suricata_alerts; } /* display the result */ ?> "); $counter++; if($counter >= $suri_nentries) break; } } ?>
" . $alert['instanceid'] . " " . $alert['dateonly'] . "
" . $alert['timeonly'] . "
" . $alert['src'] . "

" . $alert['dst'] . "
" . $alert['msg'] . "