Archivo de la etiqueta: Retos hacking

RootedCon CTF writeup niveles 7 y 8

Reto 7

Este reto era de ingeniería social y trataba de localizar a alguien. Ahora la prueba está deshabilitada y se pasa de forma rápida:

——————–

La prueba 7 se ha eliminado ya que es necesario estar en la rooted para completarla, es de ingeniería social… y bueno… no es necesario llamar a ese teléfono,… así que para saltarte la prueba este es el resultado de la prueba 7:

——————–

La imagen que había inicialmente era esta:

Así que ahora en lugar de ingeniería social tenemos una imagen que no sabemos si es la que han subido para el reto o es que el enlace está mal. Vamos a http://imageupload.org y cargamos cualquier número aleatorio, con lo que obtenemos la misma imagen. La descargamos y hacemos un diff con la que tenemos y vemos que son iguales. Por tanto, lo que está mal es el enlace a la foto, que supongo será parte del reto.

Bueno, tras un rato probando cosas resultó que el enlace estaba mal porque imageupload no funciona bien y esto no era parte del reto. Así que tras avisar a Pablo, subió bien la imagen, que era un código de barras:

Así que lo leemos desde Linux con el Zbarimg:

La solución para pasar el reto es: 2887188576

Reto 8

El número obtenido en el reto anterior resulta ser una dirección IP, en decimal: 172.23.0.96, que se puede obtener en esta web:

http://www.kloth.net/services/iplocate.php

Hacemos un escaneo a esa web para ver los puertos abiertos:

Nos conectamos como anónimo por FTP a ver qué hay:

El fichero proftpd-howto.conf trae lo siguiente:

La verdad es que me recuerda mucho al reto de Security by Default 🙂

Tenemos información del bug disponible aquí:

http://www.exploit-db.com/exploits/8037/

Consigo acceder con:

user: USER%’) and 1=2 union select 1,1,uid,gid,homedir,shell from ftpuser #

pas: 1

pero veo los mismos datos que antes:

Así que vamos a añadir un LIMIT 1,1 para ver si accedemos con otro usuario:

Por tanto, la clave para el siguiente reto es: I have to drink some beers


RootedCon CTF writeup niveles 5 y 6

Esta vez voy a subir la solución de dos retos en lugar de uno sólo, ya que el nivel 5 es fácil fácil (el más fácil de todo el CTF) … como dijo Pablo Catalina, este venía de regalo xDD

Reto 5

Para este reto tenemos que continuar por donde dejamos el anterior, como viene siendo habitual. Así que vamos a ver lo que trae esa imagen de disco:

Tras abrir el CAP con el wireshark vemos que tiene toda la pinta de ser una captura de una red wifi con encriptación WEP:

Por tanto, vamos a lanzar el aircrack-ng a ver si sacamos la clave:

Como se puede ver, la clave es: 01:01:01:01:01:01:01:01:01:01:01:01:01

Y la contraseña para pasar el reto: 01010101010101010101010101

Reto 6

Ya que tenemos la clave WEP (que por cierto, era de lo más sencilla), vamos a obtener el paquete sin cifrar:

Esto nos genera un nuevo fichero, ya descifrado (captura1-01-dec.cap) con 75.325 paquetes, nada menos. Lo abrimos con Wireshark y vemos que hay muchísimos paquetes TCP con basura (SYN, ACK, RST) pero ningún PSH con información útil. Esto supongo que lo harían para generar algo de tráfico y hacer efectivo un ataque con Aircrack-ng y así poder sacar fácilmente la clave WEP, por lo que vamos a aplicar algunos filtros que nos limpien un poco la basura:

Filtro: tcp.flags.push==1

0 resultados

Como comentaba antes, todos los paquetes TCP están de relleno, así que vamos a quitarlos, junto con los ARP e ICMP:

Filtro: !arp && !icmp && !tcp

17.075 resultados

Siguen apareciendo demasiados paquetes, pero ahora vemos algunas cosas interesantes. Parece que hay capturas de VoIP, así que vamos a filtrar esas capturas:

Filtro: ip.src eq 172.23.0.9 || ip.dst eq 172.23.0.9

Bien, pues parece que tenemos un bonito Asterisk tras todas esas tramas de datos y, como Wireshark trae una herramienta muy buena para VoIP, vamos a usarla. Entramos en Telephony -> VoIP Calls:

