Skip to content

Commit

Permalink
Remote Command Execution Vulnerability
Browse files Browse the repository at this point in the history
Fixed potential security issue. You need to allow commands via config/allowed_comapps.php
  • Loading branch information
jeanmarc77 committed Jan 14, 2022
1 parent 1922bca commit fb8fbe1
Show file tree
Hide file tree
Showing 5 changed files with 130 additions and 73 deletions.
14 changes: 13 additions & 1 deletion admin/admin_indicator.php
Expand Up @@ -8,6 +8,7 @@

include 'secure.php';
include '../config/config_indicator.php';
include '../config/allowed_comapps.php';
?>
<!DOCTYPE html>
<html>
Expand Down Expand Up @@ -60,7 +61,18 @@
<tr>
<td>Name <input type='text' name='INDNAMEx$ind_num' value='${'INDNAME'.$ind_num}' size=10></td>
<td>ID <input type='text' name='IDx$ind_num' value='${'INDID'.$ind_num}' size=10></td>
<td>Command <input type='text' name='COMMANDx$ind_num' value='${'INDCOMMAND'.$ind_num}' size=25 title='Leave empty to disable'> <input type='submit' name='bntsubmit$ind_num' value='Test command' ";
<td>Command <select name='COMMANDx$ind_num'>";
$cnt = count($ALLWDCMD);

for ($i=0; $i<$cnt; $i++) {
echo "<option value='$ALLWDCMD[$i]'";
if (${'INDCOMMAND'.$ind_num} == $ALLWDCMD[$i]) {
echo ' SELECTED';
}
echo ">$ALLWDCMD[$i]</option>";
}
echo "<option value=''>disable</option></select>
<input type='submit' name='bntsubmit$ind_num' value='Test command' ";
if (file_exists('../scripts/metern.pid')) {
echo "onclick=\"if(!confirm('meterN will be stopped for this test, continue ?')){return false;}\"";
}
Expand Down
38 changes: 20 additions & 18 deletions admin/admin_indicator2.php
Expand Up @@ -9,6 +9,7 @@
include 'secure.php';
include "../scripts/datasets/$DATASET.php";
include '../scripts/version.php';
include '../config/allowed_comapps.php';
?>
<!DOCTYPE html>
<html>
Expand Down Expand Up @@ -54,7 +55,7 @@
} else {
$IDx = '';
}
if (!empty($_POST["COMMANDx$ind_num"]) && is_string($_POST["COMMANDx$ind_num"])) {
if (!empty($_POST["COMMANDx$ind_num"]) && is_string($_POST["COMMANDx$ind_num"]) && in_array($_POST["COMMANDx$ind_num"], $ALLWDCMD)) {
$COMMANDx = htmlspecialchars($_POST["COMMANDx$ind_num"], ENT_QUOTES, 'UTF-8');
} else {
$COMMANDx = '';
Expand All @@ -69,25 +70,26 @@
$command = exec("kill -9 $pid > /dev/null 2>&1 &");
unlink('../scripts/metern.pid');
}
exec("$COMMANDx 2>&1", $datareturn);
$datareturn = trim(implode($datareturn));
$val = isvalid($IDx, $datareturn);
if (isset($val)) {
echo "
<br><div align=center>$datareturn <font color='#228B22'><b>is a valid entry !</b></font>
";
} else {
$COMMANDx = htmlentities($COMMANDx);
if (empty($datareturn)) {
$datareturn = 'null';
}
echo "
<br><div align=center><b>Command :</b> $COMMANDx <br><br>$datareturn <font color='#8B0000'><b>is not valid</b></font>";
if ($DATASET=='IEC62056') {
echo ", the correct format is $IDx(1234.5*$UNITx)";
echo '<br><div align=center>';
if (in_array($COMMANDx, $ALLWDCMD)) {
exec("$COMMANDx 2>&1", $datareturn);
$datareturn = trim(implode($datareturn));
$val = isvalid($IDx, $datareturn);
if (isset($val)) {
echo "$datareturn <font color='#228B22'><b>is a valid entry !</b></font>>";
} else {
$COMMANDx = htmlentities($COMMANDx);
if (empty($datareturn)) {
$datareturn = 'null';
}
echo "<b>Command :</b> $COMMANDx <br><br>$datareturn <font color='#8B0000'><b>is not valid</b></font>";
if ($DATASET=='IEC62056') {
echo ", the correct format is $IDx(1234.5*$UNITx)";
}
}
} else {
echo "<b>Command :</b> $COMMANDx is set to disable or is not permitted. If so, manually complete config/allowed_comapps.php";
}

}
}

Expand Down
29 changes: 25 additions & 4 deletions admin/admin_meter.php
Expand Up @@ -6,7 +6,8 @@
*/


include 'secure.php'
include 'secure.php';
include '../config/allowed_comapps.php';
?>
<!DOCTYPE html>
<html>
Expand Down Expand Up @@ -104,6 +105,8 @@
} else {
$prodconsu = 'it';
}
$cnta = count($ALLWDCMD);

