miércoles, 17 de febrero de 2016

Inyección de comodines SQL en búsquedas de tipo LIKE

A continuación voy a hablar de una vulnerabilidad muy poco conocida y tradicionalmente considerada como de poco riesgo, aunque como vamos a ver en algunas situaciones puede tener un gran impacto.

Esta vulnerabilidad consiste en la posibilidad de inyectar un comodín (wildcard) en el campo de búsqueda del operador LIKE de una sentencia SQL.

OWASP menciona brevemente en sus guías este tipo de inyecciones.

En SQL tenemos 2 tipos de comodines:
  • % que equivale a cualquier cadena de cero o más caracteres.
  • _ que equivale a cualquier carácter único.

Una aplicación es vulnerable a este ataque cuando realiza una búsqueda de tipo LIKE con un parámetro recibido del usuario sin filtrar estos 2 comodines.

Por ejemplo si tenemos una aplicación con la siguiente URL:

Que muestra un texto extraído de una BBDD mediante una sentencia SQL como la siguiente:

En vez de usar la forma simple:

Aunque la variable $nombre esté saneada para evitar la inyección de SQL (por ejemplo filtrando el carácter comilla simple) sigue siendo posible la inyección de los comodines de búsqueda, de la siguiente forma:

En una aplicación de este tipo, el poder alterar la lógica de la búsqueda tal vez no sea crítico, pero ¿y si tenemos otra aplicación como la siguiente? (de la que no conocemos ningún nombre de usuario):

Podemos fácilmente hacer lo siguiente para obtener un listado de todos los usuarios disponibles:

Podemos automatizar el proceso mediante un pequeño script que nos vaya sacando los nombres de cada usuario carácter a carácter (a lo película juegos de guerra).

¿En qué situaciones puede ser peligrosa una vulnerabilidad de este tipo?:
  • En formularios de login. Me he encontrado varias veces esta vulnerabilidad en el campo “usuario” de alguno de estos formularios y menos habitualmente en el campo “contraseña”.
  • En formularios de recuperación de contraseñas. Puede permitirnos resetear la contraseña de terceros usuarios.
  • En campos que contienen identificadores de sesión o tokens. Nos podría permitir “robar” tokens o sesiones de otros usuarios.

Aunque parezca mentira esto funciona algunas veces:

La inyección del carácter % a veces puede ser problemática, porque suele estar filtrado para evitar ataques de encoding o precisamente porque es decodificado incorrectamente (en este caso podemos probar %25, %2525).

Hace tiempo me encontré una curiosa situación en una aplicación que autenticaba mediante un identificador de sesión que almacenaba en una base de datos y que extraía mediante una búsqueda vulnerable, de esta forma:


El servidor filtraba el carácter %, pero se permitía el carácter _ de forma que podíamos explotar la vulnerabilidad de la siguiente forma:


Si queríamos acceder a alguna sesión en concreto solo teníamos que hacer un barrido:


¿Porque algunos programadores son víctimas de un bug tan evidente?

Algunas veces supongo que será por despiste, pero también he detectado que algunos frameworks encapsulan las llamadas SQL de forma transparente para el programador y si internamente usan el operador LIKE, es posible que este ni siquiera lo sepa. 

Por ejemplo en Django la siguiente sentencia:

Equivale a:

Lo que puede derivar fácilmente en múltiples vulnerabilidades si el desarrollador no es cuidadoso.

O también este otro bug del mismo estilo en el módulo Propel de Symfony.

martes, 26 de enero de 2016

Herramientas de ayuda para Delorean

Pégale un vistazo a otros posts de esta serie:

[1] NTP MitM con Delorean
[7] Otros ataques
[8] Herramientas de ayuda

Descargo de responsabilidad: Toda la información se ha obtenido de una forma empirica, realizando pruebas, y en un periodo de tiempo concreto, con lo que puede haber cambiado en el momento de leer este artículo.

Por fin hemos llegado al último post de esta serie sobre Delorean. Llegados a este punto, hemos hablando de los ataques que probamos, sobre la herramienta, y muchas otra cosas. Sin embargo, si prestáis atención al repositorio de Deloran, veréis que hay un par de scripts python de los que no habíamos hablado antes. Son pequeñas herramientas que desarrollé porque necesitaba una funcionalidad concreta pero que no tenía sentido integrarlas con Delorean, así que lo mantuve como herramientas separadas.

La primera herramienta es hsts_catcher.py, que es una herramienta muy sencilla que conecta a un website y te devuelve su configuración HSTS. Nada que no puedas hacer con curl y grep:

$ ./hsts_catcher.py -U https://accounts.google.com -A "Mozilla/4.0 (compatible; MSIE 7.0b; Windows NT 6.0)"
max-age=10893354; includeSubDomains

