A couple of weeks ago, I teamed up with my buddy, Chi Tran, to do some bug hunting on an open-source CMS application, HorizontCMS. This application was created by @ttimot24. Thank you @ttimot24 for a quick response to our bug reports and allowing us to writing a blog post about them!
Firstly, we installed the HorizontCMS on our testing environment and made it listen on the localhost (127.0.0.1). Then, we configured the Firefox to allow the localhost proxying. (If you didn’t know it already, do the following configuration on your Firefox so that it can proxy the localhost web applications.)
Next, we knew that one of the recently found CVEs for the HorizontCMS was about an arbitrary PHP file upload vulnerability: CVE-2020–27387. So, our initial approach was to see if we could bypass any filetype restrictions that the author had already fixed. This time, the issue was properly mitigated by restricting file extensions like .php
, .php5
, .php7
, .phtml
, .inc
, etc.
However, we found a filetype bypass by using “/
” (e.g., test.php/
) to upload a PHP file.
test.php
file to the “File manager”2. The file gets uploaded; however, it’s renamed to some gibberish
3. Rename the file name from gibberish to test.php/
→ Click “Rename” and we can see that the file name is now changed to test.php
Note: If you just tried to rename the file name as test.php or test.php5, it wouldn’t have worked since the author applied validationRegex() function to fix the original CVE (CVE-2020–27387)
Unfortunately, it wasn’t that easy… When we tried to access the uploaded test.php
file via browser, we ran into the following 404 error page.
So, we wanted to move onto the next interesting function: Plugins.
Many applications use plugins to introduce new features and additional functions; therefore, it might be worth to check if you could upload any malicious plugins to potentially gain RCE. In my experience, for uploading a new plugin, an application may require certain file formats, and this HorizontCMS was too. But luckily, the author had a wiki page that explains how to develop a plugin in detail as well as has a sample plugin! 😎
We did some thorough assessment on how this plugin files were developed, uploaded and deployed onto the application. And we found some vulnerable code within the plugin file where we could introduce our malicious PHP code to cause an RCE.
First, we zipped the sample GoogleMaps plugin provided by the author and uploaded it (As it was uploaded, it got unzipped in the application automatically.)
Then, there was an option to “install” & “activate” the plugin to the application. Once it was done, the plugin was activated and created “Google Maps” under the menu bar.
We observed an “Add location
” function within the Google Maps plugin. When we added an arbitrary location and saved it, it responded with a success message “Location added succesfully!
.”
So, we were curious how the application was handling that process, especially in which condition, it responded with the success message.
We searched for the response within the plugin source files and found the following PHP script (GoogleMaps/resources/lang/en/messages.php
) that looked very obvious to us.The code was basically doing:
Location added succesfully!
”We smelled some potential arbitrary code execution here :]
So, what if we modified this code (within the plugin files that we control) to add a variable called $shell
with a PHP reverse shell, and this variable would be called as the location were successfully added? Sounds promising to me :]
We re-zipped the modified GoogleMaps plugin and uploaded it again. When we added the location this time, we successfully executed our reverse shell and got RCE on the system!