Tras escuchar cada una de las conversaciones repetidas veces, me quedo con los siguientes detalles:

  1. Alguien llama a un buzón de voz para escuchar los mensajes. Tenemos los sonidos de dos pines que se introducen.
  2. Parece que dejan el número de teléfono que buscamos en un buzón de voz y no se escucha en las conversaciones de voz capturadas.

——————————

Nota: Yo me quedé aquí en este punto cuando el CTF llegó a su fin. El resto de retos los hice ya desde casa, relajado en una buena silla 🙂

Me quedé atascado porque no le encontré mucho sentido a lo que estaba pasando, es decir, el mensaje decía algo como: ‘… llámame al número de teléfono’ y se cortaba. Luego veremos que el resto del mensaje está en el buzón de voz. La verdad es que no entiendo cómo si alguien deja un mensaje en un buzón de voz, se captura una parte sólo de ese mensaje, pues debería o capturarse todo o no capturarse nada.

Esto me llevó a pensar que era un problema de ruido, así que me dediqué a descargar las voces, convertirlas a WAV y perder mucho tiempo con el Audacity.

——————————

Bien, pues continuando con el reto, parece ser que tenemos que acceder al buzón de voz del usuario para escuchar el número de teléfono que deja como mensaje. Para poder acceder al buzón de un usuario necesitamos 2 cosas. Los datos del usuario (incluida su contraseña) y su PIN. Vamos con ello:

Para extraer los datos del usuario usamos sipdump y sipcrack:

Tras pasar varios diccionarios obtuve las claves de ambos usuarios, que son:

Para el user 1001: 0000aa

Para el user 1002: aa0000

Nota: las claves para cada usuario son las mismas a pesar de tener diferente hash, lo cual nos indica que el MD5 usa algún salt.

Para averiguar el PIN, primero extraemos las voces. En el Wireshark vamos a Telephony -> RTP -> Show All Streams. Luego seleccionamos el paquete y damos a Analyze. Después, Save Payload y guardamos con formato AU.

Abrimos con el Audacity y recortamos la parte que nos interesa:

Una vez que hemos recortado los 2 pines que hemos encontrado, los desciframos con Multimon (click para agrandar la imagen):

El pin de pownme es: 987321

El pin de lamde es: 123654

El siguiente paso es conseguir un software para conectar con el Asterisk. Vamos a usar para ello el Twinkle, que está en el repositorio de Debian.

Si te atascas instalándolo, aquí hay un bonito tutorial:

http://openmaniak.com/trixbox_phone.php#twinkle

Nos conectamos a ambos buzones y en el de lamde escuchamos el número de teléfono que buscábamos y que es la clave para pasar al siguiente reto: 666.699.004


RootedCon CTF writeup nivel 4

Reto 4

Accedemos ahora a la shell de este usuario (pownme) con un su, o simplemente haciendo otra conexión por ssh:

Y vemos lo que tiene en su directorio y a lo que no teníamos acceso:

El fichero comprimido, que descargamos con un scp desde nuestra máquina, parece tener una imagen de un disco que ha sido cifrada con LUKS usando SHA256. Esto lo vemos haciendo un head del fichero o abriéndolo con un editor hexadecimal.