La segunda herramienta es crl_checker.py, que en bastante más interesante que la anterior. Mientras estuve buscando certificados para usar para mis ataques, me encontré con un problema: Algunos certificados que había encontrado tenían problemas de validez en su cadena, por ejemplo, su root CA había expirado. Lamentablemente, comprobar la validez de cada cadena de forma manual era una putada un proceso muy largo y tedioso, así que la manera más cómoda era usar el propio navegador para comprobar si aceptaba la cadena  no. Sin embargo, hay otro problema con esto: Los servidores web necesitan tanto el certificado como la clave privada, y encontrar este clave privada sin saber si luego el certificado te valdrá o no... es un proceso excesivamente costoso como para hacerlo a ciegas. El problema era un circulo vicioso.

Por eso decidí desarrollar esta herramienta. col_checker.py implementa las primeras etapas de SSL, donde no se requiere en realidad el uso de la clave privada, pero sí se realiza la fase de validación del certificado, con lo que podemos comprobar su validez. Solo tenemos que lanzar la herramienta usando este comando y visitar el puerto con el navegador:

$ ./crl_checker.py -p 10443 -c /etc/apache2/ssl/ietf.crt


A veces hace falta refrescar varias veces para que aparezca este mensaje. Probablemente mi implementación del hanshake d SSL está demasiado hardcodada, pero no me he metido a fondo a mirarlo ya que la herramienta sigue siendo útil.

Un mensaje como el de arriba significa que el certificado es perfecto para nuestro ataque. Salen algunos mensajes de advertencia sobre el nombre del hosts o la fecha, pero estos son lógicos y no nos preocupan, ya que estamos corriendo el servidor en una IP local y la fecha... es algo que podemos solucionar con Delorean.


Si tienes mala suerte, verás otros mensaje de advertencia, como por ejemplo "the issuer certificate is unknown" que quiere decir que la CA que firma l certificado probablemente ha sido eliminada de la lista de confianza del navegador, o algún otro problema similar, así que mejor buscar otra víctima.

lunes, 25 de enero de 2016

Otros ataques usando Delorean

Pégale un vistazo a otros posts de esta serie:

[1] NTP MitM con Delorean
[7] Otros ataques
[8] Herramientas de ayuda

Descargo de responsabilidad: Toda la información se ha obtenido de una forma empirica, realizando pruebas, y en un periodo de tiempo concreto, con lo que puede haber cambiado en el momento de leer este artículo.

Los ataques que hemos estado viendo en los artículos anteriores son los que considero que son más probables y que tienen un mayor impacto. Sin embargo, también estuve probando otras opciones utilizando ataques de sincronización. Algunos de ellos funcionaros,  pesar de ser poco probables, y otros de ellos no funcionaron en absoluto.

Uno de los ataques que funcionó fue un ataque contra el planificador de taras de Windows. Como probablemente sepáis, hay un servicio que corre en las máquinas Windows que se encarga de ejecutar ciertas tareas de mantenimiento en segundo plano, como por ejemplo la propia tareas de sincronización de hora.


El planificador de tareas guarda la información de la última vez que una tarea se ejecutó, y la siguiente vez que lo hará. Estos campos son importantes porque, depende de como se haya configurado la tarea, el "Next Run Time" a veces se calcula en base al "Last Run Time", lo cual nos da la oportunidad de manipular la siguiente ejecución de la tarea si conseguimos manipular al reloj usando Delorean.

No todas las tareas calculan la hora de la siguiente ejecución de esta manera, pero hay algunas tareas interesantes que sí que lo hacen, como por ejemplo el servicio de actualizaciones automáticas de Windows.


¿Qué ocurre entonces si manipulamos el reloj usando Delorean, tal y como vimos en anteriores artículos, y la tarea de actualizaciones automáticas es ejecutada? Pues que el "Last Run Time" se ejecutará con la fecha manipulada (por ejemplo, 2020), así que la siguiente ejecución de la tarea se calculará en base a esta fecha, es decir, ocurrirá en algún momento de 2020. Esto no debería ser un problema siempre y cuando el equipo se mantenga con la fecha manipulada para siempre, pero si en algún momento el equipo vuelve a la fecha original... la siguiente ejecución del servicio de actualizaciones automáticas no se ejecutará en los próximos 4 años, con lo que el usuario no será advertido de la existencia de nuevas actualizaciones y parches de seguridad si no lo comprueba manualmente.

En realidad, este es un ataque poco problema, ya que Windows es la plataforma en la que es más complicado realizar un ataque con Delorean, y porque al menos yo no encontré una manera de devolver el reloj a su hora original sin la intervención del usuario. Sin embargo, otras tareas y otras plataformas (como cron en Linux, por ejemplo) podrían también ser manipuladas de una manera similar.