Artículo publicado en PCWorld Mayo de 2007.
Lee la segunda parte en Test Intrusión Web (parte II de II)
**********************************************************************************
Durante los tres meses anteriores hemos estado centrados en el test de intrusión en un sistema y hemos ido viendo tanto las herramientas como los procedimientos. Cuando tratamos con un sistema nos encontramos ante un entorno en el que se están utilizando protocolos, arquitecturas y aplicativos comerciales o estandarizados, es decir, podemos tener un servidor Apache o un servidor con Internet Information Services 6, un DNS de Windows Server 2003 SP1, etc... En esos entornos utilizar las herramientas de fingerprinting o los scanners de vulnerabilidades es perfecto ya que están adaptados para buscar las características y fallos de seguridad del software de uso público, pero… ¿qué sucede con esa aplicación web desarrollada por tu equipo de programación? ¿Serán capaces esas herramientas de detectar un fallo de seguridad en vuestro software? Existen herramientas con aproximaciones como veremos, pero es mucho más artesano que en el caso de los sistemas. Puedes tener un fallo de seguridad en un bonito radio button que le permita al atacante tumbar tu servidor de bases de datos y los test de intrusión anteriores te dirán que tu sistema está bien.
En el presente artículo intentaré mostraros algunos de los errores más comunes que me he encontrado durante el proceso de test de intrusión en aplicaciones web, una de mis mayores “aficiones profesionales”. Aunque algunas de ellas os suenen a ciencia ficción y leyenda urbana puedo prometeros que tengo referencias reales en primera persona de todas ellas. Aunque os voy a dar algunas herramientas para poder realizar algunas cosas hay que tener en cuenta que nos encontramos con software desarrollado, generalmente, a medida, por lo que el trabajo “artesano”. Es fundamental.
Código Limpio
La primera forma que utiliza cualquier usuario malintencionado para atacar un sistema es simplemente leer el código fuente ofertado por el desarrollador. Como dice un amigo mío: “leer es barato y se aprende mucho”. Por eso, es muy importante, que los códigos de las páginas web sean lo más limpios posibles. Solo deben ocuparse de las funciones relativas al Interfaz de usuario. No debe dejarse comentarios, ni incluirse ficheros que no se vayan a utilizar. De hay se saca mucha información sobre la estructura del sitio web al que nos enfrentamos.
Fichero Robots.txt y Estadísticas
Los buscadores de Internet utilizan arañas que rastrean todos los dominios publicados en Internet e indexan toda la información del sitio. Esto puede llevar a que se indexe información sensible que pueda ser descubierta a través de los motores de búsqueda de estas arañas. Es conveniente utilizar el fichero robots.txt para evitar que las arañas recojan información de nuestro sitio que pueda ser sensible, pero claro, si pones en el fichero que no indexe /admin/ y /basededatos/ o algo así le estás dando información al atacante que, con solo leerse ese fichero de la estructura del sitio y va a encontrar los directorios prohibidos. Lo mismo sucede con las estadísticas. Si estas son públicas cualquiera va a poder ver la estructura del sitio y sería como tener el listado de directorios abierto, peor aún, porque los programas que reciban parámetros por get van a quedar reflejados con sus parámetros. Configura de forma segura las estadísticas. De igual forma, no uses directorios ocultos, ficheros de configuración o bases de datos accesibles y predecibles. Te sorprendería la imaginación de un atacante.
Datos desde el Cliente
Todos los datos que vengan desde el cliente pueden ser manipulados, están en la máquina del atacante, así que son suyos y decide que es lo que te envía. Si dejas algo en manos del cliente, asume que puede ser tocado. No pongas ninguna autenticación en Javascript, Flash, ActiveX o Applet Java. Por desgracia, aunque parezca muy evidente, aún es muy común encontrar aplicaciones web protegidas por películas flash. Si tienes una tienda online, nunca utilices el precio que se te envía desde el cliente. ¿A que parece una chorrada?
En la imagen tienes una captura de Odysseus un “Local Proxy” que se utiliza para manipular los datos que se envían desde el cliente en peticiones por Post o por Get a la web. Existen varios como BurpSuite o Achilles, pero en todos los casos el funcionamiento es similar. Los datos salen del navegador del cliente cumpliendo todas las restricciones que se hayan puesto en javascript, cookies, etc.. y llegan al programa que actúa como Proxy y para los datos para que sean manipulados.
Los algoritmos matemáticos tampoco sirven para nada. En esos casos, se pide una contraseña, a la que se la va a pasar por un “complejo” algoritmo y se va a generar un numerito. Si el numerito es correcto se navega a esa página (que generalmente no se puede ver porque no está en el código y depende de la contraseña) y si no se deniega. Todos esos algoritmos se rompen con ingeniería inversa y, o ya está roto porque es comercial, o bien te lo van a romper por ser tuyo.
Con autenticaciones y protecciones de este tipo vas a defenderte de técnicoless, no de atacantes.
Cuando se realiza un test de intrusión a una aplicación web se va a mirar con “cariño” toda la información que tenga el cliente para ver “qué sucede”.
Tratamiento de todos los errores
Los atacantes intentan realizar ingeniera inversa y extraer información de las aplicaciones en base a los mensajes de error. Es importante que se controlen absolutamente todas las posibilidades que puedan generar error en cualquier procedimiento por parte del programador. Para cada acción de error se debe realizar un tratamiento seguro del mismo y evitar dar ninguna información útil a un posible atacante.
Es recomendable que los errores se auditen pues puede representar un fallo en la aplicación o un intento de ataque. Se puede afirmar que casi el 100 % de los atacantes a un sistema van a generar algún error en la aplicación en la fase de “trasteo”.
Error de una base de datos que da información a un ataque de SQL Injection. No parece Oracle.
Manipulación de URL & cookies
Los parámetros que se mantienen en una URL compleja son una forma más de datos en el lado del cliente. Una URL del tipo:
- http://www.miwebsite.com/prog.aspx?i=122212&i=0&p=ED00FAD3AF0A03&q=8&mode=list&code=RFADSF34SdF==
Esta URL está pidiendo a gritos que se intente decodificar, averiguar para que se usan todos y cada uno de los parámetros, intentar saber porque se ha usado un Hash en Hexadecimal (MD3, MD4 o MD5) o en Base64. Lo que se codifique en la URL debe ser comprobado constantemente en el servidor ya que un usuario malicioso puede descubrir que va codificado ahí y cambiar la información codificando otros datos con lo que pueden producirse riesgos de elevación de privilegios, denegación de servicio o incluso ataques de sql injection. Todo esto se aplica de igual forma a la información que se pone en una cookie.
SQL Injection
Es una vulnerabilidad documentada y explicada y remarcada hasta el infinito y más allá, sin embargo encontrar una aplicación que tire de una base de datos y no tenga es una vulnerabilidad es para darle un premio. La gente asume que basta con quitarle la comilla en los parámetros pero con eso no basta (el mes que viene haremos una explicación detallada de cómo proteger nuestra aplicación contra un ataque a ciegas). Cuando tengamos una aplicación que tire de una base de datos debemos mirar todos, absolutamente todos los datos que nos vengan desde fuera y estemos utilizando en consultas a bases de datos. Cuando digo todos, me refiero a TODOS, es decir, todos los campos de formularios, los values de checkbuttons y radiobuttons, los parámetros de consultas javascript, los valores de las cookies, los valores de los campos http, etc… No importa que pensemos que a esa función solo la llamo yo desde una librería javascript que le pasa el parámetro, si alguien quiere atacar tu web va a saber realizar esa llamada y si no va a aprender. Si tienes que hacer unas pruebas con tu aplicación prueba a meter a todos los parámetros comandos sql del siguiente tipo: pagina.asp?id=1 y allí pon 1’a a ver si rompe, o 1 or 1=1 a ver si devuelve más de lo que debe o -1 or 1=1 a ver si devuelve algo cuando no lo debía o 1 and 1=3 a ver si no devuelve nada o 1; shutdown—(uff, cuidado con esto último, no vaya a ser que funcione). En el momento que el comportamiento de la web no sea el esperado tendremos un problema que alguien va a saber explotar.
Fortificación de la base de datos
Las consultas que se lanzan desde la aplicación a la base de datos mediante consultas SQL se ejecutan dentro del servidor de bases de datos en el contexto de la cuenta de usuario que utiliza el programador. Es importante que estén controlados los permisos que tiene ese usuario sobre todos los objetos y sobre los objetos de las demás bases de datos que comparten el servidor. Así mismo, es necesario que ningún otro usuario de ninguna otra base de datos pueda acceder a la información de ésta.
Una vulnerabilidad de SQL Injection podría permitir a un usuario de la aplicación Web apagar el servidor de bases de datos, acceder a cualquier información de cualquier base de datos que comparta dicho servidor e incluso ejecutar, mediante procedimientos almacenados, comandos en el sistema operativo.
**********************************************************************************
Artículo publicado en PCWorld Mayo de 2007.
Lee la segunda parte en Test Intrusión Web (parte II de II)
**********************************************************************************
Buen post Chema
ResponderEliminarMuy bueno el análisis. Enhorabuena Chema!!
ResponderEliminarnosotros ya estamos en el camping de el rocio. hay WiFi!!!!
ResponderEliminar«Si tienes una tienda online, nunca utilices el precio que se te envía desde el cliente. ¿A que parece una chorrada?»
ResponderEliminarLo parece, y sin embargo...
Element N.V. Element InstantShop Price Modification Vulnerability (octubre de 2000)
Recuerdo este ejemplo porque el libro Writing Secure Code, 2nd Edition lo menciona en el capítulo 13, dedicado a los problemas de seguridad que pueden surgir en aplicaciones web por errores de validación.
"All input is evil unless proven otherwise." (Toda entrada es bronxtolita* hasta que se demuestre lo contrario.)
* maligna :-P
Muy bueno Ramón!
ResponderEliminarEn el trabajo que estoy escribiendo esa frase es de las que más destaco: "All input is evil" y respecto a lo de los precios, ya pusimos lo de "Coja su cambio. Sea justo"
Muy buena apreciación, no conocía el fallo del 2000!