13 de junio de 2012

¿Qué es una inyección LDAP?

Si bien las inyecciones LDAP no son muy comunes, pueden ser una de las más peligrosas vulnerabilidades en la web. Para empezar necesitamos aclarar para aquellos que no entienden el término que significa el acrónimo LDAP. Lightweight Directory Access Protocol o traducido al español Protoloco Ligero de Acceso a Directorio es el que se encarga del control de las listas de control de acceso de un dominio o red determinado. Para los amantes de Windows, quizás hayan escuchado hablar más de Active Directory que no es sino la versión de LDAP del entorno de Windows. Otros sitemas operativos utilizan versiones de OpenLDAP, Novell Directory Services, Apache Directory Service y otros.

Por tanto una vez dicho lo anterior explicamos la forma en que se puede realizar una inyección LDAP. Aunque como dijimos al principio el ataque de inyección LDAP no es muy común, se parece de alguna forma a un ataque de inyección SQL, ya que para los efectos de una aplicación web, el acceso a LDAP es muy parecido al acceso a una base de datos, la diferencia estriba en que con los conocimientos necesarios, en vez de atacar a un servidor SQL el hacker ataca al sistema de validación de usuarios, para intentar así cambiar la permisología de estos y hasta crear usuarios con los cuales acceder luego a otros equipos o a zonas más sensibles del dominio.

Uno de los preferidos vectores de acceso son los formularios de búsqueda de usuarios. Imaginesmos un simple formulario que solicite el "login" o identificador de usuario para mostrar algún dato de este.

<input type="text" size=20 name="nombre">Introduzca el nombre de usuario a buscar</input>

Al igual que en el caso del SQL injection, el programador toma el contenido del campo nombre sin desinfectarlo y lo introduce en una consulta como:

string nombre = Request.Querystring("nombre")
String ldapSearchQuery =  "(cn=" + nombre +")";

Si el usuario coloca el nombre "alberto" esto produciría la cadena de consulta "(cn = alberto)". Pero que sucedería si el usuario insertara en el campo nombre la cadena "alberto)(|(password=*)" .En este caso se produciría la cadena resultante "(cn=alberto)(|(password=*))" que devolvería el password del usuario alberto.

Como podrá intuir, otro de los "dulces" preferidos de los hackers son los formularios de entrada que validan a sus usuarios mediante LDAP. La que acabamos de mostrar no es más que una simple técnica de ejemplo. El atacante experimentado suele introducir rutinas completas en una vulnerabilidad como la que acabamos de mostrar.

¿Cuál es el remedio? Validación estricta de los datos de entrada o lo que conocemos como desinfección de parámetros del lado del servidor. De nada sirve validar los datos con Javascript en estos casos, el atacante utiliza formularios forjados o simplemente deshabilita el javascript en su navegador.

Pareciera repetitivo, pero existen muy buenas librerías de desinfección de parámetros para cada uno de los lenguajes de uso común actualmente. Usted también puede verificar las soluciones que ofrecen las extensiones PHPFilter para PHP, Microsoft Web Protection Library y los Proyectos AntiSami de OWASP entre muchas otras.

¿Que es un ataque de DDoS?

Escribo este artículo precisamente para aclarar una serie de preguntas de las que he sido objeto en días en que se ha desatado la mayor guerra cibernética de la historia. Es estos últimos día debido al caso WikiLeaks, hemos escuchado y leido acerca del término DDoS en repetidas ocasiones, asociado a varios ataques realizados a sitios importantes de uno y de otro bando de la confrontación y es necesario aclarar qué significa.

Para empezar hablemos de DoS, aunque parezcan las siglas de un viejo y recordado sistema operativo hay que notar que la "o" del medio en este acrónimo está en minúsculas intencionalmente, precisamente porque era una manera de diferenciar a este tipo de ataque conocido como Denial of Service (Negación de Servicio) del viejo sistema operativo DOS.

La técnica de DoS en palabras simples se basa en solicitar un recurso a un servidor web desde varias locaciones simultáneamente y una gran cantidad de veces de forma que el servidor no pueda atender a otras solicitudes.

Tomemos el clásico el ejemplo del cantinero que puede atender a una serie de clientes en una barra de un bar y de repente se ve completamente agobiado ante las solicitudes de dos equipos completos de fútbol que han llegado a festejar a bar, dejando mal atendidos o desatendidos a los clientes habituales.

