CVE-2022–41544 — Unauthenticated RCE in Get-Simple

vsociety
10 min readJun 22, 2023

--

Introduction

CVE : CVE-2022–41544

Description: GetSimple CMS v3.3.16 was discovered to contain a remote code execution (RCE) vulnerability via the edited_file parameter in admin/theme-edit.php.

Version: v3.3.16 and the lasted in this time

Product: Get-Simple CMS

Based on fofa (a cyberspace search engine), using the filter (body=" content=\\\"GetSimple" || body=" Powered by GetSimple") approximately 4,276 instances are found using this vulnerable version, which is publicly exploitable as shown bellow

What is GetSimple CMS ?

GetSimple CS is an open-source, light content manager without database, Ideal for small websites and user-friendly customizable templates, built in PHP language

Let’s set up the testing Lab and start hunting for some fun!

Building The Testing Lab

I will use Ubuntu as the local host server to host the app,

for downloading the CMS code you can get it from the offical repositroy or execute the following command:

wget https://github.com/GetSimpleCMS/GetSimpleCMS/archive/refs/tags/v3.3.16.tar.gz

and install the essentials CMS components like (apache2, mysql, php..etc) to run the application:

sudo apt-get install apache2 wget guzip php7.2 libapache2-mod-php7.2 php7.2-common php7.2-mbstring php7.2-xmlrpc php7.2-soap php7.2-gd php7.2-xml php7.2-cli php7.2-curl php7.2-zip -y

extract and move the application files to the /var/www/html/ directory

and setup the files permission by the following

sudo chown -R www-data:www-data /var/www/html/CMS

sudo chmod -R 755 /var/www/html/CMS/

And after completing the preparation steps above, check the status of the Apache2 server and byy visiting localhost by the application’s file name. you should see something similar like the following

then make an account:

And the application will generate a random password for you to use when logging into the admin panel as shown below:

login using the username and the pass

time to reviwing the code and spot the root case in the static analysis

Static Analysis

The directory tree of the application is structured as follows

And as mentioned in the CVE Description the vulnerability exists in admin/theme-edit.php file in the theme edit HTTP request and this file which is the responsible file for editing themes in the GetSimple CMS panel.

Therefore by reviewing the code for the theme edit request, which handles the HTTP request form in the theme-edit.php file to understand how it works as the following

The code first checks for a form submission by validating the CSRF token to avoid a Cross-site Request Forgery attack (CSRF) by checking if the nonce value exists in the POST request parameter or not If the nonce value exists, the code checks if it’s a valid or not using the check_nonce() function. If the nonce value is invalid, the script prints an error message saying "CSRF detected!" and stops processing of the request.

and by looking at the check_nonce() function code which exists in admin/inc/security_functions.php as shown bellow

In the function body, the code calls the get_nonce() function, which is responsible for generating the nonce value and then returning it. so the check_nonce() compares between the the nonce value sent by the user in the HTTP request and the true nonce value which is returned by get_nonce() function.

so to understand how the application generates and obtains the nonce parameter value. which was returned by get_nonce() function and we need to review the code of the function which is existed in file admin/inc/security_functions.php as shown bellow

the function generates a unique and time-limited nonce value by concatenating the $action, $file, $uid, $USR, $SALT variables and the current date@date('YmdH',$time) to ensure the nonce value is unique and secure and then hashing it to the SHA-1 and return its value.

so after understanding how the application generates the nonce value and processes it to prevent CSRF attacks let’s return to reviewing the code for the vulnerable theme edit HTTP request which is located in the theme-edit.php file as mentioned earlier.

i found the code responsible for editing the file to be modified and saving its value, which starts at line 55, as the following

first the code retrieves the name of the theme template file to be edited from the edited_file parameter in the HTTP POST request and next it retrieves the contents of the file to be saved from the content parameter in the HTTP POST request.

Then, the code opens the file specified in the edited_file parameter using the fopen() PHP built-in function and writes the content parameter values into it using the fwrite() PHP built-in function which is used for writing to an open file.

The vulnerable part of the code is when it uses fopen to open a file with write permission (w) during the theme-edit process. This means that anyone with access to the theme-edit functionality can potentially write to the server and it's normal for file upload functions but there is another issue that makes it more dangerous the edited_file value is not filtered/santizated, which could lead to a directory traversal attack that gives the attacker to manipulate this value to write to files outside of the intended directory and potentially overwrite any file in the root directory

Reproducing the Vulnerability as a PoC

by login into the GetSimple panel then go to Edit Theme

save the template to intercept the request with Burp Suite and replace some of its content with our own web shell or code as shown below

after inspecting the request in burp suite, modify the edited_file parameter value to another file and i edited it to ../hack.php and then modify the content parameter with the code/content you want to upload to the crafted file which is hack.php and in this case we will upload the phpinfo() to proof the bug

and go to uploaded file hack.php as demonstrated in the following picture and this mean vulnerability exploited successfully

but still, this vulnerability requires the attacker to have an admin user in the Get-simple panel to access this vulnerable functionality so let’s see how the Authentication works in the Runtime to bypass it and achieve a RCE (Remote Code Execution)

Dynamic Analysis

time to Debugging the application to get a solid understanding of the application flow and the Authentication process

