Agilizando SSH

Ampliando el post de mi compañero José Vila (@jovimon) sobre introducción a túneles SSH, os quiero mostrar otros truquillos para aquellos que usamos SSH a diario, y poder así agilizar tareas. Ya sabéis, para ser productivo hay que ser un maestro kung-fu de las herramientas que más usas ;)

Multiplexar conexiones y hacerlas persistentes aunque hayamos cerrado sesión

Muy útil si en nuestro día a día estamos entrando y saliendo en varios servidores. Aunque tengamos varias shells abiertas contra un servidor, el cliente SSH solo habrá creado una conexión y todas las consolas compartirán el mismo socket. De esta forma, sólo será necesario autenticarse la primera vez. Se creará un socket donde las siguientes conexiones a ese servidor irán multiplexadas a través de él. Por tanto, los próximos accesos serán mucho más rápidos y sin tener que introducir las credenciales de nuevo.

[Read more…]

Copiar un certificado para evadir autenticación

En ocasiones, una aplicación web permite utilizar certificados X.509 como medio de autenticación. Estos certificados, asociados a una persona, pueden ser generados bien por una autoridad certificadora reconocida (FNMT, ACCV…), o de forma privada para uso interno de una organización. En cualquier caso, la aplicación web debería comprobar que el certificado que se presenta está firmado por la CA correspondiente. De esta forma, se está asegurando que la persona es quien dice ser. Para información más ampliada sobre infraestructuras PKI, podéis leer la estupenda serie de posts del compañero David Cutanda.

Ahora bien, es posible que el desarrollador de la aplicación no haya considerado necesario tomarse tanta molestia de comprobar firmas, y únicamente verifique que algún campo del certificado coincida con su base de datos, como el DNI, número de serie, etc. ¿Cómo podría un atacante aprovechar esa deficiencia? Generando un certificado con los mismos datos que un certificado válido, y rezando para que la aplicación no haga ninguna comprobación adicional, ya que la firma del certificado no coincide con la CA legítima.

Vamos al ajo. Supongamos que tenemos suficiente información sobre los certificados que se utilizan para la autenticación. Vamos a explicar los pasos para generar una CA con los mismos datos que la original, un certificado de un usuario, y después firmaremos ese certificado con la CA que hemos generado.

Crear clave privada RSA para la CA

$ openssl genrsa -out rootCA.key 2048

Crear CA

$ openssl req -x509 -new -nodes -key rootCA.key -days 3650 -out rootCA.pem 
-subj "/O=Wayne Corp./OU=WaynePKI/CN=Wayne-CA"

Crear clave privada RSA para certificado personal

$ openssl genrsa -out personal.key 1024

Crear certificado

$ openssl req -new -key personal.key -out personal.csr -subj "/O=Wayne 
Corp./OU=Direccion/CN=Bruce Wayne" 

Firmar el certificado con la CA

$ openssl x509 -req -in personal.csr -CA rootCA.pem -CAkey rootCA.key -
CAcreateserial -out personal.crt -days 500 -set_serial 0x5599aaffbb4422cc

Exportar el certificado a PKCS12

$ openssl pkcs12 -export -out personal.p12 -in personal.crt -certfile rootCA.pem -
inkey personal.key

Exportar a PKCS12 es recomendable para poder importar el certificado en algún navegador. Es importante también darse cuenta que a la hora de firmar el certificado, es posible hardcodear el número de serie que deseemos. Si disponemos de un certificado legítimo que queramos clonar, se puede crear con el mismo número de serie. No es la primera vez que veo que ese dato es el que comprueba la aplicación para autenticarse.

En el caso de este ejemplo sólo he cumplimentado la organización O, unidad organizativa OU y common name CN, pero por supuesto se puede rellenar todo lo necesario para que el certificado sea lo más parecido posible al original.

Con el fichero personal.p12 generado ya podemos importarlo a nuestros navegadores, perfiles de SoapUI para auditar un WebService con WS-security, o lo que necesitemos. Es posible que también se necesite importar la CA que hemos creado al navegador como entidad de confianza, para que no se queje el navegador de que no puede comprobar la autenticidad del certificado.