En los casos del DoS tradicional la idea es solicitar un recurso muy "pesado" en cuanto a tamaño y potencia de CPU mediante un simple URL que no tiene prácticamente costo de ancho de banda. Sin embargo esta técnica ya no es efectiva ya que cualquier firewall o cortafuegos puede controlar la cantidad de ancho de banda utilizado en satisfacer a un solo cliente y si esta es excesiva bloquea automáticamente las solicitudes provenientes de dicho cliente.

La técnica fue perfeccionándose y los ataque se basaron ya no en solicitar recursos complejos, sino en ubicar una deficiencia en la programación que indujera a errores no controlados (Exploits) para reproducirla la cantidad de veces necesaria para que el servidor quede sin recursos de memoria, espacio en disco u otro recurso necesario. Sin embargo al corregir la vulnerabilidad el método quedaba obsoleto y solo era efectivo en servidores que no hubieran corregido el problema, lo que reducía la efectividad con el tiempo.

A veces la aplicación de la técnica podía ser tan sencilla como ejecutar un error en código tal cantidad de veces que el archivo de registro de sucesos de errores crecía tanto que ocupaba todo el espacio disponible en el equipo del servidor.

Pero esos eran tiempos pasados, el problema ahora es otro aunque los métodos se basan en el mismo principio. Cuando hablamos de DDoS (con una D más) nos referimos a Distributed Denial of Service.

Para hablar de esta vertiente mucho más compleja del DoS original es necesario explicar que es una BotNet. El término proveniente de "Robots Net" o red de robots y se usa para denominar a una red de computadores que han sido infectados con un troyano (o rootkit) que permite al hacker utilizarlos como zombies para enviar SPAM, generar ataques de fuerza bruta para obtención de credenciales y otras  técnicas del lado oscuro, como por ejemplo el DDos. Las BotNets usualmente "pertenecen" a un Hacker o grupo de hackers específico. Mientras más grande la BotNet más "poderoso" es el hacker.

Efectivamente en suma el DDoS no es más que un ataque de negación de servicio pero distribuido, ejecutado a través de una red de computadores zombies. Sin embargo es muy difícil de detener, ya que no se puede diferenciar el origen del ataque para bloquear las solicitudes ya que estas difícilmente se pueden aislar de las de los clientes reales. Además el hacker utiliza a sus zombies como batallones que atacan en grupos y a diferente flancos (diferentes recursos).


Todos estos zombies en la mayoría de los casos son controlados mediante instrucciones colocadas en un canal de IRC (Internet Relay Chat), una de las más antiguas formas de chatear en la red. Ellos simplemente se conectan a un puerto determinado en un servidor con un dominio flotante,  obteniendo instrucciones cada tantos minutos y ejecutándolas.

Aunque estoy a favor de la libertad de expresión y especialmente en el ciberespacio, creo que lo que debiera preocuparnos algo más la cantidad de  equipos infectados que están interviniendo en esta guerra virtual. Usted pudiera estar interviniendo en ella mientras lee este artículo sin saberlo.

Hasta la próxima...

¿Que es el Cross Site Request Forgery (CSRF)?

Cuando apenas empezamos a controlar el dolor de cabeza generado por el XSS (Cross Site Scripting) nos vemos las caras con otra amenaza que aunque lleva tiempo en el ruedo de la seguridad web últimamente pareciera tomar auge definitivo para convertirse en una de las peores amenazas de los próximos años. El CSRF o Cross Site Request Forgery también conocido como XSRF, al contrario del XSS que explota la confianza del usuario en un sitio en particular, explota la confianza del sitio en un usuario en particular. Convencionalmente el CSRF utiliza a un usuario validado para a través de este introducir solicitudes "válidas" que modifiquen el comportamiento de la aplicación a favor del atacante.

En palabras simples, el atacante usa a la victima para que sea ella misma la que realice la transacción dañina cuando la víctima se encuentra validada en el servidor y en la aplicación específica. El proceso es simple, muchos usuarios no finalizan correctamente (o no pueden hacerlo) sus sesiones en las aplicaciones bancarias o de otra índole que puedan ser afectadas por esta vulnerabilidad y las mantienen activas mientras navegan otros sitios, más aún en tiempos en que las pestañas de los navegadores son muy utilizadas, por tanto desde cualquier otra ventana en el navegador se pudiera inducir al usuario a pulsar un enlace con una orden a sitios en los que el usuario ha ya autenticado, para que el usuario ejecute sin saberlo la acción de ataque.


