jueves, agosto 28, 2008

Asegurando un servidor con PHP

php

1. Introducción.

Hay muchas personas y administradores que dejan la instalación PHP por default, es decir, no tocan nada de php.ini, cosa que compromete de una manera grave la seguridad, tanto del servidor en sí, como de los usuarios y obviamente, la información que se trate.

Y viendolo desde el lado del prestigio del servidor puede acarrear problemas, tanto con otros servidores como con la misma blacklist*. Pues programar una herramienta que verifique puertos abiertos, cheque la versión del httpd server y sus extenciones, hasta la compilación de un exploit no es dificil pues hay funciones que practicamente nos dan una shell aunque no se tenga acceso por ssh o telnet.

Como debes saber, lo que aquí explicaré aplica para la mayoría (si no es que todas) las plataformas en las que PHP esta, hasta la fecha, portado. Y sólo como referencia les menciono las condiciones del equipo en las que se trabajó:

Sistema Operativo: OpenBSD 3.2
Versión de Apache: 1.3.29
Versión de PHP: 4.0.5

Mi servidor vecino más pronto en el que apliqué también estas opciones de configuración cuenta con estas caracterizticas:

Sistema Operativo: Microsoft Windows ME
Versión de Apache: 1.3.14
Versión de PHP: 4.0.5

Sin duda grandes diferencias, pero lo cierto es que los importante aquí no es la estructura y componenete en sí del servidor, si no de php y la manera en la que este configurado.

En algunas plataformas se corren mas riesgos que en otras, por ejemplo, en Windows, es mas peligroso ejecutar un ‘del’ que un ‘rm’ en unix.

2. Scripts mal intensionados.

Una mala configuración de PHP puede, como ya comente, significar una grave falla de seguridad en nuestro sistema, ya que cualquier persona con acceso y permiso para escribir o subir aplicaciones dentro del servidor puede jugar de muchas maneras con la información y comprometer al sistema.

Veamos un caso típico de una función peligrosa.

comandos.php

system(”ls -l”);

?>

Como podras imaginar, la función system(); ejecutar una orden en el sistema, o sea, un comando. En el ejemplo se listaría el directorío en el que se esta ejecutando el programa. Por que no probamos listar otro directorio, /homa, por ejemplo.

comandos.php

system(”ls /home”);

?>

Eso nos daría, literalmente, los nombres de todos los usuarios existentes en el sistema (que tengan su directorio en /home, claro). Y ya tendras la idea de lo que pasaría si se lanza un ‘del’ en un sistema Windows.

Existe otra forma de conseguir acceso al interprete de comandos

Puede estar desactivada/bloqueada la función system();, pero aún quedan las comillas invertidas.

comandos.php

$comando=`ls /home`;

echo $comando;

?>

Eso, si system(); llegará a fallar, también lanza la orden al shell.

Lo anterior expone la integridad del servidor, ahora veamos como se puede comprometer un sistema de manera ‘etica’, es decir, ejecutando acciones hacia otras maquinas en internet que se puedan mal interpretar, y claro, puedan ser mal intensionadas.

puertos.php

$puerto=25;
$sock=fsockopen(”www.otro-servidor.com”, $puerto, $errno, $errstr, 5);

if ($sock) {
echo “El puerto esta abierto”;
} else {
echo “El puerto esta cerrado”;
}
?>

Un escaner de puertos, esa función tomaría el script anterior. Y como se lee se ejecuta hacia otro servidor. Pero esto es un ejemplo nada mas, con un poco de dedicación se pueden hacer más cosas.

Existe otra falla de seguridad común en aplicaciónes PHP, esto quizá no sea una tarea propia de nosotros como administradores, pero proveeriamos a nuestros usuarios de seguridad extra para sus aplicaciones, y les vendría muy bien si se tratara de usuarios/programadores iniciados ó no con mucha experiencia.

Hablo de \ (caracter de escape) en variables pasadas por GET, POST y Cookies,que puede ser agregado a “, ‘ y \ automaticamente.

Veamos un ejemplo de “Inyección SQL” que nosotros mismo como administradores podemos evitar.

$sentencia_sql=”SELECT * FROM nombres WHERE id=$id”;
$cnx= mysql_connect (”localhost”, “pam25″, “ilovemygeek”);
mysql_db_query(”nominas”, $sentencia_sql);
mysql_close ($cnx);

?>

Supongamos que el codigo mostrado anteriormente es el ‘target’ de un formulario que permite a los visitantes ver los datos o el perfil de los trabajadores de la empresa.

Ahora, supongamos que un vistante ‘malvado’ en lugar de ingresar un ID, manda algo como: xx; DELETE FROM nominas. La variavle $sentencia_sql tomaría un aspecto así:

$sentencia_sql=”SELECT * FROM nombres WHERE id=xx; DELETE FROM nominas”;

¡Vaya!, borro todos los datos de “nonimas”.

3. Asegurando PHP.

Para asegurar PHP en nuestro sistema, como era de esperarse, debemos tener muy bien configurado el archivo php.ini.

Abrirmos con cualquier editor de textos el archivo php.ini y:

Empezemos deshabilitando funciones que no querramos que sean ejecutadas en nuestro servidor, como system(), shell_exec(), fsockopen(), etc…

disable_functions=system,fsockopen,shell_exec ; This directive allows you to disable certain
; functions for security reasons. It receives
; a comma separated list of function names.

La función mail() puede implicar problema si se trata de un servidor publico, pues es muy fácil enviar ‘fake mails’ (claro, con todos los datos de nuestro servidor).

Ahora, PHP permite conexiones mediante FTP. Eso también podemos evitarlo, pues no queremos que si el usuarios usa indebidamente recursos de otros servidores, nos vayan a culpar, entonces también beriamos incluir en esa lista la función ftp_connect().

NOTA: Las funciones FTP sólo estarán disponibles si se compiló PHP con –enable-ftp ó
–with-ftp (en PHP3).

Buscamos la directiva magic_quotes_gpc, que quizá este en Off, pues la activamos con On. Esto hace la adición automática del caracter de escape “\” en variables tomadas de GET, POST y Cookies.

magic_quotes_gpc = On ; magic quotes for incoming GET/POST/Cookie data

Para evitar que en lugar de enviar cadenas mal intencionadas, sean almacenadas en bases de datos o archivos de texto. Debemos activar magic_quotes_runtime.

magic_quotes_runtime = Off ; magic quotes for runtime-generated data.

Se podría decir que hasta ahí tenemos mas o menos asegurado PHP. ¿Fácil, no?.

Bueno esto fue un docus corto de como asegurar php en sismples pasos en diferentes plataformas, si tienes mas tips o formas me las puedes hacer llegar mediante mensaje en este mismo apartado y vamos colocando ende vayan llegando mas sugerencias.

No hay comentarios.: