false,
PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => false,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
]);
} catch(PDOException $e){
// if connection fails, log PDO error.
error_log("Error connecting to mysql: ". $e->getMessage());
}
$type = $_REQUEST['type'];
$types = array(
'0' => 'level0',
'1' => 'level1',
'2' => 'level2',
'2a' => 'level2a',
'3' => 'payload',
'4' => 'signatures',
'5' => 'tab',
'6' => 'ec',
'7' => 'transcript',
'8' => 'filters',
'9' => 'cat',
'10' => 'map',
'11' => 'comments',
'12' => 'remove_comment',
'13' => 'sensors',
'14' => 'user_profile',
'15' => 'summary',
'16' => 'view',
'17' => 'autocat',
'18' => 'esquery',
'19' => 'addremoveobject',
'20' => 'getcolour',
'21' => 'objhistory',
'22' => 'times',
);
$type = $types[$type];
if (isset($_REQUEST['ts'])) {
// Need EC
$tsParts = explode("|", hextostr($_REQUEST['ts']));
$sdate = $tsParts[0];
$edate = $tsParts[1];
$stime = $tsParts[2];
$etime = $tsParts[3];
$offset = $tsParts[4];
$start = "CONVERT_TZ('$sdate $stime','$offset','+00:00')";
$end = "CONVERT_TZ('$edate $etime','$offset','+00:00')";
$when = "event.timestamp BETWEEN $start AND $end";
// combine start date and start time for prepared statements
$sdatetime = "$sdate $stime";
// combine end date and end time for prepared statements
$edatetime = "$edate $etime";
}
// user can specify sensors
$sensors = '';
$sensorsclean = '';
$in = '';
$sensor_params = array();
if (isset($_REQUEST['sensors'])) {
$sensors = hextostr($_REQUEST['sensors']);
if ($sensors == 'empty') {
$sensors = '';
} else {
// $sensors looks like this:
// AND event.sid IN('3','1')
// let's clean that up so we can use prepared statements
$sensorsclean = ltrim($sensors, 'AND event.sid IN(');
$sensorsclean = rtrim($sensorsclean, ')');
$sensorsclean = str_replace("'","", $sensorsclean);
// now we need to dynamically build IN for prepared statement based on:
// https://phpdelusions.net/pdo#like
$ids = explode(",", $sensorsclean);
foreach ($ids as $i => $item)
{
$key = ":id".$i;
$in .= "$key,";
$sensor_params[$key] = $item; // collecting values into key-value array
}
$in = rtrim($in,","); // :id0,:id1,:id2
$sensors = "AND event.sid IN($in)";
}
}
// rt is the queue-only toggle on the left side of the EVENTS tab
$rt = "";
if (isset($_REQUEST['rt']) && $_REQUEST['rt'] == 1) {
$rt = "AND event.status = 0";
}
// $sv is for sorting. For example: DESC
// this cannot be done via prepared statement, so we use a whitelist approach
$sv = "";
if (isset($_REQUEST['sv'])) {
$sv = $_REQUEST['sv'] == 'DESC' ? 'DESC' : 'ASC';
}
// many functions below rely on filters so let's build that out now
if (isset($_REQUEST['filter'])) {
$filter = hextostr($_REQUEST['filter']);
// $filter comes from the filter box in the upper right corner of the EVENTS tab. Default: empty
if ($filter != 'empty') {
if (substr($filter, 0,4) == 'cmt ') {
// user entered cmt into the filter box
// pull their filter out and place it into the prepared statement array
$comment = explode('cmt ', $filter);
$filtercmt = $comment[1];
$qp2 = "LEFT JOIN history ON event.sid = history.sid AND event.cid = history.cid
WHERE history.comment = :filtercmt";
// build parameters for prepared statement
$qp2_params = [":filtercmt" => "$filtercmt"];
} else {
// if the user didn't enter cmt, then they may be using one of the built-in filters
// for example, if the user wants to search for alerts with src or dst ip in US:
// cc us
// we'll then receive the following:
// (msrc.cc = 'us' OR mdst.cc = 'us')
// the general strategy is to try to match this with one of the built-in filters to ensure validity
// then build a prepared statement
// this needs to be fixed
$filter = str_replace('<','<', $filter);
$filter = str_replace('>','>', $filter);
// build parameters for prepared statement
$qp2_params = [":sdatetime" => "$sdatetime", ":edatetime" => "$edatetime", ":soffset" => "$offset", ":eoffset" => "$offset"];
// find whatever is enclosed in single ticks and replace with $
$exploded=explode("'",$filter);
$filtervar=$exploded[1];
$compfilter = str_replace($filtervar, '$', $filter);
// retrieve all valid filters from database
$statement="SELECT UNHEX(filter) from filters where type='filter';";
$query = $dbpdo->prepare("$statement");
$query->execute();
$rows = $query->fetchAll(PDO::FETCH_BOTH);
// search for user filter in list of valid filters
$newfilter = "";
$filter = "";
// "signature LIKE" is a special case
if ( "$compfilter" == "(signature LIKE '$' OR signature LIKE '$')" ) {
$filter = "AND (signature LIKE :filtervar1 OR signature LIKE :filtervar2)";
$qp2_params[":filtervar1"] = "%$filtervar%";
$qp2_params[":filtervar2"] = "%$filtervar%";
} else {
foreach ($rows as $row) {
if ( "$compfilter" == "$row[0]" ) {
$newfilter = $row[0];
$i=0;
while (strpos($newfilter, "'\$'") !== false) {
$newfilter = preg_replace('/\'\$\'/', ":filtervar$i", "$newfilter", 1);
$qp2_params[":filtervar$i"] = $filtervar;
$i++;
}
$filter = "AND " . $newfilter;
}
}
}
$qp2 = "WHERE event.timestamp BETWEEN CONVERT_TZ(:sdatetime,:soffset,'+00:00') AND CONVERT_TZ(:edatetime,:eoffset,'+00:00')
$sensors
$filter
$rt";
}
} else {
// filter box was empty so we'll just build a prepared statement using sensors and rt values
$qp2 = "WHERE event.timestamp BETWEEN CONVERT_TZ(:sdatetime,:soffset,'+00:00') AND CONVERT_TZ(:edatetime,:eoffset,'+00:00')
$sensors
$rt";
// build parameters for prepared statement
$qp2_params = [":sdatetime" => "$sdatetime", ":edatetime" => "$edatetime", ":soffset" => "$offset", ":eoffset" => "$offset"];
}
}
if (!$type) {
exit;
}
function ec() {
// This function returns event count grouped by status.
// This is used to populate the numbers in the Classification section on the left side of the EVENTS tab.
// This function has been updated to use PDO prepared statements.
global $sdatetime, $edatetime, $offset, $sensors, $sensor_params, $dbpdo;
// build statement
$statement = "SELECT COUNT(status) AS count, status FROM event LEFT JOIN sensor AS s ON event.sid = s.sid
WHERE event.timestamp BETWEEN CONVERT_TZ(:sdatetime,:soffset,'+00:00') AND CONVERT_TZ(:edatetime,:eoffset,'+00:00')
$sensors
GROUP BY status;";
// debug
//error_log("$statement");
// prepare statement
$query = $dbpdo->prepare("$statement");
// build parameters for prepared statement
$params = [":sdatetime" => "$sdatetime", ":edatetime" => "$edatetime", ":soffset" => "$offset", ":eoffset" => "$offset"];
// execute the prepared statement and pass it the local params array and the sensor_params array
$query->execute(array_merge($params,$sensor_params));
// fetch the data and encode to json
$rows = $query->fetchAll(PDO::FETCH_ASSOC);
$theJSON = json_encode($rows);
echo $theJSON;
}
function signatures() {
function urlMkr($line) {
$pattern = '/reference:url,([^;]+)/';
$answer = preg_replace($pattern, 'reference:url,$1', $line);
return $answer;
}
$object = $_REQUEST['sid'];
list($sigID, $gID) = explode("-", $object);
global $rulePath;
$wasMatched = 0;
$dirs = explode("||",$rulePath);
if ( $gID == 10001 ) {
$result = array("ruletxt" => "Generator ID $gID. OSSEC rules can be found in /var/ossec/rules/.",
"rulefile" => "n/a",
"ruleline" => "n/a",
);
} elseif ( $gID != 1 && $gID != 3 ) {
$result = array("ruletxt" => "Generator ID $gID. This event belongs to a preprocessor or decoder.",
"rulefile" => "n/a",
"ruleline" => "n/a",
);
} else {
$dc = (count($dirs) - 1);
for ($i = 0; $i <= $dc; $i++)
if ($ruleDir = opendir($dirs[$i])) {
while (false !== ($ruleFile = readdir($ruleDir))) {
if ($ruleFile != "." && $ruleFile != "..") {
$ruleLines = file("$dirs[$i]/$ruleFile");
$lineNumber = 1;
foreach($ruleLines as $line) {
$searchCount = preg_match("/sid\:\s*$sigID\s*\;/",$line);
if($searchCount > 0) {
$tempMsg = preg_match("/\bmsg\s*:\s*\"(.+?)\"\s*;/i",$line,$ruleMsg);
$line = urlMkr(htmlspecialchars($line));
$result = array("ruletxt" => $line,
"rulefile" => $ruleFile,
"ruleline" => $lineNumber,
);
$wasMatched = 1;
break;
}
$lineNumber++;
}
}
}
closedir($ruleDir);
}
if ($wasMatched == 0) {
$result = array("ruletxt" => "No match for signature ID $sigID",
"rulefile" => "n/a",
"ruleline" => "n/a",
);
}
}
$theJSON = json_encode($result);
echo $theJSON;
}
function level0() {
// This function returns the aggegrated event data in the main section of the EVENTS tab.
// This function has been updated to use PDO prepared statements.
global $offset, $when, $sensors, $rt, $sdatetime, $edatetime, $sensor_params, $dbpdo, $qp2, $qp2_params, $sv;
// build statement
$statement="SELECT COUNT(event.signature) AS f1,
event.signature AS f2,
event.signature_id AS f3,
event.signature_gen AS f4,
MAX(CONVERT_TZ(event.timestamp,'+00:00',:maxoffset)) AS f5,
COUNT(DISTINCT(event.src_ip)) AS f6,
COUNT(DISTINCT(event.dst_ip)) AS f7,
event.ip_proto AS f8,
GROUP_CONCAT(DISTINCT(event.status)) AS f9,
GROUP_CONCAT(DISTINCT(event.sid)) AS f10,
GROUP_CONCAT(event.status) AS f11,
GROUP_CONCAT(SUBSTRING(CONVERT_TZ(event.timestamp, '+00:00', :groupoffset),12,2)) AS f12,
event.priority AS f13,
GROUP_CONCAT(DISTINCT(src_tag.value)) AS f14,
GROUP_CONCAT(DISTINCT(dst_tag.value)) AS f15
FROM event
LEFT JOIN mappings AS msrc ON event.src_ip = msrc.ip
LEFT JOIN mappings AS mdst ON event.dst_ip = mdst.ip
LEFT JOIN object_mappings AS src_tag ON event.src_ip = src_tag.object AND src_tag.type = 'tag'
LEFT JOIN object_mappings AS dst_tag ON event.dst_ip = dst_tag.object AND dst_tag.type = 'tag'
$qp2
GROUP BY f3
ORDER BY f5 $sv";
// add params for local part of statement
$local_params[':maxoffset'] = "$offset";
$local_params[':groupoffset'] = "$offset";
// prepare statement
$query = $dbpdo->prepare("$statement");
// merge params
$merged_params = array_merge($local_params, $sensor_params, $qp2_params);
// debug
//error_log("statement: $statement");
//error_log("merged_params: " . print_r($merged_params,1));
// execute the prepared statement with the params
$query->execute($merged_params);
// fetch the data and encode to json
$rows = $query->fetchAll(PDO::FETCH_ASSOC);
// the frontend expects all values to be strings
for ($i=0;$iprepare("$statement");
// merge params
$merged_params = array_merge($local_params, $sensor_params, $qp2_params);
// debug
//error_log("statement: $statement");
//error_log("merged_params: " . print_r($merged_params,1));
// execute the prepared statement with the params
$query->execute($merged_params);
// fetch the data and encode to json
$rows = $query->fetchAll(PDO::FETCH_ASSOC);
// the frontend expects all values to be strings
for ($i=0;$iprepare("$statement");
// merge params
$merged_params = array_merge($local_params, $sensor_params, $qp2_params);
// debug
//error_log("statement: $statement");
//error_log("merged_params: " . print_r($merged_params,1));
// execute the prepared statement with the params
$query->execute($merged_params);
// fetch the data and encode to json
$rows = $query->fetchAll(PDO::FETCH_ASSOC);
// the frontend expects all values to be strings
for ($i=0;$iprepare("$statement");
// merge params
$merged_params = array_merge($local_params, $sensor_params, $qp2_params);
// debug
//error_log("statement: $statement");
//error_log("merged_params: " . print_r($merged_params,1));
// execute the prepared statement with the params
$query->execute($merged_params);
// fetch the data and encode to json
$rows = $query->fetchAll(PDO::FETCH_ASSOC);
// the frontend expects all values to be strings
for ($i=0;$iprepare("$statement");
// build parameters for prepared statement
$params = [":offset" => "$offset", ":sid" => "$sid", ":cid" => "$cid"];
// execute the prepared statement with params
$query->execute(array_merge($params));
// fetch the data
$row = $query->fetchall(PDO::FETCH_ASSOC);
$rows = array();
if (array_key_exists(0, $row)) {
$rows[] = $row[0];
}
$ipp = $row[0]["ip_proto"];
// Protocol
switch ($ipp) {
case 1:
$statement = "SELECT event.icmp_type AS icmp_type,
event.icmp_code AS icmp_code,
icmphdr.icmp_csum AS icmp_csum,
icmphdr.icmp_id AS icmp_id,
icmphdr.icmp_seq AS icmp_seq
FROM event, icmphdr
WHERE event.sid=icmphdr.sid
AND event.cid=icmphdr.cid
AND event.sid=:sid
AND event.cid=:cid";
// debug
//error_log("$statement");
// prepare statement
$query = $dbpdo->prepare("$statement");
// build parameters for prepared statement
$params = [":sid" => "$sid", ":cid" => "$cid"];
// execute the prepared statement with params
$query->execute(array_merge($params));
// fetch the data
$row = $query->fetchall(PDO::FETCH_ASSOC);
if (array_key_exists(0, $row)) {
$rows[] = $row[0];
}
break;
case 6:
$statement = "SELECT tcp_seq, tcp_ack, tcp_off, tcp_res, tcp_flags, tcp_win, tcp_urp, tcp_csum
FROM tcphdr
WHERE sid=:sid AND cid=:cid";
// prepare statement
$query = $dbpdo->prepare("$statement");
// build parameters for prepared statement
$params = [":sid" => "$sid", ":cid" => "$cid"];
// execute the prepared statement with params
$query->execute(array_merge($params));
// fetch the data
$row = $query->fetchall(PDO::FETCH_ASSOC);
if (array_key_exists(0, $row)) {
$rows[] = $row[0];
}
break;
case 17:
$statement = "SELECT udp_len, udp_csum
FROM udphdr
WHERE sid=:sid AND cid=:cid";
// prepare statement
$query = $dbpdo->prepare("$statement");
// build parameters for prepared statement
$params = [":sid" => "$sid", ":cid" => "$cid"];
// execute the prepared statement with params
$query->execute(array_merge($params));
// fetch the data
$row = $query->fetchall(PDO::FETCH_ASSOC);
if (array_key_exists(0, $row)) {
$rows[] = $row[0];
}
break;
default:
$result = array(0 => 0);
$rows[] = $row;
break;
}
// Data
$statement = "SELECT data_payload
FROM data
WHERE sid=:sid AND cid=:cid";
// prepare statement
$query = $dbpdo->prepare("$statement");
// build parameters for prepared statement
$params = [":sid" => "$sid", ":cid" => "$cid"];
// execute the prepared statement with params
$query->execute(array_merge($params));
// fetch the data and encode to json
$row = $query->fetchall(PDO::FETCH_ASSOC);
if (array_key_exists(0, $row)) {
$rows[] = $row[0];
// Add the row again for Bro agent
$rows[] = $row[0];
}
$theJSON = json_encode($rows);
echo $theJSON;
}
function tab() {
$tab = $_REQUEST['tab'];
$_SESSION['sTab'] = $tab;
}
function transcript() {
# We no longer use Squert's native transcript functionality.
# Squert now pivots to CapMe for transcripts.
}
function filters() {
// This function queries and updates the filters table.
// This function has been updated to use PDO prepared statements.
global $dbpdo;
$user = $_SESSION['sUser'];
$mode = $_REQUEST['mode'];
switch ($mode) {
case "query" :
$statement = "SELECT type, UNHEX(name) AS name, alias, filter, UNHEX(notes) as notes, age, global, username
FROM filters
ORDER BY global,name ASC";
$rows = array();
// debug
//error_log("$statement");
// prepare statement
$query = $dbpdo->prepare("$statement");
// execute the prepared statement with params
$query->execute();
# iterate through each row of the filter table
while ($row = $query->fetch(PDO::FETCH_ASSOC)) {
# for each field in that row, we need to sanitize before output
foreach ($row as &$value) {
# https://paragonie.com/blog/2015/06/preventing-xss-vulnerabilities-in-php-everything-you-need-know
$value = htmlentities($value, ENT_QUOTES | ENT_HTML5, 'UTF-8');
}
# must unset $value per http://php.net/manual/en/control-structures.foreach.php
unset($value);
# now add the sanitized row to the $rows array
$rows[] = $row;
}
$theJSON = json_encode($rows);
break;
case "update" :
$data = hextostr($_REQUEST['data']);
list($type, $alias, $name, $notes, $filter) = explode("||", $data);
$name = strtohex($name);
$notes = strtohex($notes);
$remove = array("DELETE","UPDATE","INSERT","SELECT","CONCAT",
"REVERSE","REPLACE","RLIKE","SUBSTR","SUBSTRING");
$filter = str_ireplace($remove, "", $filter);
$filter = strtohex($filter);
$statement = "INSERT INTO filters (type,name,alias,username,filter,notes)
VALUES (:type1,:name1,:alias1,:user1,:filter1,:notes1)
ON DUPLICATE KEY UPDATE
type=:type2,name=:name2,alias=:alias2,filter=:filter2,notes=:notes2";
// debug
//error_log("$statement");
// prepare statement
$query = $dbpdo->prepare("$statement");
// build parameters for prepared statement
$params = [":type1" => "$type", ":name1" => "$name", ":alias1" => "$alias", ":user1" => "$user", ":filter1" => "$filter", ":notes1" => "$notes", ":type2" => "$type", ":name2" => "$name", ":alias2" => "$alias", ":filter2" => "$filter", ":notes2" => "$notes"];
// execute the prepared statement with params
$query->execute(array_merge($params));
// check for errors
$error = $query->errorInfo();
$result = "";
// if there was no error, then $error[2] should be null
if ( ! is_null($error[2]) ) {
$result = $error[2];
}
$return = array("msg" => $result);
$theJSON = json_encode($return);
break;
case "remove" :
$alias = $_REQUEST['data'];
$statement = "DELETE FROM filters WHERE username = :user AND (alias = :alias AND global = 0)";
// debug
//error_log("$statement");
// prepare statement
$query = $dbpdo->prepare("$statement");
// build parameters for prepared statement
$params = [":user" => "$user", ":alias" => "$alias"];
// execute the prepared statement with the params
$query->execute(array_merge($params));
// check for errors
$error = $query->errorInfo();
$result = "";
// if there was no error, then $error[2] should be null
if ( ! is_null($error[2]) ) {
$result = $error[2];
}
$return = array("msg" => $result);
$theJSON = json_encode($return);
break;
}
echo $theJSON;
}
function cat() {
$catdata = $_REQUEST['catdata'];
$usr = $_SESSION['sUser'];
$pwd = $_SESSION['sPass'];
list($cat, $msg, $lst) = explode("|||", $catdata);
$msg = htmlentities($msg);
$cmdusr = escapeshellarg($usr);
$cmdcat = escapeshellarg($cat);
$cmdmsg = escapeshellarg($msg);
$cmdlst = escapeshellarg($lst);
$cmd = "../.scripts/clicat.tcl 0 $cmdusr $cmdcat $cmdmsg $cmdlst";
$descspec = array(
0 => array("pipe", "r"),
1 => array("pipe", "w")
);
$proc = proc_open($cmd, $descspec, $pipes);
$debug = "Process execution failed";
if (is_resource($proc)) {
fwrite($pipes[0], $pwd);
fclose($pipes[0]);
$debug = fgets($pipes[1]);
fclose($pipes[1]);
}
$result = array("dbg" => htmlspecialchars($debug));
$theJSON = json_encode($result);
echo $theJSON;
}
function comments() {
// This function retrieves comments from the history table.
// This function has been updated to use PDO prepared statements.
global $dbpdo;
$statement = "SELECT COUNT(comment) AS f1,
comment AS f2,
u.username AS f3,
MIN(timestamp) AS f4,
MAX(timestamp) AS f5,
GROUP_CONCAT(DISTINCT(status)) AS f6
FROM history
LEFT JOIN user_info AS u ON history.uid = u.uid
WHERE timestamp BETWEEN
UTC_DATE() - INTERVAL 365 DAY AND UTC_TIMESTAMP()
AND (comment NOT IN('NULL','Auto Update','') AND comment NOT LIKE ('autoid %'))
GROUP BY comment
ORDER BY f5 DESC";
// debug
//error_log("$statement");
// prepare statement
$query = $dbpdo->prepare("$statement");
// execute the prepared statement
$query->execute();
// fetch the data and encode to json
$rows = $query->fetchAll(PDO::FETCH_ASSOC);
$theJSON = json_encode($rows);
echo $theJSON;
}
function remove_comment() {
// This function removes a comment from the history table.
// This function has been updated to use PDO prepared statements.
global $dbpdo;
$user = $_SESSION['sUser'];
$comment = hextostr($_REQUEST['comment']);
$comment = $comment;
$statement = "DELETE FROM history WHERE comment = :comment";
// debug
//error_log("$statement");
// prepare statement
$query = $dbpdo->prepare("$statement");
// build parameters for prepared statement
$params = [":comment" => "$comment"];
// execute the prepared statement with the params
$query->execute(array_merge($params));
// check for errors
$error = $query->errorInfo();
$result = "";
// if there was no error, then $error[2] should be null
if ( ! is_null($error[2]) ) {
$result = $error[2];
}
$return = array("msg" => $result);
$theJSON = json_encode($return);
echo $theJSON;
}
function map() {
// This function is called when the user clicks the SUMMARY tab.
// This function has been updated to use PDO prepared statements.
global $when, $sensors, $qp2, $qp2_params, $sensor_params, $sv, $dbpdo;
$srcstatement = "SELECT COUNT(src_ip) AS c, msrc.cc
FROM event
LEFT JOIN mappings AS msrc ON event.src_ip = msrc.ip
LEFT JOIN mappings AS mdst ON event.dst_ip = mdst.ip
$qp2
AND src_ip NOT BETWEEN 167772160 AND 184549375
AND src_ip NOT BETWEEN 2886729728 AND 2886795263
AND src_ip NOT BETWEEN 3232235520 AND 3232301055
AND msrc.cc IS NOT NULL
GROUP BY msrc.cc
ORDER BY c DESC";
$dststatement = "SELECT COUNT(dst_ip) AS c, mdst.cc
FROM event
LEFT JOIN mappings AS msrc ON event.src_ip = msrc.ip
LEFT JOIN mappings AS mdst ON event.dst_ip = mdst.ip
$qp2
AND dst_ip NOT BETWEEN 167772160 AND 184549375
AND dst_ip NOT BETWEEN 2886729728 AND 2886795263
AND dst_ip NOT BETWEEN 3232235520 AND 3232301055
AND mdst.cc IS NOT NULL
GROUP BY mdst.cc
ORDER BY c DESC";
// prepare statements
$srcquery = $dbpdo->prepare("$srcstatement");
// merge params
$merged_params = array_merge($sensor_params, $qp2_params);
// debug
//error_log("srcstatement: $srcstatement");
//error_log("dststatement: $dststatement");
//error_log("merged_params: " . print_r($merged_params,1));
// execute the prepared statement with the params
$srcquery->execute($merged_params);
// A => src, B=> dst, C=> cumulative
$a1 = $a2 = $b1 = $b2 = array();
$aHit = $bHit = $cHit = 'no';
// Source countries and count
while ($row = $srcquery->fetch(PDO::FETCH_NUM)) {
$a1[] = $row[0];
$a2[] = $row[1];
$c1[] = $row[0];
$c2[] = $row[1];
$aHit = 'yes';
$cHit = 'yes';
}
$dstquery = $dbpdo->prepare("$dststatement");
$dstquery->execute($merged_params);
// Destination countries and count
// As we loop through we check to see if we hit a country
// that we already processed so that we can derive a sum
while ($row = $dstquery->fetch(PDO::FETCH_NUM)) {
$b1[] = $row[0];
$b2[] = $row[1];
if ($aHit == 'yes') {
$key = array_search($row[1],$c2);
if ($key === FALSE) {
$c1[] = $row[0];
$c2[] = $row[1];
} else {
$base = $c1[$key] + $row[0];
$c1[$key] = $base;
}
} else {
$c1[] = $row[0];
$c2[] = $row[1];
}
$bHit = 'yes';
$cHit = 'yes';
}
$aSum = $bSum = $cSum = $aItems = $bItems = $cItems = 0;
$srcd = $dstd = $alld = "";
function makeDetail($x1,$x2) {
$detail = "";
$lc = count($x1);
for ($i=0; $i<$lc; $i++) {
$detail .= "\"$x2[$i]\": \"$x1[$i]\"";
if ($i < $lc-1) {
$detail .= ",";
}
}
return $detail;
}
if ($aHit == 'yes') {
$aItems = count($a1);
$aSum = array_sum($a1);
array_multisort($a1, SORT_DESC, $a2);
$srcd = makeDetail($a1,$a2);
}
if ($bHit == 'yes') {
$bItems = count($b1);
$bSum = array_sum($b1);
array_multisort($b1, SORT_DESC, $b2);
$dstd = makeDetail($b1,$b2);
}
if ($cHit == 'yes') {
$cItems = count($c1);
$cSum = array_sum($c1);
array_multisort($c1, SORT_DESC, $c2);
$alld = makeDetail($c1,$c2);
}
$result = array("src" => "$srcd",
"dst" => "$dstd",
"all" => "$alld",
"srcc" => "$aItems",
"srce" => "$aSum",
"dstc" => "$bItems",
"dste" => "$bSum",
"allc" => "$cItems",
"alle" => "$cSum",
);
$theJSON = json_encode($result);
echo $theJSON;
}
function sensors() {
// This function gets the list of sensors.
// This function has been updated to use PDO prepared statements.
global $dbpdo;
//$query = "SELECT net_name AS f1,
$statement = "SELECT net_name AS f1,
hostname AS f2,
agent_type AS f3,
sensor.sid AS f4
FROM sensor
WHERE agent_type != 'pcap'
AND active = 'Y'
ORDER BY net_name ASC";
// debug
//error_log("$statement");
// prepare statement
$query = $dbpdo->prepare("$statement");
// execute the prepared statement
$query->execute();
// fetch the data and encode to json
$rows = $query->fetchAll(PDO::FETCH_ASSOC);
$theJSON = json_encode($rows);
echo $theJSON;
}
function user_profile() {
// This function updates the timezone offset in the user profile.
// This function has been updated to use PDO prepared statements.
global $dbpdo;
$user = $_SESSION['sUser'];
$tz = hextostr($_REQUEST['tz']);
$validtz = "/^(-12:00|-11:00|-10:00|-09:30|-09:00|-08:00|-07:00|-06:00|-05:00|-04:30|-04:00|-03:30|-03:00|-02:00|-01:00|\+00:00|\+01:00|\+02:00|\+03:00|\+03:30|\+04:00|\+04:30|\+05:00|\+05:30|\+05:45|\+06:00|\+06:30|\+07:00|\+08:00|\+08:45|\+09:00|\+09:30|\+10:00|\+10:30|\+11:00|\+11:30|\+12:00|\+12:45|\+13:00|\+14:00)$/";
if (preg_match($validtz, $tz)) {
// prepare statement
$statement = "UPDATE user_info SET tzoffset = :tz WHERE username = :user";
// debug
//error_log("$statement");
// prepare statement
$query = $dbpdo->prepare("$statement");
// build parameters for prepared statement
$params = [":tz" => "$tz", ":user" => "$user"];
// execute the prepared statement with the params
$query->execute($params);
// check for errors
$error = $query->errorInfo();
$result = "";
// if there was no error, then $error[2] should be null
if ( ! is_null($error[2]) ) {
$result = $error[2];
}
// Update session offset
$_SESSION['tzoffset'] = $tz;
} else {
$result = "Invalid timezone offset";
}
$return = array("msg" => $result);
$theJSON = json_encode($return);
echo $theJSON;
}
function summary() {
// This function is called when the user clicks the SUMMARY tab.
// This function has been updated to use PDO prepared statements.
global $when, $sensors, $qp2, $qp2_params, $sensor_params, $sv, $dbpdo;
$limit = $_REQUEST['limit'];
$qargs = $_REQUEST['qargs'];
$filter = hextostr($_REQUEST['filter']);
list($type,$subtype) = explode("-", $qargs);
$oppip = "src";
// subtype is controlled by user, don't trust it
$cleansubtype = "";
switch ($subtype) {
case "src":
$cleansubtype = "src";
$oppip = "dst";
break;
case "dst":
$cleansubtype = "dst";
break;
case "sig":
$cleansubtype = "sig";
break;
}
switch ($type) {
case "ip":
$statement = "SELECT COUNT(event.{$cleansubtype}_ip) AS f1,
COUNT(DISTINCT(event.signature)) AS f2,
COUNT(DISTINCT(event.{$oppip}_ip)) AS f3,
m{$cleansubtype}.cc AS f4,
m{$cleansubtype}.c_long AS f5,
INET_NTOA(event.{$cleansubtype}_ip) AS f6,
o{$cleansubtype}.value AS f7
FROM event
LEFT JOIN mappings AS msrc ON event.src_ip = msrc.ip
LEFT JOIN mappings AS mdst ON event.dst_ip = mdst.ip
LEFT JOIN object_mappings AS o{$cleansubtype} ON event.{$cleansubtype}_ip = o{$cleansubtype}.object
AND o{$cleansubtype}.type = 'ip_c'
$qp2
GROUP BY f6
ORDER BY f1 DESC";
break;
case "pt":
$statement = "SELECT COUNT(event.{$cleansubtype}_port) AS f1,
COUNT(DISTINCT(event.signature)) AS f2,
COUNT(DISTINCT(event.src_ip)) AS f3,
COUNT(DISTINCT(event.dst_ip)) AS f4,
event.{$cleansubtype}_port AS f5
FROM event
LEFT JOIN mappings AS msrc ON event.src_ip = msrc.ip
LEFT JOIN mappings AS mdst ON event.dst_ip = mdst.ip
$qp2
GROUP BY f5
ORDER BY f1 DESC";
break;
case "sig":
$statement = "SELECT COUNT(event.signature) AS f1,
COUNT(DISTINCT(event.src_ip)) AS f2,
COUNT(DISTINCT(event.dst_ip)) AS f3,
event.signature_id AS f4,
event.signature AS f5
FROM event
LEFT JOIN mappings AS msrc ON event.src_ip = msrc.ip
LEFT JOIN mappings AS mdst ON event.dst_ip = mdst.ip
$qp2
GROUP BY f4
ORDER BY f1 DESC";
break;
case "cc":
$statement = "SELECT COUNT(event.{$cleansubtype}_ip) AS f1,
COUNT(DISTINCT(event.signature)) AS f2,
COUNT(DISTINCT(event.{$oppip}_ip)) AS f3,
m{$cleansubtype}.cc AS f4,
m{$cleansubtype}.c_long AS f5,
COUNT(DISTINCT(event.{$cleansubtype}_ip)) AS f6
FROM event
LEFT JOIN mappings AS msrc ON event.src_ip = msrc.ip
LEFT JOIN mappings AS mdst ON event.dst_ip = mdst.ip
$qp2
AND event.{$cleansubtype}_ip NOT BETWEEN 167772160 AND 184549375
AND event.{$cleansubtype}_ip NOT BETWEEN 2886729728 AND 2886795263
AND event.{$cleansubtype}_ip NOT BETWEEN 3232235520 AND 3232301055
AND m{$cleansubtype}.cc IS NOT NULL GROUP BY m{$cleansubtype}.cc ORDER BY f1 DESC";
break;
}
// prepare statement
$query = $dbpdo->prepare("$statement");
// merge params
$merged_params = array_merge($sensor_params, $qp2_params);
// debug
//error_log("statement: $statement");
//error_log("merged_params: " . print_r($merged_params,1));
// execute the prepared statement with the params
$query->execute($merged_params);
$rows = array();
$i = 0;
$n = 0;
// unbuffered query can't do rowCount, replacing with $i below
//$r = $query->rowCount();
# iterate through each row of the filter table
while ($row = $query->fetch(PDO::FETCH_ASSOC)) {
$n += $row["f1"];
$i++;
if ($i <= $limit) $rows[] = $row;
}
$rows[] = array("n" => $n, "r" => $i);
$theJSON = json_encode($rows);
echo $theJSON;
}
function view() {
// This function is called when the user clicks the VIEWS tab.
// This function has been updated to use PDO prepared statements.
global $when, $sensors, $qp2, $qp2_params, $sensor_params, $sv, $dbpdo;
$qargs = $_REQUEST['qargs'];
$filter = hextostr($_REQUEST['filter']);
list($type,$subtype) = explode("-", $qargs);
switch ($type) {
case "ip":
$statement = "SELECT CONCAT_WS('|', INET_NTOA(event.src_ip), msrc.cc, msrc.c_long) AS source,
CONCAT_WS('|', INET_NTOA(event.dst_ip), mdst.cc, mdst.c_long) AS target,
COUNT(event.src_ip) AS value
FROM event
LEFT JOIN mappings AS msrc ON event.src_ip = msrc.ip
LEFT JOIN mappings AS mdst ON event.dst_ip = mdst.ip
$qp2
AND (INET_NTOA(event.src_ip) != '0.0.0.0' AND INET_NTOA(event.dst_ip) != '0.0.0.0')
GROUP BY source,target";
break;
case "ips":
$statement = "SELECT CONCAT_WS('|', INET_NTOA(event.src_ip), msrc.cc, msrc.c_long) AS source,
event.signature AS sig,
CONCAT_WS('|', INET_NTOA(event.dst_ip), mdst.cc, mdst.c_long) AS target,
COUNT(event.src_ip) AS value
FROM event
LEFT JOIN mappings AS msrc ON event.src_ip = msrc.ip
LEFT JOIN mappings AS mdst ON event.dst_ip = mdst.ip
$qp2
AND (INET_NTOA(event.src_ip) != '0.0.0.0' AND INET_NTOA(event.dst_ip) != '0.0.0.0')
GROUP BY source,target";
break;
case "sc":
$statement = "SELECT CONCAT_WS('|' ,msrc.c_long, msrc.cc) AS source,
CONCAT_WS('|',INET_NTOA(event.dst_ip), mdst.cc) AS target,
COUNT(event.src_ip) AS value
FROM event
LEFT JOIN mappings AS msrc ON event.src_ip = msrc.ip
LEFT JOIN mappings AS mdst ON event.dst_ip = mdst.ip
$qp2
AND (INET_NTOA(event.src_ip) != '0.0.0.0' AND INET_NTOA(event.dst_ip) != '0.0.0.0')
AND event.src_ip NOT BETWEEN 167772160 AND 184549375
AND event.src_ip NOT BETWEEN 2886729728 AND 2886795263
AND event.src_ip NOT BETWEEN 3232235520 AND 3232301055
GROUP BY source,target";
break;
case "dc":
$statement = "SELECT CONCAT_WS('|', INET_NTOA(event.src_ip), msrc.cc) AS source,
CONCAT_WS('|', mdst.c_long, mdst.cc) AS target,
COUNT(event.dst_ip) AS value
FROM event
LEFT JOIN mappings AS msrc ON event.src_ip = msrc.ip
LEFT JOIN mappings AS mdst ON event.dst_ip = mdst.ip
$qp2
AND (INET_NTOA(event.src_ip) != '0.0.0.0' AND INET_NTOA(event.dst_ip) != '0.0.0.0')
AND event.dst_ip NOT BETWEEN 167772160 AND 184549375
AND event.dst_ip NOT BETWEEN 2886729728 AND 2886795263
AND event.dst_ip NOT BETWEEN 3232235520 AND 3232301055
GROUP BY source,target";
break;
}
// prepare statement
$query = $dbpdo->prepare("$statement");
// merge params
$merged_params = array_merge($sensor_params, $qp2_params);
// debug
//error_log("statement: $statement");
//error_log("merged_params: " . print_r($merged_params,1));
// execute the prepared statement with the params
$query->execute($merged_params);
// unbuffered query can't do rowCount, replacing with $records below
//$rc = $query->rowCount();
$records = 0;
$rows = $srcs = $tgts = $vals = $skip = $names = $_names = array();
/*
*/
while ($row = $query->fetch(PDO::FETCH_ASSOC)) {
if ($type == "ips") {
$srcs[] = $row["source"];
$tgts[] = $row["sig"];
$vals[] = $row["value"];
$srcs[] = $row["sig"];
$tgts[] = $row["target"];
$vals[] = $row["value"];
} else {
$srcs[] = $row["source"];
$tgts[] = $row["target"];
$vals[] = $row["value"];
}
$sads[] = 0;
$records++;
}
if ($records == 0) {
$theJSON = json_encode(array("nodes" => $names, "links" => $rows, "records" => $records));
echo $theJSON;
exit();
}
// Value counts
$src_c = array_count_values($srcs);
$tgt_c = array_count_values($tgts);
// Accomodate sources that exist as a target with the
// current target as a source (not allowed)
foreach ($srcs as $index => $src) {
// Find the target
if (in_array($index, $skip)) { continue; }
$tgt = $tgts[$index];
// Find the keys for all instances of the target as a source
$tgt_keys = array_keys($srcs,$tgt);
// Now see if any have the source as a target
foreach ($tgt_keys as $pos) {
if ($tgts[$pos] == $src) {
$sads_val = $vals[$pos];
unset($srcs[$pos]);
unset($tgts[$pos]);
unset($vals[$pos]);
unset($sads[$pos]);
// Add offset to be skipped
$skip[] = $pos;
// By setting this we flag that this source is also a target
$sads[$index] = $sads_val;
}
}
// If there is no filter, remove 1:1s with a count of 1
if ($filter == 'empty') {
if ( isset($vals[$index]) && $vals[$index] == 1 && isset($sads[$index]) && $sads[$index] == 0 && isset($src_c[$src]) && $src_c[$src] == 1) {
unset($srcs[$index]);
unset($tgts[$index]);
unset($vals[$index]);
unset($sads[$index]);
}
}
}
// We have probably truncated these so realign the indexes
$srcs = array_slice($srcs, 0);
$tgts = array_slice($tgts, 0);
$vals = array_slice($vals, 0);
$sads = array_slice($sads, 0);
// Create distinct names array
$lc = count($srcs);
for ($i = 0; $i < $lc; $i++) {
if (!in_array($srcs[$i], $_names)) {
$_names[] = $srcs[$i];
}
if (!in_array($tgts[$i], $_names)) {
$_names[] = $tgts[$i];
}
}
// Now go through the results and map the
// sources and targets to the indexes in $_names
for ($i = 0; $i < $lc; $i++) {
// get source index
$skey = array_search($srcs[$i], $_names);
// get target index
$dkey = array_search($tgts[$i], $_names);
$val = (int)$vals[$i];
$sad = (int)$sads[$i];
$rows[] = array("source" => $skey, "target" => $dkey, "value" => $val, "sad" => $sad);
//echo "$skey,$dkey,$val,$sad
";
}
// Lastly, we reformat names
foreach ($_names as $name) {
$names[] = array("name" => $name);
//echo "$name
";
}
$theJSON = json_encode(array("nodes" => $names, "links" => $rows, "records" => $records));
echo $theJSON;
}
function autocat() {
// This function queries and updates sguild's list of autocats.
// This function has been updated to use PDO prepared statements.
global $dbpdo;
$usr = $_SESSION['sUser'];
$pwd = $_SESSION['sPass'];
$offset = $_SESSION['tzoffset'];
$mode = $_REQUEST['mode'];
switch ($mode) {
case "query" :
// build statement
$statement = "SELECT autoid, CONVERT_TZ(erase,'+00:00', :offset1) AS erase, sensorname,
src_ip, src_port, dst_ip, dst_port, ip_proto,
signature, status, active, CONVERT_TZ(timestamp,'+00:00', :offset2) AS ts,
u.username AS user, comment
FROM autocat
LEFT JOIN user_info AS u ON autocat.uid = u.uid
ORDER BY ts DESC";
// debug
//error_log("$statement");
// prepare statement
$query = $dbpdo->prepare("$statement");
// build parameters for prepared statement
$params = [":offset1" => "$offset", ":offset2" => "$offset"];
// execute the prepared statement with the params
$query->execute($params);
// fetch the data and encode to json
$rows = $query->fetchAll(PDO::FETCH_ASSOC);
$theJSON = json_encode($rows);
break;
case "update" :
$data = hextostr($_REQUEST['data']);
$v = json_decode($data, true);
// Is the timestamp freeform?
$pattern = '/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$|^none$/';
$expires = $v['expires'];
if (!preg_match($pattern, $expires)) {
$expires = gmdate("Y-m-d H:i:s", strtotime("+ $expires"));
}
$cmdusr = escapeshellarg($usr);
$cmdexpires = escapeshellarg($expires);
$cmdsensor = escapeshellarg($v['sensor']);
$cmdsrcip = escapeshellarg($v['src_ip']);
$cmdsrcport = escapeshellarg($v['src_port']);
$cmddstip = escapeshellarg($v['dst_ip']);
$cmddstport = escapeshellarg($v['dst_port']);
$cmdproto = escapeshellarg($v['proto']);
$cmdsignature = escapeshellarg($v['signature']);
$cmdstatus = escapeshellarg($v['status']);
$cmdcomment = escapeshellarg($v['comment']);
$cmd = "../.scripts/clicat.tcl 1 $cmdusr $cmdexpires $cmdsensor $cmdsrcip $cmdsrcport $cmddstip $cmddstport $cmdproto $cmdsignature $cmdstatus $cmdcomment";
$descspec = array(0 => array("pipe", "r"), 1 => array("pipe", "w"));
$proc = proc_open($cmd, $descspec, $pipes);
$debug = "Process execution failed";
if (is_resource($proc)) {
fwrite($pipes[0], $pwd);
fclose($pipes[0]);
$debug = fgets($pipes[1]);
fclose($pipes[1]);
}
$result = array("dbg" => htmlspecialchars($debug));
$theJSON = json_encode($result);
break;
case "toggle":
$obj = $_REQUEST['obj'];
$rm = 0;
list($type, $id) = explode("-", $obj);
if ($type == 4) {
$rm = 1;
$type = 3;
}
$cmdtype = escapeshellarg($type);
$cmdusr = escapeshellarg($usr);
$cmdid = escapeshellarg($id);
$cmd = "../.scripts/clicat.tcl $cmdtype $cmdusr $cmdid";
$descspec = array(0 => array("pipe", "r"), 1 => array("pipe", "w"));
$proc = proc_open($cmd, $descspec, $pipes);
$debug = "Process execution failed";
$err = "-";
if (is_resource($proc)) {
fwrite($pipes[0], $pwd);
fclose($pipes[0]);
$debug = fgets($pipes[1]);
fclose($pipes[1]);
}
if ($rm == 1) {
$statement = "DELETE FROM autocat WHERE autoid = :id";
// debug
//error_log("$statement");
// prepare statement
$query = $dbpdo->prepare("$statement");
// build parameters for prepared statement
$params = [":id" => "$id"];
// execute the prepared statement with the params
$query->execute($params);
$result = $query->errorInfo();
$err = "";
// if there was no error, then $result[2] should be null
if ( ! is_null($result[2]) ) {
$err = $result[2];
}
}
$result = array("dbg" => htmlspecialchars($debug),
"err" => htmlspecialchars($err));
$theJSON = json_encode($result);
break;
}
echo $theJSON;
}
function esquery() {
global $clientparams;
$filter = hextostr($_REQUEST['filter']);
$logtype = hextostr($_REQUEST['logtype']);
$timestamp = hextostr($_REQUEST['se']);
$tests = 0;
$msg = "";
// Check timestamps
$pattern = '/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\|\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/';
if (!preg_match($pattern, $timestamp)) {
$tests = 1;
$msg = "Bad time format!";
}
list($start,$end) = explode("|", $timestamp);
$start = strtotime($start) . "000";
$end = strtotime($end) . "000";
$now = strtotime("now") . "000";
if ($start > $end || $start == $end || $start > $now) {
$tests = 1;
$msg = "Bad time logic!";
}
// Bail if ts logic isn't sound
if ($tests == 1) {
$result = array("dbg" => "$msg");
$theJSON = json_encode($result);
echo $theJSON;
exit;
}
$client = new Elasticsearch\Client($clientparams);
$params = array();
$params['size'] = '500';
$params['ignore'] = '400,404';
$json = "{
\"query\": {
\"filtered\": {
\"query\": {
\"query_string\": {
\"query\": \"type:$logtype AND ($filter)\"
}
},
\"filter\": {
\"range\": {
\"timestamp\": {
\"from\": $start,
\"to\": $end
}
}
}
}
},
\"size\": 500,
\"sort\": [{
\"timestamp\": {
\"order\": \"desc\"
}
}]
}";
$params['body'] = $json;
$result = $client->search($params);
/*
if ($result[2] == "e") {
$result = array("dbg" => "Invalid query!");
}
*/
$theJSON = json_encode($result);
echo $theJSON;
}
function addremoveobject() {
// This function adds objects to and removes objects from the object_mappings table.
// This function has been updated to use PDO prepared statements.
global $dbpdo;
$obtype = $_REQUEST['obtype'];
$object = hextostr($_REQUEST['object']);
$value = $_REQUEST['value'];
$op = $_REQUEST['op'];
// For everything but tags we want to replace the existing value
$hash = md5($obtype . $object);
switch ($obtype) {
case "ip_c":
$object = sprintf("%u", ip2long($object));
break;
case "tag":
$object = sprintf("%u", ip2long($object));
$hash = md5($obtype . $object . $value);
break;
}
// Are we adding or removing?
switch ($op) {
case "add":
// If adding object, insert into table.
$statement = "INSERT INTO object_mappings (type,object,value,hash)
VALUES (:obtype1,:object1,:value1,:hash1)
ON DUPLICATE KEY UPDATE
type=:obtype2,object=:object2,value=:value2,hash=:hash2";
// build parameters for prepared statement
$params = [":obtype1" => "$obtype", ":object1" => "$object", ":value1" => "$value", ":hash1" => "$hash", ":obtype2" => "$obtype", ":object2" => "$object", ":value2" => "$value", ":hash2" => "$hash"];
break;
case "rm":
// If removing object, delete from table.
$statement = "DELETE FROM object_mappings WHERE hash = :hash";
// build parameters for prepared statement
$params = [":hash" => "$hash"];
break;
}
// debug
//error_log("$statement");
// prepare statement
$query = $dbpdo->prepare("$statement");
// execute the prepared statement with the params
$query->execute($params);
// check for errors
$result = $query->errorInfo();
$error = "";
// if there was no error, then $result[2] should be null
if ( ! is_null($result[2]) ) {
$error = $result[2];
}
$return = array("msg" => $error);
$theJSON = json_encode($return);
echo $theJSON;
}
function getcolour() {
// This function gets the color mappings from the object_mappings table.
// This function has been updated to use PDO prepared statements.
global $dbpdo;
// build statement
$statement = "SELECT object, value AS colour
FROM object_mappings
WHERE type = 'el_c'";
// debug
//error_log("$statement");
// prepare statement
$query = $dbpdo->prepare("$statement");
// execute the prepared statement
$query->execute();
// fetch the data and encode to json
$rows = $query->fetchAll(PDO::FETCH_ASSOC);
$theJSON = json_encode($rows);
echo $theJSON;
}
function objhistory () {
// This function returns the history for an object over the last 7 days.
// This function has been updated to use PDO prepared statements.
global $offset, $start, $sdate, $sdatetime, $offset, $dbpdo;
$object = hextostr($_REQUEST['object']);
$object = str_replace("aa", "", $object);
// Is object an IP address?
$re = '/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/';
$obtype = 0;
if (preg_match($re, $object)) {
$obtype = 1;
}
switch ($obtype) {
case 0:
$subject = "signature_id = :object";
$statement = "SELECT
DATE(CONVERT_TZ(event.timestamp,'+00:00', :offset1)) AS day,
HOUR(CONVERT_TZ(event.timestamp,'+00:00', :offset2)) AS hour,
COUNT(event.timestamp) AS value
FROM event
WHERE event.timestamp BETWEEN CONVERT_TZ(:sdatetime1,:offset3,'+00:00') - INTERVAL 6 DAY AND CONVERT_TZ(:sdatetime2,:offset4,'+00:00') + INTERVAL 1 DAY
AND signature_id = :object
GROUP BY day,hour
ORDER BY day ASC";
$params = [":offset1" => "$offset", ":offset2" => "$offset", ":sdatetime1" => "$sdatetime", ":offset3" => "$offset", ":sdatetime2" => "$sdatetime", ":offset4" => "$offset", ":object" => "$object"];
break;
case 1:
$subject = "(src_ip = INET_ATON('$object') OR dst_ip = INET_ATON('$object'))";
$statement = "SELECT
DATE(CONVERT_TZ(event.timestamp,'+00:00', :offset1)) AS day,
HOUR(CONVERT_TZ(event.timestamp,'+00:00', :offset2)) AS hour,
COUNT(event.timestamp) AS value
FROM event
WHERE event.timestamp BETWEEN CONVERT_TZ(:sdatetime1,:offset3,'+00:00') - INTERVAL 6 DAY AND CONVERT_TZ(:sdatetime2,:offset4,'+00:00') + INTERVAL 1 DAY
AND (src_ip = INET_ATON(:object1) OR dst_ip = INET_ATON(:object2))
GROUP BY day,hour
ORDER BY day ASC";
$params = [":offset1" => "$offset", ":offset2" => "$offset", ":sdatetime1" => "$sdatetime", ":offset3" => "$offset", ":sdatetime2" => "$sdatetime", ":offset4" => "$offset", ":object1" => "$object", ":object2" => "$object"];
break;
}
$query = $dbpdo->prepare("$statement");
// original used unbuffered query, but that doesn't seem to work with PDO?
//$result = mysql_unbuffered_query($query);
//$query->setAttribute( PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, False );
$query->execute(array_merge($params));
$rows1 = $rows2 = array();
$r1 = $r2 = 0;
while ($row = $query->fetch(PDO::FETCH_ASSOC)) {
$rows1[] = $row;
$r1++;
}
$result = "";
if ($r1 != 0 && $obtype == 1) {
$statement = "SELECT
COUNT(signature_id) AS value,
signature AS label,
signature_id AS sid
FROM event
WHERE event.timestamp BETWEEN CONVERT_TZ(:sdatetime1,:offset1,'+00:00') - INTERVAL 6 DAY AND CONVERT_TZ(:sdatetime2,:offset2,'+00:00') + INTERVAL 1 DAY
AND (src_ip = INET_ATON(:object1) OR dst_ip = INET_ATON(:object2))
GROUP BY signature_id
ORDER BY value DESC";
$params = [":sdatetime1" => "$sdatetime", ":offset1" => "$offset", ":sdatetime2" => "$sdatetime", ":offset2" => "$offset", ":object1" => "$object", ":object2" => "$object"];
// original used unbuffered query, but that doesn't seem to work with PDO?
//$result = mysql_unbuffered_query($query);
//$query->setAttribute( PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, False );
$query = $dbpdo->prepare("$statement");
$query->execute(array_merge($params));
while ($row = $query->fetch(PDO::FETCH_ASSOC)) {
$rows2[] = $row;
$r2++;
}
}
$theJSON = json_encode(array("rows1" => $rows1, "rows2" => $rows2, "start" => $sdate, "r1" => $r1, "r2" => $r2));
echo $theJSON;
}
function times() {
// This function returns data to the times visualization on the EVENTS tab.
// This function has been updated to use PDO prepared statements.
global $offset, $when, $sensors, $qp2, $qp2_params, $sensor_params, $sv, $dbpdo;
$statement = "SELECT
SUBSTRING(CONVERT_TZ(event.timestamp,'+00:00',:substringoffset),12,5) AS time,
COUNT(signature) AS count
FROM event
LEFT JOIN mappings AS msrc ON event.src_ip = msrc.ip
LEFT JOIN mappings AS mdst ON event.dst_ip = mdst.ip
$qp2
GROUP BY time
ORDER BY event.timestamp";
// add params for local part of statement
$local_params[':substringoffset'] = "$offset";
// prepare statement
$query = $dbpdo->prepare("$statement");
// merge params
$merged_params = array_merge($local_params, $sensor_params, $qp2_params);
// debug
//error_log("statement: $statement");
//error_log("merged_params: " . print_r($merged_params,1));
// execute the prepared statement with the params
$query->execute($merged_params);
$rows = array();
$r = $m = 0;
while ($row = $query->fetch(PDO::FETCH_ASSOC)) {
$rows[] = $row;
$cnts[] = $row['count'];
$r++;
}
if ($r > 0) {
$m = max($cnts);
}
$theJSON = json_encode(array("rows" => $rows, "r" => $r, "m" => $m));
echo $theJSON;
}
$type();
unset($rows);
unset($rows1);
unset($result);
unset($theJSON);
?>