echo "
<div align=center><form action='admin_meter2.php' method='post'>
<fieldset style='width:80%;'>
Expand All @@ -112,7 +115,7 @@
<table border=0 cellspacing=5 cellpadding=0 width='100%' align='center'>
<tr><td colspan=4><b>Specs :</b></td></tr>
<tr><td>Short description name <input type='text' name='METNAMEx' value='${'METNAME'.$met_num}' size=10></td>
<td>Color <input type='text' class=\"jscolor\" name='COLORx' value='${'COLOR'.$met_num}' maxlength=6 size=6></td>
<td>Color <input data-jscolor='{hash:false}' name='COLORx' value='${'COLOR'.$met_num}' maxlength=6 size=6></td>
<td>Type
<select name='TYPEx' onchange='this.form.submit()'>";
$TYPE_array = array(
Expand Down Expand Up @@ -177,7 +180,16 @@
<tr><td colspan=6><b>Main 5min pooling :</b></td></tr>
<tr><td>
Meter ID <input type='text' name='IDx' value='${'ID'.$met_num}' required size=10>
<td>Command <input type='text' name='COMMANDx' value='${'COMMAND'.$met_num}' size=25 required title='This command should return a quantity value (e.g.: Watts per hour)'> <input type='submit' name='bntsubmit' value='Test command' ";
<td>Command <select name='COMMANDx'>";
for ($i=0; $i<$cnta; $i++) {
echo "<option value='$ALLWDCMD[$i]'";
if (${'COMMAND'.$met_num} == $ALLWDCMD[$i]) {
echo ' SELECTED';
}
echo ">$ALLWDCMD[$i]</option>";
}
echo "<option value=''>disable</option></select>
<input type='submit' name='bntsubmit' value='Test command' ";
if (file_exists('../scripts/metern.pid')) {
echo "onclick=\"if(!confirm('meterN will be stopped for this test, continue ?')){return false;}\"";
}
Expand Down Expand Up @@ -217,7 +229,16 @@
<tr><td>
Meter ID <input type='text' name='LIDx' value='${'LID'.$met_num}' size=10>
</td>
<td>Live command <input type='text' name='LIVECOMMANDx' value='${'LIVECOMMAND'.$met_num}' size=25 title='Leave empty to disable'> <input type='submit' name='bntsubmit' value='Test live command' ";
<td>Live command <select name='LIVECOMMANDx'>";
for ($i=0; $i<$cnta; $i++) {
echo "<option value='$ALLWDCMD[$i]'";
if (${'LIVECOMMAND'.$met_num} == $ALLWDCMD[$i]) {
echo ' SELECTED';
}
echo ">$ALLWDCMD[$i]</option>";
}
echo "<option value=''>disable</option></select>
<input type='submit' name='bntsubmit' value='Test live command'";
if (file_exists('../scripts/metern.pid')) {
echo "onclick=\"if(!confirm('meterN will be stopped for this test, continue ?')){return false;}\"";
}
Expand Down
95 changes: 45 additions & 50 deletions admin/admin_meter2.php
Expand Up @@ -9,6 +9,7 @@
include 'secure.php';
include '../scripts/version.php';
include "../scripts/datasets/$DATASET.php";
include '../config/allowed_comapps.php';
?>
<!DOCTYPE html>
<html>
Expand Down Expand Up @@ -66,7 +67,7 @@
} else {
$IDx = '';
}
if (!empty($_POST['COMMANDx']) && is_string($_POST['COMMANDx'])) {
if (!empty($_POST['COMMANDx']) && is_string($_POST['COMMANDx']) && in_array($_POST['COMMANDx'], $ALLWDCMD)) {
$COMMANDx = htmlspecialchars($_POST['COMMANDx'], ENT_QUOTES, 'UTF-8');
} else {
$COMMANDx = '';
Expand Down Expand Up @@ -105,7 +106,7 @@
} else {
$LIDx = '';
}
if (!empty($_POST['LIVECOMMANDx']) && is_string($_POST['LIVECOMMANDx'])) {
if (!empty($_POST['LIVECOMMANDx']) && is_string($_POST['LIVECOMMANDx']) && in_array($_POST['LIVECOMMANDx'], $ALLWDCMD)) {
$LIVECOMMANDx = htmlspecialchars($_POST['LIVECOMMANDx'], ENT_QUOTES, 'UTF-8');
} else {
$LIVECOMMANDx = '';
Expand Down Expand Up @@ -175,8 +176,6 @@ function testemail($adress) {
else
return 'false';
}


$Err = 'false';

if ($bntsubmit == "Test mail") {
Expand Down Expand Up @@ -270,64 +269,60 @@ function testemail($adress) {
unlink('../scripts/metern.pid');
usleep(500000);
}
exec("$COMMANDx 2>&1", $datareturn);
$datareturn = trim(implode($datareturn));
$val = isvalid($IDx, $datareturn);
if (isset($val) && is_numeric($val)) {
echo "
<br><div align=center>$datareturn <font color='#228B22'><b>is a valid entry !</b></font>
<br>
<br>
<INPUT TYPE='button' onClick=\"location.href='admin_meter.php?met_num=$met_numx'\" value='Back'>
</div>";
} else {
$COMMANDx = htmlentities($COMMANDx);
if (empty($datareturn)) {
$datareturn = 'null';
}
echo "
<br><div align=center><b>Command :</b> $COMMANDx <br><br>$datareturn <font color='#8B0000'><b>is not valid</b></font>";
if ($DATASET=='IEC62056') {
echo ", the correct format is $IDx(1234.5*$UNITx)";
echo '<br><div align=center>';
if (in_array($COMMANDx, $ALLWDCMD)) {
exec("$COMMANDx 2>&1", $datareturn);
$datareturn = trim(implode($datareturn));
$val = isvalid($IDx, $datareturn);

if (isset($val) && is_numeric($val)) {
echo "<br><div align=center>$datareturn <font color='#228B22'><b>is a valid entry !</b></font>";
} else {
$COMMANDx = htmlentities($COMMANDx);
if (empty($datareturn)) {
$datareturn = 'null';
}
echo "<br><div align=center><b>Command :</b> $COMMANDx <br><br>$datareturn <font color='#8B0000'><b>is not valid</b></font>";
if ($DATASET=='IEC62056') {
echo ", the correct format is $IDx(1234.5*$UNITx)";
}
}
} else {
echo "<b>Command :</b> $COMMANDx is set to disable or is not permitted. If so, manually complete config/allowed_comapps.php";
}
echo "
<br>
<br>
<INPUT TYPE='button' onClick=\"location.href='admin_meter.php?met_num=$met_numx'\" value='Back'>
</div>";
}
echo "<br><br><INPUT TYPE='button' onClick=\"location.href='admin_meter.php?met_num=$met_numx'\" value='Back'></div>";
} elseif ($bntsubmit == "Test live command") {
if (file_exists('../scripts/metern.pid')) {
$pid = (int) file_get_contents('../scripts/metern.pid');
$command = exec("kill -9 $pid > /dev/null 2>&1 &");
unlink('../scripts/metern.pid');
}
exec("$LIVECOMMANDx 2>&1", $datareturn);
$datareturn = trim(implode($datareturn));
$val = isvalid($LIDx, $datareturn);
if (isset($val)) {
echo "
<br><div align=center>$datareturn <font color='#228B22'><b>is a valid entry !</b></font>
<br>
<br>
<INPUT TYPE='button' onClick=\"location.href='admin_meter.php?met_num=$met_numx'\" value='Back'>
</div>";
} else {
$LIVECOMMANDx = htmlentities($LIVECOMMANDx);
if (empty($datareturn)) {
$datareturn = 'null';
}
echo "
<br><div align=center><b>Command</b> : $LIVECOMMANDx <br><br>$datareturn <font color='#8B0000'><b>is not valid</b></font>";
if ($DATASET=='IEC62056') {
echo ", the correct format is $LIDx(1234.5*$LIVEUNITx)";
echo '<br><div align=center>';
if (in_array($LIVECOMMANDx, $ALLWDCMD)) {
exec("$LIVECOMMANDx 2>&1", $datareturn);
$datareturn = trim(implode($datareturn));
$val = isvalid($LIDx, $datareturn);
if (isset($val)) {
echo "$datareturn <font color='#228B22'><b>is a valid entry !</b></font>";
} else {
$LIVECOMMANDx = htmlentities($LIVECOMMANDx);
if (empty($datareturn)) {
$datareturn = 'null';
}
echo "<b>Command</b> : $LIVECOMMANDx <br><br>$datareturn <font color='#8B0000'><b>is not valid</b></font>";
if ($DATASET=='IEC62056') {
echo ", the correct format is $LIDx(1234.5*$LIVEUNITx)";
}
}
} else {
echo "<b>Command :</b> $LIVECOMMANDx is set to disable or is not permitted. If so, manually complete config/allowed_comapps.php";
}
echo "
<br>
<br>
<INPUT TYPE='button' onClick=\"location.href='admin_meter.php?met_num=$met_numx'\" value='Back'>
</div>";
}
</div>";

} else {
if (!testemail($EMAILx)) {
echo "EMAIL is not correct<br>";
Expand Down
27 changes: 27 additions & 0 deletions config/allowed_comapps.php
@@ -0,0 +1,27 @@
<?php
// For safety reason, manually complete this data array to permit mN to use those commands
// Keep 'http' user file permission

$ALLWDCMD[0] = 'houseenergy -energy';
$ALLWDCMD[1] = 'houseenergy -power';
$ALLWDCMD[2] = 'pooler -gas';
$ALLWDCMD[3] = 'poolmeters gs';
$ALLWDCMD[4] = 'pooler -water';
$ALLWDCMD[5] = 'poolmeters ws';
$ALLWDCMD[6] = 'pool123s -energy';
$ALLWDCMD[7] = 'pool123s -power';
$ALLWDCMD[8] = 'houseenergy -eimp';
$ALLWDCMD[9] = 'houseenergy -powerimp';
$ALLWDCMD[10] = 'houseenergy -eexp';
$ALLWDCMD[11] = 'houseenergy -powerexp';
$ALLWDCMD[12] = 'houseenergy -self';
$ALLWDCMD[13] = 'houseenergy -powerself';
$ALLWDCMD[14] = 'houseenergy -volt';
$ALLWDCMD[15] = 'houseenergy -frq';
$ALLWDCMD[16] = 'houseenergy -cos';
$ALLWDCMD[17] = 'meterud -energy';
//$ALLWDCMD[18] = '';
//$ALLWDCMD[19] = '';
//$ALLWDCMD[20] = '';

?>

0 comments on commit fb8fbe1

Please sign in to comment.