¿Cómo evitar el CSRF?

Uno de los mejores consejos para los usuarios es simplemente hacer una sola cosa a la vez cuando se trate de manejar sus cuentas en línea, y salir de las aplicaciones haciendo el respectivo "logout" que casi siempre significa pulsar un simple botón de "salir" o "abandonar la aplicación". Por ejemplo: No pulsar un enlace recibido mediante en "Messenger" o en otra pestaña del navegador cuando estamos utilizando la aplicación de nuestro banco puede ser la mejor solución imaginable ante un ataque de CSRF.

Sin embargo para el programador es un poco más difícil prevenir este tipo de ataque. Lo primero indudablemente es darle al usuario la posibilidad de cerrar su sesión. Aunque parezca raro, usted se asombraría de la cantidad de sitios y aplicaciones que no disponen de esta opción una vez que el usuario ha validado su ingreso a las mismas.

En cuanto a código, el mejor de los aliados para controlar el CSRF es el control estricto del Session TimeOut de la aplicación, de forma que si el usuario no se conecta nuevamente y olvida "salir" correctamente de la aplicación, el servidor deberá en un lapso corto de tiempo dar dicha sesión por finalizada.

Otra eficiente forma de controlar el CSRF es la introducción de un "token" dinámico adicional en las solicitudes del cliente que se asocia a la sesión de éste en el servidor y se agrega a todos los enlaces y solicitudes. Este token será siempre diferente por sesión y por usuario por lo que de esta forma se le hace más difícil al atacante tratar de emular el enlace necesario para efectuar el ataque debido a que el token es variable.

Muchos programadores hacen públicos los enlaces privados, y esta es también una razón para que los atacantes utilicen estos enlaces privados a discreción. Los enlaces privados solamente deben ser vistos si un usuario ha validado su sesión y jamás deben ser expuestos en e-mails o páginas públicas. Esto también parece obvio pero se asombraría al ver la cantidad de enlaces "privados" de un sitio que se pueden obtener mediante técnicas de GHDB (Google Hacking Database).

Hasta la próxima.

Decálogo de Principios de Seguridad para Desarrollo de Aplicaciones Web

Independientemente del lenguaje y/o plataforma de desarrollo que usted utilice, hay cosas que de una o de otra forma siempre hay que tomar en cuenta si queremos tener una aplicación web "relativamente" segura. Además acoto la palabra "relativamente", porque en primer orden nunca se puede obtener una aplicación 100% segura. Dice un chiste de seguridad que la única aplicación segura es la que está desconectada del cualquier red, no se ejecuta y se introduce en un "bunker antiaéreo" sellado a 50 metros de profundidad y aún así nadie apostaría un ojo asegurando la integridad de la misma.