I will use PhpStorm and Xdebug chrome extension in the debugging

And you can get the Xdebug form this here

Setting up the Debugging

after installing Xdebug on your system using the following Command

sudo apt-get install php-xdebug

Next edit the configuration file located at /etc/php/7.2/mods-available/xdebug.ini and add the following lines

zend_extension="xdebug.so"
xdebug.remote_enable = 1
xdebug.remote_port = 9000
xdebug.idekey = PHPSTORM
xdebug.show_error_trace = 1
xdebug.remote_autostart = 0

These settings configure Xdebug for remote debugging with PHPStorm like communication port, enable error traces, and disable automatic starting of remote debugging sessions.

Now, open the extension and choose the Debug option as shown below

And start the debugging listing for the xdebug connection

Accept the connection request from Xdebug the in php storm and I will start the debugging process from the admin/index.php because it's considered the entry-point for the Web app

After the login process, the debugger shows that the app calls another function from a different file, which is the login_cookie_check() function, as shown in the previous screenshot. This function is located in the admin/inc/cookie_functions.php path and is responsible for checking cookies when the admin logs in:

login_cookie_check()

As shown in the function body, it uses two other functions: create_cookie() and cookie_check() and if cookie_check() returns true, then it will call the create_cookie() function. Both functions are located in the same file so let's dive deeper into this code to gain a full understanding of the cookie creation and checking process.

create_cookie()

GetSimple CMS uses two cookies:

  1. the first cookie name is GS_ADMIN_USERNAME and its value is the admin username
  2. the second cookie’s name is stored in the $saltCOOKIE variable which contains the hashed SHA-1 values of the $cookie_name variable concatenated with the $SALT variable. The value of this cookie is stored in the $saltUSR variable which contains the hashed SHA-1 values of the $USR variable concatenated with the $SALT variable.

to understand the second cookie’s name and value generation, we first need to determine the values of the $SALT and $cookie_name variables. so let's start by finding the $SALT value. To do this, i will search for the $SALT = keyword in all CMS files. and i already found the $SALT assignment in the code in the /admin/inc/common.php file, as shown below:

The code checks if the GSUSECUSTOMSALT constant is defined or not. If it is defined the $SALT value will be the constant value (custom admin salt). If it is not defined the $SALT value is auto-generated and retrieved directly from the authorization.xml file, which is contain the CMS app API key.

and to disable the auto-generation of the SALT value and use a custom value instead, admin will assign his custom SALT value to the GSUSECUSTOMSALT constant that exists in the gsconfig.php file.

now that we know how the $SALT value is generated, let’s determine how the $cookie_name variable value is generated. To do this, i searched through all CMS files for the $cookie_name variable assignment using the keyword $cookie_name =, I found it defined in the configuration.php file, as shown below in line 16:

The $cookie_name variable value is generated by combining the SiteName (getsimple), the _cookie_ word, and the CMS version without dots (e.g., 3316).

so the complete $cookie_name value is ‘getsimple_cookie_3316’.

And as mentioned earlier the application combines these variables $SALT,$USR (admin username) and hashes SHA1 them to generate the cookie value.

the final form of the cookie looks like the following, where the second name and value represent the hashed $saltCOOKIE and $saltUSR variables

And the another function used in the login_cookie_check() function is the cookie_check() function:

cookie_check()

The cookie_check() function verifies the validity of the cookie by checking the values used in both the cookie_create() function and the application code. It returns true if the cookie is valid and indicates that the user is logged in and false if the cookie is invalid

going back to the main function for theme edit after getting authenticated to the application,

edited_file parameter which is vulnerable to Path Traversal as explained earlier

as we can see, the value of the file is passed without any filtration, which allows the attacker to change the directory of uploaded files anywhere they choose and also change its value.

GetSimpleCMS works on apache server and it’s a common server for php language, the default configuration of the Apache HTTP Server no longer includes the AllowOverride directive, meaning that any .htaccess files in your directory structure will be ignored so as a result, unauthorized users may gain access to restricted information, leading to the exposure of sensitive data. (information disclosure)

the default setting for apache server existed in /etc/apache2/apache2.conf was like the following:

The AllowOverride directive was set to None and this allowed unauthorized users to access sensitive information like api_key which exists in /data/other/authorization.xml and access the apikey and this key was used to generate the cookie as explained in the dynamic analysis above

With all the information we’ve obtained, we can now write an exploit for the CVE to regenerate the admin’s cookie and upload a web shell. The details of this exploit will be discussed in a another post.

Mitigation

unfortunately, there is no patch or updates for this Vulnrable version yet but there are ways to limit the vulnerability to achive the RCE by disabling some functions like exec, system by editing the php.ini file to prevent the common simple web shells to execute commands on the system

Conclusion

As we saw during the analysis, GetSimple CMS was not Simple to debug because there are many functions related to each other in different places, which makes it a bit difficult to trace. After mixing multiple vulnerabilities, such as Path Traversal and Information Disclosure, we were able to bypass the Authentication and upload a web shell anywhere under the root directory.

References

https://github.com/advisories/GHSA-c599-8gm5-c2jh

https://github.com/GetSimpleCMS/GetSimpleCMS

--

--

vsociety
vsociety

Written by vsociety

vsociety is a community centered around vulnerability research