Según la Wikipedia (http://es.wikipedia.org/wiki/LUKS):

——————–

LUKS (de las siglas en inglés, Linux Unified Key Setup) es una especificación de cifrado de disco creado por Clemens Fruhwirth, originalmente destinado para Linux. Mientras la mayoría del software de cifrado de discos implementan diferentes e incompatibles formatos no documentados, LUKS especifica un formato estándar en disco, independiente de plataforma, para usar en varias herramientas. Esto no sólo facilita la compatibilidad y la interoperabilidad entre los diferentes programas, sino que también garantiza que todas ellas implementen gestión de contraseñas en un lugar seguro y de manera documentada.

La implementación de referencia funciona en Linux y se basa en una versión mejorada de cryptsetup, utilizando dm-crypt como la interfaz de cifrado de disco. En Microsoft Windows, los discos cifrados con LUKS pueden ser utilizados con FreeOTFE. Ha sido diseñado para ajustarse a la clave de configuración TKS1 de sistema seguro.

——————–

Pues vamos a tratar de montar esa imagen, de la que por cierto, no tenemos la contraseña ….

Yo nunca había encriptado una unidad por lo que tras documentarme en Google, al final hice:

Una vez tenemos los módulos de crypt, vamos a tratar de montar la imagen. Para ello usaremos loop, que asigna una imagen a un dispositivo, lo que nos permitirá tratarlo como una unidad.

Para ver el primer dispositivo loop libre:

Para usar el dispositivo (con esto asociamos /dev/loop0 con nuestra imagen):

Luego tratamos de montar la imagen (si fuera una imagen normal usaríamos el comando mount, pero al tratarse de un LUKS, debemos usar cryptsetup):

Parece que la imagen está dañada ya que no la reconoce como LUKS. Tras buscar información sobre el formato y compararla con nuestra imagen, vemos claramente que hay una serie de ceros en la cabecera (antes de la palabra LUKS) que no deberían estar, por lo que hacemos una copia de la imagen (por si las moscas) y modificamos esta quitando todos esos ceros:

Para probarlo, desasociamos el dispositivo y lo volvemos a asociar:

Bueno, pues parece que ya tenemos resuelto el primer problema. Ahora queda averiguar cuál es la contraseña. Para ello me creé un pequeño script en Perl:

Lo que hace este script es probar las palabras de un diccionario, parando si consigue montar la unidad. Para ello:

  1. Cargamos el diccionario.
  2. Ejecutamos con un system el cryptsetup usando un pipe y así no tener que meter la contraseña escribiéndola desde la línea de comandos.
  3. Miramos en /dev/mapper si se ha montado el dispositivo, tras lo cual paramos el script y mostramos la última contraseña que se probó, que deberá ser la buena.

Tras unos minutos corriendo con un diccionario de palabras comunes, obtenemos la contraseña, que es: key y que nos sirve para pasar al reto siguiente.

RootedCon CTF writeup nivel 3

Reto 3

Como vimos en el reto anterior, tenemos corriendo un knockd que nos abre un ssh en el puerto 22.

Si no sabes lo que es el port knocking puedes ver cómo funciona aquí: http://es.wikipedia.org/wiki/Golpeo_de_puertos

Como resumen, diré que se trata de un mecanismo de seguridad que oculta ciertos servicios y los abre recibiendo una secuencia mágica de números.

En este caso, todos los puertos que espera knockd son TCP, por lo que para que nos de acceso, le mandaremos la secuencia mágica, para posteriormente conectarnos por ssh:

Accedemos con nuestro usuario y contraseña:

Y analizamos un poco el entorno.

En nuestro directorio no vemos nada de utilidad pero si retrocedemos un directorio, en /home/ hay un segundo usuario cuyo nombre nos incita a entrar 🙂 … su nombre es: pownme

Así que accedemos a su carpeta personal y hacemos un ls -la para ver lo que hay dentro:

Aquí vemos varias cosas interesantes:

  • Un binario que podemos ejecutar con suid de pownme.
  • Un fichero de configuración al que no tenemos acceso.
  • Otro fichero comprimido al que tampoco tenemos acceso.

Todo apunta a que hay que hacer una escalada de privilegios para llegar a ver el contenido de ese fichero comprimido, así que vamos a ver qué hace el binario:

Bueno, pues está claro que se trata de un overflow. Llegados a este punto necesitamos obtener algo de información para ver con qué nos enfrentamos, si tenemos que crear un exploit o simplemente hay que machacar algún dato.

Sacamos algo de información del sistema:

A primera vista ya nos encontramos con varios problemas:

  • Por un lado se trata de una arquitectura de 64 bits.
  • Por otro lado, tenemos activado el randomize_va_space.
  • El binario no tiene permisos de lectura, por lo que no podemos descargarlo a nuestra máquina y usar luego el EDB, IDA Pro o nuestro debugger favorito.
  • No hay ningún depurador instalado en la máquina, por lo que tampoco podemos depurar ahí.

Llegados a este punto sólo nos queda probar a mano:

Tras realizar varias pruebas al final vemos algo interesante introduciendo el usuario seguido de diferentes \x01:

Vemos que ya no da error de permisos pero tampoco saca los datos completos. Así que vamos a probar con \x02:

Y ya, por curiosidad, si ponemos un \x03:

Pues parece hemos sobrescrito en número de líneas a imprimir, a parte de otra cosa, que nos permite ver los datos de otro usuario.

Introducimos el usuario y la contraseña obtenida para pasar el reto: pownme:c@r@m3l0_0.o

———————————————————————————-

Nota: La verdad es que no comprendí muy bien cómo pasé el reto ya que fui probando bytes hasta que ‘de casualidad’ me apareció la contraseña por pantalla.

Ya, por mera curiosidad y, en casita, me descargué el binario (ahora que ya tenemos la contraseña de pownme, es fácil 🙂 y lo abrí con IDA Pro para analizarlo un poco).

Abrimos el binario con el IDA Pro para 64 bits y echamos un ojo al contenido.

>>>> Antes de nada, si meto la pata no me fustiguéis, que los binarios de 64 bits en Linux no son precisamente mi fuerte 😛 <<<<

Bien, pues de momento nos encontramos una función llamada get_value(), que tras entrar en ella podemos ver:

En la cabecera de la función vemos la inicialización de los parámetros usados, que por comodidad he renombrado:

  • nombreDeUsuario es el parámetro de entrada, donde escribimos el nombre de usuario.
  • bufferValidacion (igual el nombre que le he puesto resulta lioso) es, digamos, el umbral a partir del cual te dice si eres un Bad Boy.
  • UIDUsuario es donde se guarda el resultado de la llamada a _getuid.

Un poco más abajo vemos cómo, tras el _getuid, guarda un 0 si no tenemos permisos o un 1 si los tenemos, es decir, por defecto, con el usuario lamde, nos dejaría un 0 y no podríamos ver los datos de pownme:

Y más abajo aún tenemos la verificación de lo que he llamado bufferValidacion, que tendría el valor con el que sobrescribimos pasados los 12 bytes primeros. Y en caso de ser menor de 3, nos aparece el mensaje de ‘Bad Kid’:

Por último, tenemos la verificación de lo que almacenamos anteriormente en UIDUsuario, que como vimos, era un 0 si no tenemos acceso, y un 1 si lo tenemos:

Como podemos apreciar, si vale 0 nos manda al mensaje de ‘You can’t touch this!’ y, en caso contrario, nos mostrará los datos del usuario.

En resumen, nuestra finalidad es cambiar el valor de UIDUsuario para que nos deje mostrar los datos de pownme, pero saltándonos el filtro de bufferValidacion que nos lleva por otro camino para mostrarnos la frase Bad Kid.

Por tanto, una forma de pasarlo directamente sería introduciendo (clickea en la imagen para ampliar):

donde \x70\x6f\x77\x6e\x6d\x65 es pownme.

———————————————————————————-

RootedCon CTF writeup niveles 1 y 2

A petición de Pablo Catalina (@xkill), voy a ir poniendo la solución del CTF por partes. Ahora voy a publicar la solución de los niveles 1 y 2 (en este último es donde más gente ha quedado atascada), y cada semana publicaré un nuevo nivel.

Ahí vamos … 🙂

Reto 1

Al validarse en el reto, a cada participante le aparecía una URL de acceso diferente, ya que cada uno debíamos atacar a una máquina virtual distinta. En mi caso, la URL era http://172.23.23.24 y tras acceder por web, únicamente aparecía la siguiente imagen:


Mirando el código fuente de la página, nada más que se ve esto:

De manera que todo apunta a una prueba de esteganografía.

Lo primero que hice fue bajarme la imagen y hacer un strings para ver si salía algo de texto, luego la analicé con un editor hexadecimal (concretamente con el gHex2) por si aparecía algo extraño. También miré, sin éxito, con el 010 Editor, que trae muchos templates para analizar diferentes formatos de ficheros.

Como no sacaba nada en claro, el siguiente paso fue abrirla con el Gimp y empezar a cambiar tonos, brillos, etc, etc, etc. Tampoco hubo suerte.

Como último recurso, me puse a probar, a voleo, diferentes programas de esteganografía (steghide, xdeview, snowdrop, enscribe, openstego, etc) hasta que di con uno (el outguess) que, al fin, sacó los datos ocultos:

La respuesta para pasar el reto es: Lamde:JodNes=


Reto 2

Al pasar el primer reto se obtiene un usuario y una contraseña, pero nada más. Ningún acceso a una nueva web donde validar esos datos ni nada, así que no queda otra que hacer un escaneo a ver si encontramos algo:

Para ello usé DirBuster: http://www.owasp.org/index.php/Category:OWASP_DirBuster_Project

Tras unos minutos de escaneo encontró el directorio: /backstage con algunos subdirectorios. Tras acceder a él se puede ver el acceso a lo que parece un file manager:

Lo primero que trato de hacer es lo más lógico, dado que en el reto anterior obtuve un usuario y una contraseña, traté de usarlos para entrar, pero me decía que los datos eran incorrectos.

Este reto me llevó casi un día resolverlo. La verdad es que fue una verdadera agonía.

Analizando el código, vi que se trataba de la última versión de PHPFileNavigator v2.3.3 (http://pfn.sourceforge.net/) así que lo primero fue buscar alguna vulnerabilidad conocida en securityfocus, exploit-db, etc, sin éxito. El segundo paso fue descargar los fuentes y analizarlos para ver un poco cómo estaba programado y buscar algún posible bug.

Bajé los fuentes y le eché un ojo a los 3 posibles formularios de entrada:

– El de validación de usuario: index.php

– El de recuperación de contraseña: contrasinal.php

– El de activación de nueva contraseña: activar_contrasinal.php

Todos ellos filtraban bien todos los valores que se obtenían.

Echando un ojo a los PHP que se incluían tampoco encontré forma de inyectar nada ya que en todos tenía un control de sesiones. Así que volví a cargar estos 3 formularios en la web para jugar un poco con ellos.

Me llamó la atención el de recuperación de contraseña, ya que nos avisa si el usuario que introducimos es correcto o no:

Usuario: admin

Correo electrónico: x@x.com

No existe ningún usuario con esos datos, por favor comprueba que el usuario y el correo son correctos.

Usuario: Lamde

Correo electrónico: x@x.com

Este usuario no tiene permisos para cambiar su contraseña, por favor contacta con el administrador.

Usuario: lamde

Correo electrónico: x@x.com

Este usuario no tiene permisos para cambiar su contraseña, por favor contacta con el administrador.

(Nota: Esto es un fallo del reto. Luego explicaré por qué)

Tras perder bastante tiempo con los 3 formularios y, ya bastante desesperado, le pasé un par de fuzzers que tengo programados para buscar fallos de SQLi, ICH, RCE, LFI, RFI por si se me escapaba algo, pero tampoco encontró nada.

Como dije antes, perdí casi un día con este reto y no encontré ninguna vulnerabilidad nueva.

Al final, resultó que el usuario era todo en minúsculas y la contraseña tal cual nos salió en el reto anterior: lamde / JodNes=

(Nota: dije antes que era un fallo del reto porque en ambos casos (con Lamde y con lamde), en la pantalla de recuperación de contraseña, nos dice que el usuario no tiene permisos, cuando en el primer caso debería decir que no existe el usuario, tal y como ocurrió cuando probé con admin (y con otros tantos). Esto fue el motivo por el que perdí tanto tiempo y por el que se quedaron atascados muchos de los participantes.)

Una vez que conseguí acceso al dichoso file manager, se podían ver un montón de ficheros PDF, que supongo estarían para despistar, porque cuando se accede a una web de este tipo, al primer lugar a donde se te van los ojos es a los permisos de escritura. En este caso sí que teníamos permisos, por lo que subí un phpinfo (por mera curiosidad) y una shell.

Como para resolver la prueba pedía: ‘numero, numero, numero, …’, me imaginé que se trataba de un knock, así que tras verificar que el demonio knockd estaba corriendo, el siguiente paso era ver los puertos usados:

Editando con un cat el fichero de configuración /etc/knockd.conf vemos:


Los puertos de desbloqueo y la contraseña para pasar este segundo reto es:

7000,8000,9000,2323,23,65000

Web challenges from RootedCON’2010 CTF

Si eres un apasionado de los retos de hacking, esta tarde a las 20:00 hora española dará comienzo un nuevo reto creado por RoManSoFt y Dreyer que, conociendo a estos dos personajes, la verdad es que proteme ser muy interesante … y también difícil.

Más info del concuro aquí: http://www.rs-labs.com/noticias/#38

Date prisa que sólo quedan unas horas para que de comienzo 🙂