web-security.png
Por lo tanto el presente artículo, tiene como fin el poner al lector al tanto de una serie de principios de seguridad que debería seguir en el proceso de desarrollo si realmente desea obtener un resultado favorable en lo referente a este tema.

  • Defensa en profundidad.
    Nunca confíe en un solo punto de defensa. Su aplicación en la mayoría de los casos será siempre la última línea de defensa entre el atacante y servidores del entorno de redes corporativas. Por tanto usted debe proveerle a su aplicación más de un método de defensa si desea proteger servidores de bases de datos e información sensible de la empresa.
  • Nunca confíe en las entradas de datos.
    Como usted podrá descubrir mediante un simple ejemplo de XSS o SQL injection, la mayoría de los problemas empiezan por creer que la validación del lado cliente en Javascript puede ser suficiente, suponer que la única forma de solicitar un tipo de datos es un formulario u olvidar validar que los datos no excedan la capacidad de un contenedor. En las aplicaciones web los datos pueden venir de cualquier parte, pueden ser y muchas veces son forjados, y su aplicación debe tener la capacidad de responder ante este hecho.
  • Controle los errores elegantemente.
    Aunque usted haya pensado en todo, siempre algo nuevo puede suceder para lo que la aplicación podría no estar preparada. Controle las respuestas de error y trate de no entregar en ellas información que pudiera ayudar al atacante a descubrir datos acerca de como está hecha o funcionan los procedimientos de la misma. Utilice siempre que sea posible controles de error (try - catch) para que su aplicación no muestre la típica página de error 500. Una simple página de error 403 (acceso denegado) puede decirle a un escaner de vulnerabilidades que un directorio sacado de un diccionario existe, y permitirle montar un aproximado de su la estructura de directorios por ensayo y error.
  • Esté atento a los ataques.
    Inclusive si usted maneja los errores elegantemente, usted pudiera no estar guardando en bitácora (log) cuáles son las causas de dichos errores. Hacerlo le permitirá corregirlos sin esperar que un usuario se los reporte y además podrá verificar si la aplicación está siendo o ha sido atacada y lo mejor de todo, podrá verificar cómo está siendo atacada.
  • Use los menores privilegios posibles.
    Posiblemente a la hora de desarrollar la aplicación usted no tenga inconvenientes en utilizar una cuenta de administrador de su servidor de bases de datos, pero dejar esa información de conexión administrativa para una aplicación que probablemente solo ejecute procesos que pudieran perfectamente asociarse a una cuenta con muchos menos privilegios, es una falla que puede costar cara si el atacante logra obtener acceso a algún archivo de configuración. Lo mismo sucede con la permisología de escritura y ejecución en directorios. Si solo necesita subir archivos a un directorio una vez, no tiene sentido dejar los privilegios de escritura de forma permanente. Use siempre los menores privilegios posibles para su aplicación.
  • Los Cortafuegos (Firewalls) y la Criptografía no son una panacea.
    Es muy fácil creer que por que algo está cifrado no podrá ser accedido, o que porque tenemos un firewall el atacante no podrá tener acceso al sistema. Ninguno de los anteriores es cierto. Los firewalls deben permitir el acceso al puerto en el que se desempeña su aplicación (típicamente el puerto 80 y el 443) y una sentencia SQL a través de un campo mal validado no puede ser bloqueada por este medio.
    Lo mismo sucede con la cryptografía, hace años se consideraba muy seguro un hash MD5 o SHA1, hoy en día los ataques por diccionario y tablas de arcoiris nos hacen pensar en nuevos métodos y trucos de cifrado que antes no eran necesarios. El ancho de banda y la velocidad de procesamiento hacen posibles ataques por fuerza bruta que tiempo atrás eran impensables.
  • La Seguridad debe ser el estatus por defecto.
    Es muy fácil instalar un servicio, hardware o aplicación y dejar los atributos por defecto que vienen habilitados desde la casa matriz. Un ejemplo de esto es la cara lección que tuvo que aprender Microsoft por el caso del SQL Slammer, que atacaba el el servicio de SQL Browser que venía activo por defecto en todos los paquetes de SQL Server, cuando en realidad la gran mayoría de usuarios no lo necesitaba. Revise bien los atributos por defecto de sus instalaciones y no deje servicios activos que no necesita. Usted reducirá así la superficie de ataque y con ello el riesgo de uno.
  • El Documento OWASP Top 10
    OWASP desarrolló una lista de los 10 grupos de vulnerabilidades más comunes en orden de importancia. También creó ejemplos explicativos de las mismas y de cómo proteger a su aplicación  de dichas fallas o vulnerabilidades. Usted no puede dejar de leer este documento y de aplicar esta lista en el rastreo de los posibles errores de seguridad en su desarrollo. También puede acceder a una traducción hecha por mi persona de la lista en este enlace.
  • Manténgase un paso adelante
    Su aplicación si bien puede haber sido realizada con todo lo anterior en mente por su propia naturaleza será expuesta a todo el mundo. Internet no es una capsula, nada más lejos de eso. Su aplicación estará disponible a todos los posibles atacantes mediante una simple consulta en un buscador. Google Hacking Database es un ejemplo de cómo obtener listados de posibles aplicaciones víctimas mediante el uso de búsquedas avanzadas en Google. Por tanto usted debe estar al tanto de cualquier tipo de vulnerabilidad descubierta para poder protegerse de ella antes de que un posible atacante descubra la falla en su sitio.
  • Mantenga el software de terceros actualizados.
    Su aplicación se basa en software desarrollado por terceros en mayor o menor grado. Usted la coloca en un servidor web (Apache, ISS, Nginx, etc) que a su vez corre en un sistema operativo. También accede a manejadores de bases de datos. Todos estos servicios suelen tener fallas y deben siempre que sea posible ejecutar en sus últimas actualizaciones. Usted también podría utilizar manejadores y componentes de terceros directamente en su aplicación. Este y todo tipo de software de terceros debe estar actualizado siempre que sea posible . Usted se sorprenderá al saber que los atacantes son los primeros en estar registrados en las listas de control de vulnerabilidades para saber cuáles versiones de determinado software son vulnerables a un determinado tipo de ataque.