¡A jugar!

Bastionado de sistemas Linux

(N.d.E. Hoy les traemos una presentación que nuestro compañero José Luis Chica, @bufferovercat, realizó en la MurciaLanParty’13, sobre el Bastionado de sistemas Linux. Esperamos que les guste.)

Evasión de autenticación con inyección SQL

Los ataques de inyección SQL son muy conocidos y temidos por tener un impacto tremendo en la seguridad de una aplicación, además de ser la vulnerabilidad más común, según el Top Ten de OWASP. Cuando pensamos en una inyección SQL, enseguida la relacionamos con fuga de información o robo de credenciales, porque el ataque más usual es volcar tablas de la base de datos que utiliza la aplicación vulnerable.

En este post voy a hablaros de otro método para aprovechar una vulnerabilidad de inyección SQL: saltarse un formulario de login, pudiendo autenticarse sin conocer credenciales.

Partamos de un ejemplo típico: un formulario con un campo de usuario y otro de contraseña. La aplicación hará una consulta a la base de datos muy parecida al código a continuación:

[...]
$usuario=$_POST['usuario'];
$pass=$_POST['password'];
$query="SELECT * FROM users WHERE usuario = '$usuario' AND password = '$pass'";
[...]

[Read more…]

Recursos para formación en desarrollo web seguro

Probablemente muchos de vosotros habréis caído en la cuenta de la falta completa de información referente a la seguridad en desarrollo web que se suele impartir en universidades, o específicamente, en cursos o másteres de desarrollo. De toda la gente a la que he preguntado, a nadie le han enseñado técnicas de desarrollo seguro en su formación universitaria. Sólo una persona, que acabó recientemente la carrera, me comentó que había una asignatura referente a seguridad, muy en general, y era de libre elección. Y no sólo en la formación. En cualquier libro técnico sobre introducción al desarrollo web, tampoco hacen mucha mención a la necesidad de filtrar parámetros de entrada, o cifrar las comunicaciones de un formulario de login.

¿Y por qué menciono yo esto? ¿Por qué es tan importante que un desarrollador tenga conocimientos de desarrollo seguro? Porque ahorra tiempo y dinero. Se estima que el coste en euros de solucionar una vulnerabilidad detectada en producción es 15 veces más que si se hubiera arreglado en la fase de desarrollo. Muchos sabréis de primera mano lo tedioso que es subir una nueva versión a producción: pruebas en pre, ventana de mantenimiento para detener la aplicación, litros de café y plegarias para que nada explote.

Mi idea al escribir este post es recopilar lo esencial de lo esencial, como base para aprender en qué momentos es necesario tomar ciertas medidas de seguridad. Por suerte, todo lo que he considerado de imprescindible lectura está disponible libremente en la web de OWASP. Por supuesto, hay muchísimo más, aunque me he centrado en comentar los proyectos de OWASP por ser recursos desarrollados por la comunidad.

El primero de todos, la guía de desarrollo seguro de OWASP. Este documento explica las vulnerabilidades web más comunes y su forma de evitarla. Actualmente la versión publicada es del año 2005, aunque la información sigue siendo hoy día perfectamente válida. La mayoría de ejemplos están descritos en Java. Además de los temas conocidos como validación de datos de entrada, gestión de sesiones, mecanismos de autenticación o autorización, toca temas como webservices, phising, o buenas prácticas en el manejo de errores. Es un recurso que todo desarrollador web debería conocer, y tener a mano para consultar, para que al menos, aunque no recuerde cómo implementar de forma segura cierta funcionalidad, si que al menos sepa que lo que está programando implica una posible vulnerabilidad y que es necesario desarrollarlo con cuidado.

Otra lectura muy recomendable es la guía de revisión de código. Aplicable tanto para el personal dedicado a la fase de test de un proyecto, como a los pentesters que realizan test de intrusión de caja blanca, con acceso al código fuente. Se definen una serie de controles y muestra en qué hay que fijarse para detectar una posible vulnerabilidad. Enseña tanto errores comunes como buenas prácticas.

