The Synopsys Software Integrity Group is now Black Duck®. Learn More

close search bar

Sorry, not available in this language yet

close language selection

A deep-dive on Pluck CMS vulnerability CVE-2023-25828

Matthew Hogg

May 07, 2023 / 6 min read

CVE-2023-25828 vulnerability; history, mitigation analysis, and everything you need to know about the remote code execution (RCE) vulnerability in Pluck CMS.

Summary

CVE-2023-25828, tracked in the Black Duck KnowledgeBase™ as BDSA-2023-0370, is an authenticated remote code execution vulnerability in Pluck CMS. Pluck is a PHP-based content management system (CMS) used to set up and manage websites. Designed with ease of use and simplicity in mind, Pluck CMS is ideal for running a small website, such as a personal blog. The software has been maintained since 2005 when it was first released under the name CMSsystem, and has received 53 stars since migrating to GitHub in 2014. This vulnerability was discovered by Black Duck Cybersecurity Research Center (CyRC) researchers while auditing the Pluck CMS source code.

Discovery process

Review of the source code was conducted with special attention paid to features that provide file upload functionality. File uploads can be dangerous in many types of applications, but especially so in PHP applications, so this functionality was examined first.

Pluck CMS allows the administrator to upload images.

Pluck CMS Vulnerability CVE-2023-25828 Image Upload Interface for Remote Code Execution Analysis

Figure 1: Uploading an image in Pluck CMS

Browsing the source code of this feature, there is no obvious vulnerability. The mime type and the file extension are checked against an allow list.

Visual Representation of Pluck CMS Vulnerability CVE-2023-25828 Dependency Tree in Black Duck Software Security Analysis Tool

Snippet 1: data/inc/images.php

The question is, has this allow list implementation been used for all file upload functionality? Let’s examine another file upload feature, the albums module image upload. This feature is similar to the image upload functionality, except that images can be collected into albums and added all at once into web pages.

The relevant function of this feature is albums_page_admin_editalbum() in the file data/modules/albums/albums.admin.php.

Snippet 2

Snippet 2: data/modules/albums/albums.admin.php
 

When a file is submitted, the mime type is checked against an allow list.

mime type

Then some processing is performed on the image file name. This determines the position of the ‘ . ’ character, separates the file name from the file extension with specific logic for when the character is not found, performs search engine optimization on the file name, and constructs full paths for the full image and image thumbnail.

Separates file name from file extension

Interestingly, nowhere in this process does the application limit the file extension with an allow list. This immediately raises alarms, since it means a file extension that enables the content of the uploaded file to be interpreted and executed by the underlying web server, such as .php and .phar, can be used without restriction.

There are multiple ways to exploit this behavior using a file extension and valid mime type. A web shell could replace the file contents entirely, be added to the file contents, or be included in image metadata. However, none of these techniques are applicable in this case because of logic later in the function.

Snippet 3

Snippet 3: data/modules/albums.admin.php

The $fullimage path calculated previously is used to instantiate a SmartImage object. Resizing might also seem like an issue, but that can be avoided by providing an image with equal height and width. So let’s examine the SmartImage constructor to see what it does.

Snippet 4

Snippet 4: data/inc/lib/SmartImage.class.php


The __construct function uses the built-in getimagesize PHP-GD function to identify the type of image being processed from the constant assigned by the function. This is accessed via $this->info[2], and a different built-in imagecreatefrom* PHP-GD function is then used to process the image depending on the value of the constant. These functions perform normalization that destroys any naively embedded web shell, such as one appended to the file or inserted into image metadata.

At this point, CyRC researchers looked into the behavior of these imagecreatefrom* functions. Focusing first on imagecreatefromjpeg, they discovered prior research that showed it is possible to embed a web shell in such a manner that it can survive the normalization. The Jellypeg tool can be used to find a location where a small piece of code survived the compression process. The tool achieves this by brute-force searching for an offset where the web shell is still contained within the file contents even after being processed by the imagecreatefromjpeg and imagejpeg functions.

Running the tool with the default configuration, a valid image with the embedded payload <?=exec($_GET[“c”])?> can be found.

Deep-Dive Analysis of Pluck CMS Vulnerability CVE-2023-25828 Showing Embedded Payload

Figure 2: The embedded payload
 

This file will allow the web shell to survive through the normalization performed by imagecreatefromjpeg in the SmartImage constructor. If uploaded with a valid mime type and .php file extension, RCE can be achieved by navigating to the file directly at the web path /pluck/data/settings/modules/albums/<album_name>/<file_name> and passing commands via the HTTP parameter ‘c’. This is a serious vulnerability, as it allows an authenticated attacker to run arbitrary commands on the underlying web server of the application.

Mitigation analysis

The vendor released a patch for this vulnerability in version 4.7.16-dev5 in the commit 8aec080. This replicates the extension allow list implementation in the standard image upload functionality.

Snippet 5

Snippet 5: data/modules/albums/albums.admin.php
 

However, there is an error with this patch. The highlighted characters are dangling, so they introduce a syntax error into the file. When this file is included by other pages in the application, it throws an error, disabling the albums module entirely. Another patch was released in 4.7.17 in the commit a52de9c to correct this syntax error, and this mitigates the vulnerability.

Acknowledgements

We thank Jinny Ramsmark for her work developing Jellypeg.

Read more about CVE-2023-25828

Continue Reading

Explore Topics