Todos las anteriores son recomendaciones y principios generales que no dependen del tipo de lenguaje y/o plataforma de desarrollo que utilice. Son prácticamente obligaciones que tiene usted como desarrollador para con su empresa, sus clientes y sus usuarios. Téngalos en cuenta y se ahorrará muchas molestias.

Hasta la próxima!

Cuando el hacker utiliza los respaldos para vulnerar una aplicación web!

Es una técnica tradicional y hasta podría decirse que una costumbre, renombrar algunas rutinas agregándoles la extensión .bak cuando deseamos hacer nuevos ajustes para no perder el código escrito con anterioridad. Algunos de nosotros como programadores utilizamos esta y otras extensiones y simplemente las adosamos a la rutina existente de forma que por ejemplo un archivo "index.php" pasa a ser "index.php.bak" o "index.php.old". El problema reside en que dejar estas rutinas con dichas extensiones puede ser un peligro latente para la seguridad de nuestro sitio.

Los servidores web, pre-procesan los archivos del tipo php, asp, asp.net, jsp y otros, de forma que el contenido que llega al navegador cliente sea simple HTML (en nuestra jerga HTML plano). Como es conocido, dependiendo del tipo de servidor y tecnología, los archivos con estas extensiones (y algunas otras) son procesados del lado del servidor y definen lo que conocemos como rutinas "server-side", sin embargo al cambiar la extensión de los mismos a ".bak", ".old" o cualquier otro tipo de extensión no asociada a un proceso en el servidor, simplemente hacemos que el servidor entregue el archivo "como es", entregando el código "tal cual" lo hemos escrito". Para ello el atacante posee herramientas que intentan obtener nuestras rutinas con una serie de extensiones comúnmente usadas para archivos de respaldo. Inclusive apoyado en otra vulnerabilidad, podría obtener dichos listados directamente en Google (ver artículo sobre Google Hacking Database).

De esta forma puede llegar a obtener información de calidad acerca de nuestra aplicación y de nuestro servidor, como nombres de conexiones y bases de datos, directorios físicos de nuestro servidor y muchas otras cosas que pudieran abrir una brecha razonable de seguridad.

Sin embargo el anterior es el menor de los casos. Muchas veces existen respaldos completos de un sitio en formato "zip" o "rar" ubicados bajo el directorio principal, con el mismo nombre de alguna de las carpetas o directorios bajo este.

Por ejemplo, si el programador creó un sub-directorio en donde lleva todo el control administrativo llamado "admin" (por cierto admin es un mal nombre para un directorio administrativo de la aplicación) es probable que desde la interfaz de escritorio del servidor haya hecho un respaldo de dicho directorio con solo pulsar el botón derecho del ratón y ubicar la opción por defecto de enviar a carpeta comprimida en formato "zip". Por tanto todo lo que hay que hacer es intentar ubicar el archivo "admin.zip" bajo dicho directorio para obtener una copia completa y funcional de dicha aplicación.

Lo que pudiera suceder en este caso de que el atacante obtenga una copia actualizada del código completo del sitio, lo dejo a su imaginación... Este último punto pareciera un absurdo, sin embargo se sorprenderían de saber la cantidad de sitios que han sido vulnerados por esta razón.

¿Cómo protegernos?

  • De ahora en adelante, si es necesario dejar archivos de respaldo de las rutinas en el servidor de producción (debiera ser un absurdo, para eso existen los entornos de desarrollo) entonces deberemos renombrar los mismos sin cambiar la extensión, ejemplo: index.old.php, index.bak.aspx. De esta forma siempre será procesado el código y al navegador cliente llegará solo HTML plano.
  • Bajo ningún pretexto dejar cualquier tipo de respaldo comprimido del sitio web en el sitio web. Esto no tiene otra solución razonable. No se debe hacer y punto! Hacerlo es como dejar los planos de nuestros puestos de avance en manos del enemigo.

Hasta la próxima...

Entradas populares