Por último, Application Security Verification Standard (ASVS) son una serie de controles, que a modo de CheckList, puede sernos muy útil usarlo en la fase de testing. Está categorizado por el tipo de vulnerabilidades a revisar y además catalogados en tres niveles, dependiendo del nivel de exigencia a cumplir. Actualmente la versión 2.0 está en fase de borrador con muchas mejoras, como la simplificación de niveles y nuevas categorías, como desarrollo para aplicaciones móviles. Un recurso muy valioso tanto para el desarrollador como para el jefe del proyecto.

Y por supuesto, no me puedo dejar como fuente de información este blog ;) Sobre todo muy interesantes los post de nuestros compañeros David, Guillermo, y Nedim.

Filtrado de parámetros de entrada. Recomendaciones

Parámetros de entrada. Ese gran agujero de seguridad por el que se cuelan dos de las vulnerabilidades más comunes en cualquier aplicación web: Inyección SQL y Cross-Site Scripting. No están por casualidad en los puestos número uno y tres del TOP 10 de OWASP de este año 2013.

Y es que es una batalla por la que los pentesters luchamos a diario. La formación sobre desarrollo seguro sigue siendo, a día de hoy, escasa. Por poner un ejemplo, de todo el material de un máster sobre desarrollo web al que he podido echar un vistazo, de un año de duración, las referencias sobre seguridad son una única sección, de un tema, de una asignatura, con un total de 9 páginas. La información sobre la correcta implementación de medidas de seguridad es obviamente insuficiente.

Pero el problema también se encuentra en nuestro lado de la mesa. Si después de haber entregado un informe de un test de intrusión a un cliente, las correcciones tomadas han sido insuficientes, es que no hemos sido capaces de transmitir la gravedad de la vulnerabilidad, ni la forma correcta de mitigarlas. La solución “filtrar correctamente los parámetros de entrada” necesita una explicación más extensa sobre lo que quiere decir “filtrar correctamente”.

Por este motivo, me he decidido a enumerar unas recomendaciones generales, pero un poco más precisas, sobre el filtrado de parámetros de entrada. Empecemos:

  • En primer lugar, una pregunta recurrente: ¿Dónde deben validarse los datos de entrada? ¿En el lado del cliente? ¿O en el del servidor? Seguramente os habréis dado cuenta de que es una pregunta trampa porque la respuesta correcta es en los dos lados ;) . Es imprescindible que toda validación y filtrado de datos de entrada se realice en el lado del servidor, ya que el lado del cliente es ejecutado por el usuario, y las restricciones se pueden evadir. Pero también es recomendable añadir validación en el lado del cliente, no por temas de seguridad, pero si por usabilidad. A pesar de que el servidor va a comprobar que todo lo que reciba es correcto, viene bien que un javascript compruebe también que se están escribiendo datos correctos, por ejemplo en un formulario. Ahorras tiempo al usuario, y ahorras ancho de banda al servidor.
  • Filtrar TODA la entrada. No se debe limitar a los datos que escribe el usuario en la barra del navegador, o los campos de un formulario. También los campos ocultos HTML de un formulario, las cookies, cabeceras HTTP. No presuponer que el usuario no va a tocar esos datos porque la aplicación no dispone de esa funcionalidad. Con un proxy HTTP, o con una simple extensión del navegador, como tamper data, es posible modificar cualquier cosa que se vaya a enviar de nuestro navegador al servidor.
  • No reinventar la rueda: no complicarse la vida. No es recomendable crear desde cero una implementación propia, ya que probablemente no contemple todos los casos posibles. Mejor usar funciones ya testeadas y maduras como las disponibles en prácticamente cualquier lenguaje de programación o framework. También se puede usar la librería ESAPI de OWASP, con APIs para Java, Python, .NET, PHP, ASP, entre otros.
  • Comprueba tipos de variables: si un parámetro de entrada solo espera recibir un entero, comprueba si lo que recibe es efectivamente un entero. En datos como IDs de objetos suele ser bastante útil, del estilo de http://a/index.php?id=400
  • Como complemento al punto anterior, usa listas blancas de datos permitidos, y deniega todo lo demás. Es mucho más sencillo definir lo permitido, que enumerar todo lo prohibido. Por ejemplo, para una cadena de texto, se puede definir que sea válida toda cadena que contenga a..z, A..Z, 0..9 y todo lo demás eliminarlo. Con esto se evita el uso de caracteres especiales.
  • Si no se desea filtrar caracteres especiales, por requerimientos de la aplicación, usa codificación de salida a la hora de representar los datos. Por ejemplo, codificación HTML para caracteres especiales, como “>” que pasa a ser “>” o “&” “&amp”.
  • Antes de filtrar, codifica. Los datos de entrada pueden venir de muchas formas codificadas. Siguiendo el ejemplo del anterior punto, el carácter “>” se puede representar también como “&gt”, “%3E”, o “&#x3E”. Es conveniente normalizar todo el texto, antes de aplicar los filtros. La librería ESAPI dispone de la función canonicalize() para pasar una cadena directamente a ASCII.
  • Controla el tamaño de la entrada: no sólo es recomendable controlar que entra, si no también cuanto. Con esto, se evita cualquier problema de denegación de servicio, por saturar al servidor con una entrada enorme, y también de los peligrosos de desbordamientos de buffer.

