Private GIT

Skip to content
Snippets Groups Projects
Commit 03088d2d authored by Kevin Duret's avatar Kevin Duret
Browse files

avoid external command shell injection in comment

parent e583bbe0
Branches
Tags
No related merge requests found
...@@ -47,7 +47,7 @@ require_once _CENTREON_PATH_ . "/www/include/common/common-Func.php"; ...@@ -47,7 +47,7 @@ require_once _CENTREON_PATH_ . "/www/include/common/common-Func.php";
class CentreonExternalCommand { class CentreonExternalCommand {
var $DB; var $DB;
var $cmd_tab; var $cmd_tab = array();
var $poller_tab; var $poller_tab;
var $localhost_tab = array(); var $localhost_tab = array();
var $actions = array(); var $actions = array();
...@@ -94,47 +94,33 @@ class CentreonExternalCommand { ...@@ -94,47 +94,33 @@ class CentreonExternalCommand {
$varlib = _CENTREON_VARLIB_; $varlib = _CENTREON_VARLIB_;
} }
$str_local = "";
$str_remote = ""; $str_remote = "";
$return_local = 0;
$return_remote = 0; $return_remote = 0;
if (count($this->cmd_tab)) {
foreach ($this->cmd_tab as $key => $cmd) { foreach ($this->cmd_tab as $key => $cmd) {
$cmd = str_replace("\"", "", $cmd); $cmd = str_replace("\"", "", $cmd);
$cmd = str_replace("\n", "<br>", $cmd); $cmd = str_replace("\n", "<br>", $cmd);
if (isset($this->localhost_tab[$this->poller_tab[$key]])) { $cmd = "[" . time() . "] " . $cmd . "\n";
$str_local .= "\"[" . time() . "] " . $cmd . "\n\""; $str_remote .= "EXTERNALCMD:" . $this->poller_tab[$key] . ":" . $cmd;
} else {
$str_remote .= "\"EXTERNALCMD:" . $this->poller_tab[$key] . ":[" . time() . "] " . $cmd . "\n\"";
}
}
} }
if ($str_local != "") {
$str_local = "echo " . $str_local . " >> " . $centreon->Nagioscfg["command_file"];
if ($this->debug) {
print "COMMAND BEFORE SEND: $str_local";
}
passthru(trim($str_local), $return_local);
}
if ($str_remote != "") { if ($str_remote != "") {
$str_remote = "echo " . $str_remote . " >> $varlib/centcore.cmd";
if ($this->debug) { if ($this->debug) {
print "COMMAND BEFORE SEND: $str_remote"; print "COMMAND BEFORE SEND: $str_remote";
} }
passthru($str_remote, $return_remote); $result = file_put_contents($varlib . '/centcore.cmd', $str_remote, FILE_APPEND);
$return_remote = ($result !== false) ? 0 : 1;
} }
$this->cmd_tab = array(); $this->cmd_tab = array();
$this->poller_tab = array(); $this->poller_tab = array();
return ($return_local + $return_remote); return $return_remote;
} }
/* /*
* set basic process commands * set basic process commands
*/ */
public function set_process_command($command, $poller) { public function setProcessCommand($command, $poller) {
if ($this->debug) { if ($this->debug) {
print "POLLER: $poller<br>"; print "POLLER: $poller<br>";
print "COMMAND: $command<br>"; print "COMMAND: $command<br>";
...@@ -287,9 +273,94 @@ class CentreonExternalCommand { ...@@ -287,9 +273,94 @@ class CentreonExternalCommand {
return $this->actions; return $this->actions;
} }
/** * ****************************************************
* Downtime /****************
* Schedule check
***************/
/**
* @param $hostName
*/
public function scheduleForcedCheckHost($hostName)
{
$pollerId = $this->getPollerID($hostName);
$this->setProcessCommand(
"SCHEDULE_FORCED_HOST_CHECK;" . $hostName . ";" . time(),
$pollerId
);
$this->write();
}
/**
* @param $hostName
* @param $serviceDescription
*/
public function scheduleForcedCheckService($hostName, $serviceDescription)
{
$pollerId = $this->getPollerID($hostName);
$this->setProcessCommand(
"SCHEDULE_FORCED_SVC_CHECK;" . $hostName . ";" . $serviceDescription . ";" . time(),
$pollerId
);
$this->write();
}
/*****************
* Acknowledgement
****************/
/**
* @param $hostName
* @param $serviceDescription
* @param $sticky
* @param $notify
* @param $persistent
* @param $author
* @param $comment
*/ */
public function acknowledgeHost(
$hostName,
$sticky,
$notify,
$persistent,
$author,
$comment
) {
$pollerId = $this->getPollerID($hostName);
$this->setProcessCommand(
"ACKNOWLEDGE_HOST_PROBLEM;" . $hostName . ";" .
$sticky . ";" . $notify . ";" . $persistent . ";" . $author . ";" . $comment,
$pollerId
);
$this->write();
}
/**
* @param $hostName
* @param $serviceDescription
* @param $sticky
* @param $notify
* @param $persistent
* @param $author
* @param $comment
*/
public function acknowledgeService(
$hostName,
$serviceDescription,
$sticky,
$notify,
$persistent,
$author,
$comment
) {
$pollerId = $this->getPollerID($hostName);
$this->setProcessCommand(
"ACKNOWLEDGE_SVC_PROBLEM;" . $hostName . ";" . $serviceDescription . ";" .
$sticky . ";" . $notify . ";" . $persistent . ";" . $author . ";" . $comment,
$pollerId
);
$this->write();
}
/**********
* Downtime
*********/
/** /**
* *
...@@ -301,27 +372,11 @@ class CentreonExternalCommand { ...@@ -301,27 +372,11 @@ class CentreonExternalCommand {
foreach ($hosts as $key => $value) { foreach ($hosts as $key => $value) {
$res = preg_split("/\;/", $key); $res = preg_split("/\;/", $key);
$poller_id = $this->getPollerID($res[0]); $poller_id = $this->getPollerID($res[0]);
$this->set_process_command("DEL_" . $type . "_DOWNTIME;" . $res[1], $poller_id); $this->setProcessCommand("DEL_" . $type . "_DOWNTIME;" . $res[1], $poller_id);
} }
$this->write(); $this->write();
} }
/**
*
* Get date from string
*
* date format: m/d/Y H:i
* @param string $string
*/
private function getDate($string) {
$res = preg_split("/ /", $string);
$res3 = preg_split("/\//", $res[0]);
$res4 = preg_split("/:/", $res[1]);
$end_time = mktime($res4[0], $res4[1], "0", $res3[0], $res3[1], $res3[2]);
unset($res);
return $end_time;
}
/** /**
* *
* Add a host downtime * Add a host downtime
...@@ -362,9 +417,9 @@ class CentreonExternalCommand { ...@@ -362,9 +417,9 @@ class CentreonExternalCommand {
if (!isset($duration)) { if (!isset($duration)) {
$duration = $start_time - $end_time; $duration = $start_time - $end_time;
} }
$this->set_process_command("SCHEDULE_HOST_DOWNTIME;" . getMyHostName($host) . ";" . $start_time . ";" . $end_time . ";" . $persistant . ";0;" . $duration . ";" . $centreon->user->get_alias() . ";" . $comment, $poller_id); $this->setProcessCommand("SCHEDULE_HOST_DOWNTIME;" . getMyHostName($host) . ";" . $start_time . ";" . $end_time . ";" . $persistant . ";0;" . $duration . ";" . $centreon->user->get_alias() . ";" . $comment, $poller_id);
if ($with_services === true) { if ($with_services === true) {
$this->set_process_command("SCHEDULE_HOST_SVC_DOWNTIME;" . getMyHostName($host) . ";" . $start_time . ";" . $end_time . ";" . $persistant . ";0;" . $duration . ";" . $centreon->user->get_alias() . ";" . $comment, $poller_id); $this->setProcessCommand("SCHEDULE_HOST_SVC_DOWNTIME;" . getMyHostName($host) . ";" . $start_time . ";" . $end_time . ";" . $persistant . ";0;" . $duration . ";" . $centreon->user->get_alias() . ";" . $comment, $poller_id);
} }
$this->write(); $this->write();
} }
...@@ -411,10 +466,7 @@ class CentreonExternalCommand { ...@@ -411,10 +466,7 @@ class CentreonExternalCommand {
if (!isset($duration)) { if (!isset($duration)) {
$duration = $start_time - $end_time; $duration = $start_time - $end_time;
} }
$this->set_process_command("SCHEDULE_SVC_DOWNTIME;" . getMyHostName($host) . ";" . getMyServiceName($service) . ";" . $start_time . ";" . $end_time . ";" . $persistant . ";0;" . $duration . ";" . $centreon->user->get_alias() . ";" . $comment, $poller_id); $this->setProcessCommand("SCHEDULE_SVC_DOWNTIME;" . getMyHostName($host) . ";" . getMyServiceName($service) . ";" . $start_time . ";" . $end_time . ";" . $persistant . ";0;" . $duration . ";" . $centreon->user->get_alias() . ";" . $comment, $poller_id);
$this->write(); $this->write();
} }
} }
\ No newline at end of file
?>
...@@ -15,29 +15,17 @@ ...@@ -15,29 +15,17 @@
* For information : contact@centreon.com * For information : contact@centreon.com
*/ */
if (!isset($oreon)) if (!isset($oreon)) {
exit(); exit();
/** }
*
* Write command in nagios pipe or in centcore pipe.
* @param $cmd
* @param $poller
*/
function write_command($cmd, $poller){
global $oreon, $key, $pearDB;
$str = NULL;
$informations = preg_split("/\;/", $key);
/* Replace forbidden charaters in external command*/
$cmd = str_replace("`", "&#96;", $cmd);
//$cmd = str_replace("'", "&#39;", $cmd);
$cmd = str_replace("\n", "<br>", $cmd); function sanitizeShellString($string)
{
$string = str_replace('\'', ' ', trim(urldecode($string)));
$string = str_replace('`', ' ', $string);
$string = str_replace('$(', '(', $string);
setlocale(LC_CTYPE, 'en_US.UTF-8'); return $string;
$str = "echo ". escapeshellarg("EXTERNALCMD:$poller:[" . time() . "]" . $cmd . "\n") . " >> " . _CENTREON_VARLIB_."/centcore.cmd";
return passthru($str);
} }
/** /**
...@@ -49,41 +37,64 @@ ...@@ -49,41 +37,64 @@
global $pearDB, $is_admin, $oreon; global $pearDB, $is_admin, $oreon;
static $processedHosts = array(); static $processedHosts = array();
$actions = false;
$actions = $oreon->user->access->checkAction("host_acknowledgement"); $actions = $oreon->user->access->checkAction("host_acknowledgement");
$key = urldecode($key); $key = urldecode($key);
$tmp = preg_split("/\;/", $key); $tmp = preg_split("/\;/", $key);
$host_name = $tmp[0]; $hostName = $tmp[0];
if (isset($processedHosts[$host_name])) { if (isset($processedHosts[$hostName])) {
return null; return null;
} }
$processedHosts[$host_name] = true; $processedHosts[$hostName] = true;
isset($_GET['persistent']) && $_GET['persistent'] == "true" ? $persistent = "1" : $persistent = "0"; $persistent = isset($_GET['persistent']) && $_GET['persistent'] == "true" ? "1" : "0";
isset($_GET['notify']) && $_GET['notify'] == "true" ? $notify = "1" : $notify = "0"; $notify = isset($_GET['notify']) && $_GET['notify'] == "true" ? "1" :"0";
isset($_GET['sticky']) && $_GET['sticky'] == "true" ? $sticky = "2" : $sticky = "1"; $sticky = isset($_GET['sticky']) && $_GET['sticky'] == "true" ? "2" : "1";
isset($_GET['force_check']) && $_GET['force_check'] == "true" ? $force_check = "1" : $force_check = "0"; $force_check = isset($_GET['force_check']) && $_GET['force_check'] == "true" ? "1" : "0";
$_GET["comment"] = sanitizeShellString($_GET["comment"]);
$extCmdObj = new CentreonExternalCommand($oreon);
if ($actions == true || $is_admin) { if ($actions == true || $is_admin) {
$host_poller = GetMyHostPoller($pearDB, $host_name); $extCmdObj->acknowledgeHost(
$flg = write_command(" ACKNOWLEDGE_HOST_PROBLEM;".$host_name.";".$sticky.";".$notify.";".$persistent.";".$_GET["author"].";".trim(urldecode($_GET["comment"])), $host_poller); $hostName,
if ($force_check == 1) { $sticky,
write_command(" SCHEDULE_FORCED_HOST_CHECK;".$host_name.";".time(), $host_poller); $notify,
$persistent,
$_GET["author"],
$_GET["comment"]
);
} }
if ($force_check == 1) {
$extCmdObj->scheduleForcedCheckHost(
$hostName
);
} }
$actions = $oreon->user->access->checkAction("service_acknowledgement"); $actions = $oreon->user->access->checkAction("service_acknowledgement");
if (($actions == true || $is_admin) && isset($_GET['ackhostservice']) && $_GET['ackhostservice'] == "true") { if (($actions == true || $is_admin) && isset($_GET['ackhostservice']) && $_GET['ackhostservice'] == "true") {
$DBRES = $pearDB->query("SELECT host_id FROM `host` WHERE host_name = '".$host_name."' LIMIT 1"); $DBRES = $pearDB->query("SELECT host_id FROM `host` WHERE host_name = '".$hostName."' LIMIT 1");
$row = $DBRES->fetchRow(); $row = $DBRES->fetchRow();
$svc_tab = array();
$svc_tab = getMyHostServices($row['host_id']); $svc_tab = getMyHostServices($row['host_id']);
if (count($svc_tab)) { if (count($svc_tab)) {
foreach ($svc_tab as $key2 => $value) { foreach ($svc_tab as $key2 => $value) {
write_command(" ACKNOWLEDGE_SVC_PROBLEM;".$host_name.";".$value.";".$sticky.";".$notify.";".$persistent.";".$_GET["author"].";".trim(urldecode($_GET["comment"])), $host_poller); $extCmdObj->acknowledgeService(
if ($force_check == 1 && $oreon->user->access->checkAction("service_schedule_forced_check") == true) { $hostName,
write_command(" SCHEDULE_FORCED_SVC_CHECK;".$host_name.";".$value.";".time(), $host_poller); $value,
$sticky,
$notify,
$persistent,
$_GET["author"],
$_GET["comment"]
);
if ($force_check == 1 &&
$oreon->user->access->checkAction("service_schedule_forced_check") == true) {
$extCmdObj->scheduleForcedCheckService(
$hostName,
$value
);
} }
} }
} }
...@@ -108,7 +119,6 @@ ...@@ -108,7 +119,6 @@
function massiveServiceAck($key){ function massiveServiceAck($key){
global $pearDB, $is_admin, $oreon; global $pearDB, $is_admin, $oreon;
$actions = false;
$actions = $oreon->user->access->checkAction("service_acknowledgement"); $actions = $oreon->user->access->checkAction("service_acknowledgement");
$key = urldecode($key); $key = urldecode($key);
...@@ -118,12 +128,12 @@ ...@@ -118,12 +128,12 @@
if (!isset($tmp[0])) { if (!isset($tmp[0])) {
throw new Exception('No host found'); throw new Exception('No host found');
} }
$host_name = $tmp[0]; $hostName = $tmp[0];
if (!isset($tmp[1])) { if (!isset($tmp[1])) {
throw new Exception('No service found'); throw new Exception('No service found');
} else { } else {
$svc_description = $tmp[1]; $serviceDescription = $tmp[1];
} }
isset($_GET['persistent']) && $_GET['persistent'] == "true" ? $persistent = "1" : $persistent = "0"; isset($_GET['persistent']) && $_GET['persistent'] == "true" ? $persistent = "1" : $persistent = "0";
...@@ -131,17 +141,25 @@ ...@@ -131,17 +141,25 @@
isset($_GET['sticky']) && $_GET['sticky'] == "true" ? $sticky = "2" : $sticky = "1"; isset($_GET['sticky']) && $_GET['sticky'] == "true" ? $sticky = "2" : $sticky = "1";
isset($_GET['force_check']) && $_GET['force_check'] == "true" ? $force_check = "1" : $force_check = "0"; isset($_GET['force_check']) && $_GET['force_check'] == "true" ? $force_check = "1" : $force_check = "0";
$host_poller = GetMyHostPoller($pearDB, $host_name);
if ($actions == true || $is_admin) { if ($actions == true || $is_admin) {
$_GET["comment"] = sanitizeShellString($_GET["comment"]);
$_GET["comment"] = $_GET["comment"]; $extCmdObj = new CentreonExternalCommand($oreon);
$_GET["comment"] = str_replace('\'', ' ', trim(urldecode($_GET["comment"]))); $extCmdObj->acknowledgeService(
$hostName,
$flg = write_command(" ACKNOWLEDGE_SVC_PROBLEM;".$host_name.";".$svc_description.";".$sticky.";".$notify.";".$persistent.";".$_GET["author"].";".$_GET["comment"], $host_poller); $serviceDescription,
$sticky,
$notify,
$persistent,
$_GET["author"],
$_GET["comment"]
);
if ($force_check == 1 && $oreon->user->access->checkAction("service_schedule_forced_check") == true) { if ($force_check == 1 && $oreon->user->access->checkAction("service_schedule_forced_check") == true) {
write_command(" SCHEDULE_FORCED_SVC_CHECK;".$host_name.";".$svc_description.";".time(), $host_poller); $extCmdObj->scheduleForcedCheckService(
$hostName,
$serviceDescription
);
} }
set_user_param($oreon->user->user_id, $pearDB, "ack_sticky", $sticky); set_user_param($oreon->user->user_id, $pearDB, "ack_sticky", $sticky);
set_user_param($oreon->user->user_id, $pearDB, "ack_notify", $notify); set_user_param($oreon->user->user_id, $pearDB, "ack_notify", $notify);
...@@ -161,10 +179,9 @@ ...@@ -161,10 +179,9 @@
*/ */
function massiveHostDowntime($key) function massiveHostDowntime($key)
{ {
global $pearDB, $is_admin, $oreon, $centreonGMT; global $is_admin, $oreon;
static $processedHosts = array(); static $processedHosts = array();
$actions = false;
$actions = $oreon->user->access->checkAction("host_schedule_downtime"); $actions = $oreon->user->access->checkAction("host_schedule_downtime");
if ($actions == true || $is_admin) { if ($actions == true || $is_admin) {
...@@ -181,13 +198,15 @@ ...@@ -181,13 +198,15 @@
} }
$processedHosts[$host_name] = true; $processedHosts[$host_name] = true;
isset($_GET['start']) && $_GET['start'] ? $start = $_GET['start'] : $start = time(); $start = isset($_GET['start']) && $_GET['start'] ? $_GET['start'] : time();
isset($_GET['end']) && $_GET['end'] ? $end = $_GET['end'] : $end = time(); $end = isset($_GET['end']) && $_GET['end'] ? $_GET['end'] : time();
isset($_GET['comment']) && $_GET['comment'] ? $comment = str_replace('\'', ' ', trim(urldecode($_GET["comment"]))) : $comment = ""; $comment = isset($_GET['comment']) && $_GET['comment'] ? sanitizeShellString($_GET["comment"]) : "";
isset($_GET['fixed']) && $_GET['fixed'] == "true" ? $fixed = 1 : $fixed = 0; $fixed = isset($_GET['fixed']) && $_GET['fixed'] == "true" ? $fixed = 1 : $fixed = 0;
isset($_GET['duration']) && $_GET['duration'] && is_numeric($_GET['duration']) ? $duration = $_GET['duration'] : $duration = 0; $duration = isset($_GET['duration']) && $_GET['duration'] && is_numeric($_GET['duration']) ?
isset($_GET['duration_scale']) && $_GET['duration_scale'] ? $duration_scale = $_GET['duration_scale'] : $duration_scale = "s"; $duration = $_GET['duration'] : $duration = 0;
isset($_GET['host_or_centreon_time']) && $_GET['host_or_centreon_time'] == "true" ? $host_or_centreon_time = "1" : $host_or_centreon_time = "0"; $duration_scale = isset($_GET['duration_scale']) && $_GET['duration_scale'] ?
$duration_scale = $_GET['duration_scale'] : $duration_scale = "s";
$hostTime = isset($_GET['host_or_centreon_time']) && $_GET['host_or_centreon_time'] == "true" ? "1" : "0";
if ($duration > 0) { if ($duration > 0) {
switch ($duration_scale) { switch ($duration_scale) {
...@@ -216,7 +235,7 @@ ...@@ -216,7 +235,7 @@
} }
$extCmdObj = new CentreonExternalCommand($oreon); $extCmdObj = new CentreonExternalCommand($oreon);
$extCmdObj->AddHostDowntime($host, $comment, $start, $end, $fixed, $duration, $with_services,$host_or_centreon_time); $extCmdObj->addHostDowntime($host, $comment, $start, $end, $fixed, $duration, $with_services, $hostTime);
} }
return null; return null;
...@@ -226,9 +245,8 @@ ...@@ -226,9 +245,8 @@
* Sets service downtime massively * Sets service downtime massively
*/ */
function massiveServiceDowntime($key) { function massiveServiceDowntime($key) {
global $pearDB, $is_admin, $oreon, $centreonGMT; global $is_admin, $oreon;
$actions = false;
$actions = $oreon->user->access->checkAction("service_schedule_downtime"); $actions = $oreon->user->access->checkAction("service_schedule_downtime");
if ($actions == true || $is_admin) { if ($actions == true || $is_admin) {
...@@ -246,18 +264,17 @@ ...@@ -246,18 +264,17 @@
$svc_description = $tmp[1]; $svc_description = $tmp[1];
} }
isset($_GET['start']) && $_GET['start'] ? $start = $_GET['start'] : $start = time(); $start = isset($_GET['start']) && $_GET['start'] ? $_GET['start'] : time();
isset($_GET['end']) && $_GET['end'] ? $end = $_GET['end'] : $end = time(); $end = isset($_GET['end']) && $_GET['end'] ? $_GET['end'] : time();
isset($_GET['comment']) && $_GET['comment'] ? $comment = str_replace('\'', ' ', $_GET["comment"]) : $comment = ""; $comment = isset($_GET['comment']) && $_GET['comment'] ? sanitizeShellString($_GET["comment"]) : "";
isset($_GET['fixed']) && $_GET['fixed'] == "true" ? $fixed = 1 : $fixed = 0; $fixed = isset($_GET['fixed']) && $_GET['fixed'] == "true" ? 1 : 0;
isset($_GET['duration']) && $_GET['duration'] && is_numeric($_GET['duration']) ? $duration = $_GET['duration'] : $duration = 0; $duration = isset($_GET['duration']) && $_GET['duration'] && is_numeric($_GET['duration']) ?
isset($_GET['duration_scale']) && $_GET['duration_scale'] ? $duration_scale = $_GET['duration_scale'] : $duration_scale = "s"; $_GET['duration'] : 0;
isset($_GET['host_or_centreon_time']) && $_GET['host_or_centreon_time'] == "true" ? $host_or_centreon_time = "1" : $host_or_centreon_time = "0"; $duration_scale = isset($_GET['duration_scale']) && $_GET['duration_scale'] ? $_GET['duration_scale'] : "s";
$hostTime = isset($_GET['host_or_centreon_time']) && $_GET['host_or_centreon_time'] == "true" ? "1" : "0";
if ($duration > 0) if ($duration > 0) {
{ switch ($duration_scale) {
switch ($duration_scale)
{
default: default:
case 's': case 's':
$duration = $duration; $duration = $duration;
...@@ -281,12 +298,7 @@ ...@@ -281,12 +298,7 @@
$service = getMyServiceID($svc_description, $host); $service = getMyServiceID($svc_description, $host);
$extCmdObj = new CentreonExternalCommand($oreon); $extCmdObj = new CentreonExternalCommand($oreon);
$extCmdObj->AddSvcDowntime($host, $service, $comment, $start, $end, $fixed, $duration, $host_or_centreon_time); $extCmdObj->AddSvcDowntime($host, $service, $comment, $start, $end, $fixed, $duration, $hostTime);
//write_command(" SCHEDULE_SVC_DOWNTIME;".urldecode($host_name).";".urldecode($svc_description).";".$start_time.";".$end_time.";".$fixed.";0;".$duration.";".$oreon->user->get_alias().";".$comment."\n", GetMyHostPoller($pearDB, urldecode($host_name)));
} }
return null; return null;
} }
?>
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment