23 de julio de 2005

Hablando de errores

Una de esas madrugadas en donde no tienes más que hacer que ponerte a instalarle bichos de seguridad a los sistemas y platicar con los cuates crackers... uno de estos me hizo notar una cosa interesante en: http://www.uson.mx/noti_php/nota1.php

Si tienen la curiosidad de entrar a este URL se darán cuenta que marca varios errores de PHP:

Notice: Undefined index: m in /spaceA/www/www.uson.mx/noti_php/nota1.php on line 220
AGOSTO del
Notice: Undefined variable: a in /spaceA/www/www.uson.mx/noti_php/nota1.php on line 285

De los cuales podemos observar
1. Del primer error (Undefined index: m), concluímos que por ahí la variable m está incluída como un índice en un arreglo o bien está metido en un switch.
2. Del segundo error: Undefined variable a, sacamos que obviamente por ahí hay exíste una variable a.
3. Aún no sabemos para qué se utilizan pero al menos sabemos que exísten

Acto seguido, probaremos si tienen las register globals encendidas o no. Esto de las register globals tiene que ver con el hecho de que puedas o no enviar datos al script de PHP directamente desde el query string. Probaremos qué hace si yo le doy un valor a la variable a: http://www.uson.mx/noti_php/nota1.php?a=saludos

Y entonces el mensaje cambia a:
Notice: Undefined index: m in /spaceA/www/www.uson.mx/noti_php/nota1.php on line 220
AGOSTO del saludos

De lo cual deducimos:
1) La variable $a el el valor del año y
2) Se está usando una versión de PHP que no tiene las register globals apagadas. So? se le puede enviar información a diestra y siniestra.

Probemos ahora con el index $m, vamos a meterle un valor mm de 2 digamos:
http://www.uson.mx/noti_php/nota1.php?a=saludos&m=2

Lo que nos devuelve:
FEBRERO del saludos

Oh sorpresa! el índice m parece tener que ver con un arreglo en el que se guardan los nombres de los meses. Ahora, si a $m le mandamos una letra o un 0 simplemente nos dirá "AGOSTO", pero curiosamente si le pasamos un número negativo como -2 lo imprimirá y mandará el mensaje de:
-2 del saludos

Así que podemos saber algo respecto a este arreglo de datos, que al parecer el valor por defecto es AGOSTO, aunque me intriga el hecho de que imprima el número negativo.

Finalmente aunque traté de enviarle un `ls -l` para ver si me devolvía la salida pues no funcionó pues al parecer al menos se tomaron la molestia de pasar por un addslashes() las variables de entrada antes de imprimirlas.

Imagínense lo que pasaría si hubiese podido ejecutar mi "ls -l".

¿Ya ven porqué es bueno validar los datos de entrada?

Ahí va otra.
Echemos una mirada a http://opina.iteso.mx/
Aquí obviamente veremos que el nombre de usuario con el que uno se conecta a la base de datos es "dragnovich", que la base de datos está en "localhost" y que utiliza un password de entrada

En fin, hay uno de estos en cada lugar.

21 de julio de 2005

Falla 6: Fallas de inyección

Este tipo de fallas está en cierto modo relacionado con el de la entrada de datos no validada puesto que permite que un atacante envíe código malicioso a través de una aplicación web hacia otro sistema. Estos códigos pueden ser llamadas al sistema, el uso de programas externos vía comandos de shell así como llamadas servidores de soporte mediante SQL (variante conocida como inyección SQL). Incluso se pueden enviar scripts completos escritos en perl, python y otros lenguajes usando aplicacines web pobremente diseñadas y ejecutadas. De modo que cualquier aplicación web que use un intérprete es suceptible de estos ataques ya que generalmente se ayudan de programas externos y de opciones del sistema operativo para llevar a cabo sus tareas.

Muchas aplicaciones web utilizan programas externos o del sistema operativo para llevar a cabo sus tareas. Uno de los más frecuentemente invocados es sendmail (un programa para envío de correo electrónico). Cuando una aplicación pasa información desde una petición HTTP debe revisarla cuidadosamente, de otro modo el atacante puede inyectar metacaracteres especiales, comandos maliciosos o modificadores de comandos y la aplicación los pasará confiadamente al sistema externo donde serán ejecutados.

La inyección de comandos SQL es una variante particularmente extendida y peligrosa de este tipo de ataques, para lo cual un atacante debe encontrar un parámetro que la aplicación pase a la base de datos e incluir ciertos comandos como parte del contenido de éste.Como se pueden imaginar estos ataques no son difíciles de llevar a cabo puesto que exísten varias herramientas para buscar estas fallas y las consecuencias pueden ir desde la obtención de los datos almacenados hasta la pérdida total de la base.

Como resuta claro, en virtud de que está muy extendido el uso de las llamadas a funciones del sistema operativo y de programas externos, la posibilidad de tener una de estas fallas debe ser considerada como alta.

Todos los ambientes de aplicaciones web permiten la ejecución de comandos externos tales como llamadas al sistema, interfaces de comando y solicitudes SQL. La suceptibilidad de una llamada externa a una inyección de comando depende de cómo es hecha la llamada y el componente específico que está siendo llamado, pero casi todas estas llamadas externas puedens er atacadas si la aplicación no está codificadamente codificada.

La mejor forma de determinar si nuestras aplicaciones son o no vulnerables es buscar en el código fuente todas las llamadas a recursos externos (system, exec, fork, runtime.exec, peticiones SQL o cualquier función que se use para enviar información a intérpretes de comandos). Notemos que muchos lenguajes tienen varias formas de ejecutar comandos externos. Los desarrolladores deben revisar su código y buscar por todos los lugares donde la entrada de una petición HTTP podría posiblemente hacerse camino a través de cualquiera de estas llamadas. Debemos examinar cuidadosamente cada una de éstas para asegurarnos que los pasos de protección se verifican completamente.