Como veis, son bastantes las consideraciones que hay que tener en cuenta para que nuestra aplicación sea robusta de cara a los datos que entren. No obstante, una vez comprendida la posible vulnerabilidad y su riesgo, es fácil aplicarle la medida correcta.

Productividad para pentesters

Continuando con la temática mi post anterior, me gustaría hablaros de esos temas que ayudan a mejorar la calidad de un pentest, pero que no se suelen encontrar en los manuales. Con la experiencia, acabas adquiriendo conocimientos que no te ha proporcionado un libro o un paper, esos hábitos que coges a lo largo de sucesivos proyectos, que has adoptado porque lo probaste una vez y te funcionó.

A continuación voy a enumerar unos cuantos hábitos que a mí personalmente me han funcionado de maravilla.

  • Conviértete en maestro shaolin de las herramientas que uses de forma cotidiana. ¿Sabías que en Burp Suite, con CTRL+SHIFT+U hace URL decode al texto seleccionado? Hay muchos atajos de teclado de acciones repetitivas que te harán trabajar más rápido. En la última Hack In Paris 2013 hubo una ponencia muy interesante sobre tips & tricks de Burp Suite, que recomiendo su lectura. Tómate tu tiempo en aprovechar todas las características de herramientas como vim, metasploit, gimp, o muy importante, el procesador de textos, para hacer el informe.
  • [Read more…]

Test de intrusión: Informe de resultados

Hoy día, tenemos disponible gran cantidad de material sobre temas relacionados con test de intrusión: cursos, libros, webs especializadas, etc. Todos explican que las fases de un pentest comienzan con la recogida de información, y terminan con la post-explotación y el borrado de evidencias, básicamente. Sin embargo, la mayoría de publicaciones que enseñan a hacer pentest, fallan en una parte importantísima: la elaboración del informe de resultados.

Está claro: es la parte más aburrida. Es mucho más entretenido trabajar con una shell que con un procesador de textos, ¿verdad? ;-) Es vital tener bien claro que el informe es, en última instancia, es el producto que se le entrega al cliente. Si no somos capaces de plasmar y reflejar en texto el trabajo realizado, por muy bueno que sea el proceso seguido y el resultado obtenido, con un informe mediocre el esfuerzo habrá sido en balde. Por eso me he animado a comentar los puntos claves para rematar la faena, con un informe de calidad.

Para explicar el informe de resultados, antes hay que tener en cuenta un documento previo: el plan de pruebas. Este documento, que debe estar aprobado por el cliente, es la autorización para poder auditar lícitamente un recurso que no es tuyo. En él se describe básicamente qué se va a hacer, y hasta donde se va a llegar. Sin este documento firmado por el cliente, podríamos meternos en un buen lío. Incluye:

  • Ámbito de las pruebas. Qué se audita y qué se queda fuera.
  • Rangos de IP, tanto del cliente como de los auditores.
  • Planificación temporal, días y horas en las que tendrá lugar.
  • Personas de contacto. A quién llamar en caso de que algo caiga.
  • Tipos de pruebas, si se está autorizado a lanzar ataques DoS o de ingeniería social.
  • Propósito del pentest: para qué se va a hacer, qué se quiere conseguir.

