From 8880793278c39e8e39c4461d3def3ecf81ef73be Mon Sep 17 00:00:00 2001 From: Mr_Moose Date: Fri, 15 Apr 2016 12:02:27 +0200 Subject: [PATCH 1/6] security: validate screen session before proceed Validate the connection to the screen session, if it fails we simply kill the page and return to home instead of giving the user full shell access to whatever user is logged in over ssh. --- utilitiesrcontool.php | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/utilitiesrcontool.php b/utilitiesrcontool.php index 72e15e58..3c14497c 100644 --- a/utilitiesrcontool.php +++ b/utilitiesrcontool.php @@ -240,6 +240,15 @@ // We retrieve screen contents $ssh->write("screen -R ".$session."\n"); $ssh->setTimeout(1.1); + + if (!$session || $session == '') + { + $_SESSION['msg1'] = T_('Connection Error!'); + $_SESSION['msg2'] = T_('The server is not running and it may have crashed! Use "reboot" to re-start'); + $_SESSION['msg-type'] = 'error'; + header( 'Location: index.php' ); + die(); + } @$ansi->appendString($ssh->read()); $screenContents = htmlspecialchars_decode(strip_tags($ansi->getScreen())); @@ -351,4 +360,4 @@ function refreshConsole() include("./bootstrap/footer.php"); -?> \ No newline at end of file +?> From f6728cfc1d1a1a5e6b31acc2a3157a985ead5dff Mon Sep 17 00:00:00 2001 From: Mr_Moose Date: Fri, 15 Apr 2016 12:04:34 +0200 Subject: [PATCH 2/6] security: validate screen session before proceed This will kill the SSH shell if it fails to connect to screen --- utilitiesrcontoolprocess.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/utilitiesrcontoolprocess.php b/utilitiesrcontoolprocess.php index 927e1d15..43e78743 100644 --- a/utilitiesrcontoolprocess.php +++ b/utilitiesrcontoolprocess.php @@ -130,6 +130,10 @@ // We retrieve screen name ($session) $session = $ssh->exec( "screen -ls | awk '{ print $1 }' | grep '^[0-9]*\.".$server['screen']."$'"."\n" ); $session = trim($session); + + if (!$session || $session == '') { + die(); + } // We retrieve screen contents $ssh->write("screen -R ".$session."\n"); @@ -169,4 +173,4 @@ -?> \ No newline at end of file +?> From 2badf75b4dba585b525a38a692a19bd0897218ed Mon Sep 17 00:00:00 2001 From: Mr_Moose Date: Fri, 15 Apr 2016 12:06:07 +0200 Subject: [PATCH 3/6] security: validate screen session before proceed This will kill the SSH shell if it fails to connect to screen --- admin/utilitiesrcontool.php | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/admin/utilitiesrcontool.php b/admin/utilitiesrcontool.php index 7653033a..acfc91b6 100644 --- a/admin/utilitiesrcontool.php +++ b/admin/utilitiesrcontool.php @@ -240,6 +240,15 @@ $ssh->write("screen -R ".$session."\n"); $ssh->setTimeout(1.1); + if (!$session || $session == '') + { + $_SESSION['msg1'] = T_('Connection Error!'); + $_SESSION['msg2'] = T_('The server is not running and it may have crashed! Use "reboot" to re-start'); + $_SESSION['msg-type'] = 'error'; + header( 'Location: index.php' ); + die(); + } + @$ansi->appendString($ssh->read()); $screenContents = htmlspecialchars_decode(strip_tags($ansi->getScreen())); @@ -350,4 +359,4 @@ function refreshConsole() include("./bootstrap/footer.php"); -?> \ No newline at end of file +?> From fa92dfee5390a499fd7277c02ba0b91de91cfd91 Mon Sep 17 00:00:00 2001 From: Mr_Moose Date: Mon, 18 Apr 2016 15:11:53 +0200 Subject: [PATCH 4/6] security: escape user input to avoid shell access This is a critical vulnerability, assume a user enter this: '"; rm -rf #' and bam, the entire file system for the ssh user is deleted. If it's root then the entire server is removed. --- utilitiesrcontool.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/utilitiesrcontool.php b/utilitiesrcontool.php index 3c14497c..a4487b78 100644 --- a/utilitiesrcontool.php +++ b/utilitiesrcontool.php @@ -216,15 +216,15 @@ $ansi = new File_ANSI(); // We retrieve screen name ($session) - $session = $ssh->exec( "screen -ls | awk '{ print $1 }' | grep '^[0-9]*\.".$server['screen']."$'"."\n" ); + $session = $ssh->exec( "screen -ls | awk '{ print $1 }' | grep '^[0-9]*\.".escapeshellcmd($server['screen'])."$'"."\n" ); $session = trim($session); if (!empty($_GET['cmd'])) { - $cmdRcon = $_GET['cmd']; + $cmdRcon = escapeshellcmd($_GET['cmd']); // We prepare and we send the command into the screen - $cmd = "screen -S ".$session." -p 0 -X stuff \"".$cmdRcon."\"`echo -ne '\015'`"; + $cmd = "screen -S ".escapeshellcmd($session)." -p 0 -X stuff \"".$cmdRcon."\"`echo -ne '\015'`"; $ssh->exec($cmd."\n"); unset($cmd); From 94dc96469068fea79421943b461695398fcb5497 Mon Sep 17 00:00:00 2001 From: Mr_Moose Date: Mon, 18 Apr 2016 21:30:52 +0200 Subject: [PATCH 5/6] security: escape all shell commands modifieable by users Simply sending a command like: "; mkdir hello_world # into rcon tool could bypass the screen and create a folder in the shell if shell commands aren't escaped properly. --- admin/utilitiesrcontool.php | 20 +++++++++---------- admin/utilitiesrcontoolprocess.php | 18 +++-------------- utilitiesrcontool.php | 32 ++++++++++++++++-------------- utilitiesrcontoolprocess.php | 14 +++++-------- 4 files changed, 35 insertions(+), 49 deletions(-) diff --git a/admin/utilitiesrcontool.php b/admin/utilitiesrcontool.php index acfc91b6..5342ee08 100644 --- a/admin/utilitiesrcontool.php +++ b/admin/utilitiesrcontool.php @@ -215,12 +215,12 @@ $ansi = new File_ANSI(); // We retrieve screen name ($session) - $session = $ssh->exec( "screen -ls | awk '{ print $1 }' | grep '^[0-9]*\.".$server['screen']."$'"."\n" ); + $session = $ssh->exec( "screen -ls | awk '{ print $1 }' | grep '^[0-9]*\.".escapeshellcmd($server['screen'])."$'"."\n" ); $session = trim($session); if (!empty($_GET['cmd'])) { - $cmdRcon = $_GET['cmd']; + $cmdRcon = escapeshellcmd($_GET['cmd']); // We prepare and we send the command into the screen $cmd = "screen -S ".$session." -p 0 -X stuff \"".$cmdRcon."\"`echo -ne '\015'`"; @@ -248,14 +248,13 @@ header( 'Location: index.php' ); die(); } - + @$ansi->appendString($ssh->read()); $screenContents = htmlspecialchars_decode(strip_tags($ansi->getScreen())); $ssh->disconnect(); unset($session); - include("./bootstrap/header.php"); @@ -279,14 +278,15 @@ // Output foreach ($rowsTable as $key => $value) { - echo htmlentities($value, ENT_QUOTES); + if (isset($value) && trim($value) != '') + echo htmlentities($value, ENT_QUOTES); } ?>
-
+
: @@ -336,16 +336,16 @@ function refreshConsole() $( "#ajaxicon" ).html( '' ); }, error: function(jqXHR, textStatus, errorThrown) { - $( "#console" ).html( 'Loading...' ); + //$( "#console" ).html( 'Loading...' ); } }); } var refreshId = setInterval( function() { - $( "#ajaxicon" ).html( "loading... Loading..." ); + //$( "#ajaxicon" ).html( "loading... Loading..." ); refreshConsole(); - }, 5000 ); + }, 10000 ); }); +?> \ No newline at end of file diff --git a/admin/utilitiesrcontoolprocess.php b/admin/utilitiesrcontoolprocess.php index 26059ffb..e1d57b51 100644 --- a/admin/utilitiesrcontoolprocess.php +++ b/admin/utilitiesrcontoolprocess.php @@ -121,7 +121,7 @@ $ansi = new File_ANSI(); // We retrieve screen name ($session) - $session = $ssh->exec( "screen -ls | awk '{ print $1 }' | grep '^[0-9]*\.".$server['screen']."$'"."\n" ); + $session = $ssh->exec( "screen -ls | awk '{ print $1 }' | grep '^[0-9]*\.".escapeshellcmd($server['screen'])."$'"."\n" ); $session = trim($session); // We retrieve screen contents @@ -134,32 +134,20 @@ $ssh->disconnect(); unset($session); - -?> - - $value) { - echo htmlentities($value, ENT_QUOTES); + if (isset($value) && trim($value) != '' && !preg_match('/> - - \ No newline at end of file diff --git a/utilitiesrcontool.php b/utilitiesrcontool.php index a4487b78..4c30b9fc 100644 --- a/utilitiesrcontool.php +++ b/utilitiesrcontool.php @@ -218,6 +218,16 @@ // We retrieve screen name ($session) $session = $ssh->exec( "screen -ls | awk '{ print $1 }' | grep '^[0-9]*\.".escapeshellcmd($server['screen'])."$'"."\n" ); $session = trim($session); + + //Validate session before executing any commands + if (!$session || $session == '') + { + $_SESSION['msg1'] = T_('Connection Error!'); + $_SESSION['msg2'] = T_('The server is not running and it may have crashed! Use "reboot" to re-start'); + $_SESSION['msg-type'] = 'error'; + header( 'Location: index.php' ); + die(); + } if (!empty($_GET['cmd'])) { @@ -239,16 +249,7 @@ // We retrieve screen contents $ssh->write("screen -R ".$session."\n"); - $ssh->setTimeout(1.1); - - if (!$session || $session == '') - { - $_SESSION['msg1'] = T_('Connection Error!'); - $_SESSION['msg2'] = T_('The server is not running and it may have crashed! Use "reboot" to re-start'); - $_SESSION['msg-type'] = 'error'; - header( 'Location: index.php' ); - die(); - } + $ssh->setTimeout(3); @$ansi->appendString($ssh->read()); $screenContents = htmlspecialchars_decode(strip_tags($ansi->getScreen())); @@ -280,7 +281,8 @@ // Output foreach ($rowsTable as $key => $value) { - echo htmlentities($value, ENT_QUOTES); + if (isset($value) && trim($value) != '') + echo htmlentities($value, ENT_QUOTES); } ?> @@ -337,16 +339,16 @@ function refreshConsole() $( "#ajaxicon" ).html( '' ); }, error: function(jqXHR, textStatus, errorThrown) { - $( "#console" ).html( 'Loading...' ); + //$( "#console" ).html( 'Loading...' ); } }); } var refreshId = setInterval( function() { - $( "#ajaxicon" ).html( "loading... Loading..." ); + //$( "#ajaxicon" ).html( "loading... Loading..." ); refreshConsole(); - }, 5000 ); + }, 10000 ); }); +?> \ No newline at end of file diff --git a/utilitiesrcontoolprocess.php b/utilitiesrcontoolprocess.php index 43e78743..cea9a3af 100644 --- a/utilitiesrcontoolprocess.php +++ b/utilitiesrcontoolprocess.php @@ -128,7 +128,7 @@ $ansi = new File_ANSI(); // We retrieve screen name ($session) - $session = $ssh->exec( "screen -ls | awk '{ print $1 }' | grep '^[0-9]*\.".$server['screen']."$'"."\n" ); + $session = $ssh->exec( "screen -ls | awk '{ print $1 }' | grep '^[0-9]*\.".escapeshellcmd($server['screen'])."$'"."\n" ); $session = trim($session); if (!$session || $session == '') { @@ -137,7 +137,7 @@ // We retrieve screen contents $ssh->write("screen -R ".$session."\n"); - $ssh->setTimeout(1.1); + $ssh->setTimeout(2); @$ansi->appendString($ssh->read()); $screenContents = htmlspecialchars_decode(strip_tags($ansi->getScreen())); @@ -145,18 +145,14 @@ $ssh->disconnect(); unset($session); - -?> - - $value) { - echo htmlentities($value, ENT_QUOTES); + if (isset($value) && trim($value) != '') + echo str_replace('\n', '', htmlentities($value, ENT_QUOTES)); } ?> @@ -173,4 +169,4 @@ -?> +?> \ No newline at end of file From 4d8ce7b07d4be537206f34ae362a5ef712d2dde9 Mon Sep 17 00:00:00 2001 From: Mr_Moose Date: Mon, 18 Apr 2016 21:32:25 +0200 Subject: [PATCH 6/6] update: moving to mysqli php mysql is deprecated and needs to be replaced in order to work in the future. --- includes/mysql.php | 39 ++++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/includes/mysql.php b/includes/mysql.php index ee2cd6d0..9e5254e8 100644 --- a/includes/mysql.php +++ b/includes/mysql.php @@ -34,19 +34,17 @@ exit('Access Denied'); } - - $connection = mysql_connect(DBHOST, DBUSER, DBPASSWORD); // Connection to database if (!$connection) // Return error if connection is broken { - exit("Critical Error!!!
MySQL Error!"); + exit("

Database maintenance

Please check back later

"); } $db_connection = mysql_select_db(DBNAME); // Select our database if (!$db_connection) // Return error if error happened with database { - exit("Critical Error!!!
MySQL Error!"); + exit("

Database maintenance

Please check back later

"); } @@ -56,16 +54,19 @@ * * Used for INSERT INTO - UPDATE - DELETE requests. * - * No return. + * Return true on success */ -function query_basic($query) -{ - $result = mysql_query($query); +function query_basic($query) { + $conn = mysqli_connect(DBHOST, DBUSER, DBPASSWORD, DBNAME); + $result = mysqli_query($conn, $query); if ($result == FALSE) { - $msg = 'Invalid query : '.mysql_error()."\n"; + $msg = 'Invalid query : '.mysqli_error($conn)."\n"; echo $msg; + return FALSE; } + else + return TRUE; } /** @@ -73,15 +74,15 @@ function query_basic($query) * * Retrieves the number of rows from a result set and return it. */ -function query_numrows($query) -{ - $result = mysql_query($query); +function query_numrows($query) { + $conn = mysqli_connect(DBHOST, DBUSER, DBPASSWORD, DBNAME); + $result = mysqli_query($conn, $query); if ($result == FALSE) { - $msg = 'Invalid query : '.mysql_error()."\n"; + $msg = 'Invalid query : '.mysqli_error($conn)."\n"; echo $msg; } - return (mysql_num_rows($result)); + return (mysqli_num_rows($result)); } /** @@ -89,14 +90,14 @@ function query_numrows($query) * * Returns an associative array that corresponds to the fetched row. */ -function query_fetch_assoc($query) -{ - $result = mysql_query($query); +function query_fetch_assoc($query) { + $conn = mysqli_connect(DBHOST, DBUSER, DBPASSWORD, DBNAME); + $result = mysqli_query($conn, $query); if ($result == FALSE) { - $msg = 'Invalid query : '.mysql_error()."\n"; + $msg = 'Invalid query : '.mysqli_error($conn)."\n"; echo $msg; } - return (mysql_fetch_assoc($result)); + return mysqli_fetch_assoc($result); } ?> \ No newline at end of file