Authenticated Remote Code Execution (RCE) on PluckCMS - 4.7.15

syed
3 min readJun 6, 2023

--

Description:

Found authenticated Remote Code Execution (RCE) on pluck 4.7.15.

Affected Endpoint:

http://192.168.0.211/admin.php?action=files

Evidence:

While reading the source code, I found blacklisted extension are mentioned in the file (data/inc/files.php) at line 44 and 45.

File upload function validating the file extension is match any one of the following extension (.php, php3, php4, php5, php6, php7, phtml, .phtm, .pht, .ph3, .ph4, .ph5, .asp, .cgi, .phar). If the extension matched then renaming the file with .txt extension at end.

And there is .htaccess file in files directory (upload file directory) where php_flag engine is disabled. So we can’t ale to execute the file in this directory

For successful exploitation we required to upload web shell without the aforementioned extension and the file should not be in files directory.

So I created a simple webshell with “.inc” extension and upload the file.

Login to the admin account. Use the following URL (http://192.168.0.211/admin.php?action=files) or navigate to pages -> manage files.

Upload the webshell with “.inc” extension.

We already know there is no restriction for file upload if the file extension is aforementioned extension then it will renamed the file. So anyway our webshell is uploaded.

Try to execute the uploaded .inc file, as guessed our file is not executed.

Now we need to move the file to some other directory. While analysing I found that trash directory doesn’t have any validation.

So deleting the file will move webshell to trash directory. So we can able to execute from trash directory.

Once the file is deleted then navigate to the following directory (http://192.168.0.211/data/trash/files/<fileName>) to execute our web shell.

Our web shell executing successfully.

This was fixed on PluckCMS - 4.7.16

Recommendation:

  • Instead of blacklisting the extension use whitelisted extension
  • Remote execution permission from trash directory also.

WebShell Used:

<?php

if (isset($_GET[‘d’])) {

eval(passthru($_GET[‘d’]));

};

--

--