Una vez aprobado el plan de pruebas, ya tenemos luz verde para empezar con el test de intrusión. ¡Comienza la diversión!

OK. Ya está todo probado. Tenemos nuestras notas, capturas de pantalla, logs, y demás evidencias de las vulnerabilidades encontradas. Ahora, como ya hemos comentado, toca la parte de transformar toda esta información en un documento y que el cliente conozca todo lo que has descubierto.

En primer lugar, hay que preguntarse: ¿A quién va dirigido este informe? ¿Personal técnico? ¿Directivo? ¿Ambos? Por regla general, los informes de resultados van a ser leídos por varios departamentos, con perfiles muy diferentes. Por ello será necesario redactar una parte, con un resumen ejecutivo, sin entrar en detalles y otra parte con un análisis de las vulnerabilidades.

En el resumen ejecutivo, se enumerarán las vulnerabilidades encontradas. Según su criticidad, se pueden usar colores, puntuaciones, gráficos, etcétera, cuanto más visual, más claro quedará. Recordad que esta sección debe redactarse en un lenguaje lo menos técnico posible. Se deben incluir también las recomendaciones generales para mitigar las vulnerabilidades, sin extenderse en detalles, y finalmente las conclusiones. Esta parte está relacionada con el plan de pruebas y el propósito del pentest. Respondería a preguntas como ¿puede salir la aplicación web a producción? ¿Es la red de mi organización razonablemente segura?

La otra parte del informe es el análisis de las vulnerabilidades. Aquí es donde se debe describir con todo lujo de detalles cuales han sido las pruebas realizadas, qué ha conseguido explotarse, adjuntar capturas de pantalla que lo demuestren, y una valoración del impacto, probabilidad de ocurrencia, y riesgo asociado a cada vulnerabilidad. Por último, unas recomendaciones sobre cómo mitigar la vulnerabilidad, sin escatimar en referencias. Nos puede ser muy útil el post de nuestro compañero David sobre el uso de gimp para capturas de pantalla en los pentest.

Finalmente, también puede ser recomendable incluir un apéndice, con información ampliada que no sea esencial para describir las vulnerabilidades descubiertas, como resultados de herramientas, logs, etc y un glosario de términos, para aquellos acrónimos o términos técnicos relevantes.

Una vez terminado el informe, hay que recordar que la información contenida en el documento es muy sensible. El documento debe advertir claramente que su contenido tiene carácter confidencial. Por una parte, debe enviarse al cliente por una vía segura y cifrada, y por otra parte, es nuestra responsabilidad almacenar el informe con los permisos únicamente de los implicados en el proyecto.

Espero que hayan sido de utilidad estas indicaciones. Información ampliada e informes de ejemplo pueden encontrarse en los siguientes enlaces (en inglés):

Ejemplo informe de pentest Offensive Security [PDF]
SANS Reading Room, Writing a Penetration Testing Report [PDF]
Writing penetration testing resports
The penetration testing report

Libro: Traffic Analysis with Tshark How-to

El libro que me gustaría comentar ha caído hace pocos días en mis manos y se titula “Traffic Analysis with Tshark How-to” cuyo autor es nada menos que nuestro compañero del blog Borja Merino (@BorjaMerino).

Este libro trata, como es evidente, sobre el uso de la herramienta Tshark, la versión de línea de comandos de Wireshark, y de la que ya hemos hablado en alguna ocasión (Registro forense de red con tshark). Aunque Borja cubre un gran abanico de temas, incluye algunos ejemplos que muestran formas de capturar tráfico, la localización problemas de saturación de red, uso de filtros para buscar evidencias concretas, detectar ataques de red o la utilización de la herramienta como apoyo al hacer fuzzing a una aplicación.

Se explica de forma atractiva puesto que se presenta en forma de receta y después la explicación de qué estamos haciendo, o como lo titulan en la forma del libro “How to do it” y “How it works”. También se etiquetan las secciones por su utilidad e importancia, de la forma “recomendable”, “imprescindible” y “conviértete en experto”, de modo que permite identificar aquellos aspectos por su importancia de cara al grado de utilización de la herramienta que vaya a hacer el usuario.

Eso sí, es necesario leerlo con un equipo y una shell delante para asimilar toda la información que recoge en tan poco espacio, ya que el material es de alto nivel técnico, con explicaciones prácticas y ejemplos útiles sobre situaciones comunes para cualquier administrador de sistemas, incident handler o para cualquiera que quiera aprender o mejorar su kung-fu en tshark.

En definitiva, una lectura totalmente recomendada, a la altura del nivel técnico del autor.

Análisis de estadísticas de red como herramienta de detección de incidentes

Las estadísticas de red, o network flows, son datos recopilados del tráfico de una red que básicamente suele consistir en registros de cada una de las conexiones. Pueden ser IP origen y destino, protocolo, número de paquetes enviados/recibidos, tiempo de conexión, etc. Esta información se almacena en base de datos para sacar estadísticas, muy útiles para los administradores de red, y también como vamos a explicar hoy, para la gestión de incidentes.

Usualmente estos datos pueden exportarse directamente de la electrónica de red, en formato sFlow o NetFlow, este último formato propietario de Cisco. Algunas aplicaciones usuales para manejar estos datos suelen ser SiLK o Argus.

¿Qué ventajas tiene un gestor de estadísticas de red?

  • Recopila información sobre el tráfico, sin tener que capturar ni esnifar.
  • No importa si el tráfico va cifrado.
  • Es fácil de implementar.
  • Actúa como histórico para usarlo de consulta.
  • Es un excelente complemento para un IDS o IPS.

Con esta información, es posible detectar incidentes que se hayan producido si sabemos qué buscar y cómo buscarlo. Por poner un ejemplo, se podría hacer un timeline bastante preciso de una intrusión o verificar después de la contención de una infección que ésta ha sido efectiva. Veamos algunas técnicas para buscar posibles incidentes:

  • Filtrado: Se pueden acotar los datos a una IP concreta que previamente hemos detectado como sospechosa. De este modo se puede tener un registro detallado de su actividad, y deducir si sus acciones han sido maliciosas. También podría filtrarse por una franja horaria o un puerto concreto que sabemos opera algún malware determinado.
  • Tráfico normal vs tráfico anómalo: identificando cual es el tráfico normal en una red, se puede identificar de forma sutil el tráfico anómalo y potencialmente malicioso a toda actividad que se salga del patrón habitual. Tráfico entrante hacia un puerto no identificado puede traducirse a un posible backdoor en un servidor. Así también sería posible detectar algún indicio de ataque dirigido.
  • “Dirty Values”: En análisis forense es habitual disponer una lista de valores predefinida a buscar. Como aquí no se tiene el contenido del tráfico, los patrones a buscar serían, por ejemplo, listados de direcciones IP maliciosas, como las disponibles en abuse.ch o Shadowserver.
  • Patrones de actividad: los incidentes de seguridad suelen identificarse por un comportamiento muy concreto. Conociendo el patrón que siguen, se puede detectar. Si la tarea se automatiza y se parametriza de acuerdo al entorno de la organización, se tendría una poderosa herramienta de detección de incidentes.

Con las técnicas descritas, a modo de ejemplo vamos a enumerar varios casos de incidentes y sus comportamientos habituales:

Botnets / Malware:

  • Incremento de peticiones DNS, mucho más de lo usual, o más que los demás hosts. Típico para el malware que usa fast-flux.
  • Tráfico SMTP, RPC, SMB o IRC inusual.
  • Tráfico de 1 origen y N destinos.

Escaneos

  • Tráfico de 1 origen y N destinos y excesivos paquetes SYN sin contestar.

DDOS

  • Tráfico de N orígenes y 1 destino y excesivos paquetes SYN sin contestar.

Fuga de datos / Servidor comprometido

  • Mucho tráfico saliente hacia una única IP.
  • Tráfico en horario poco habitual.

Más información: