pluck-cms / pluck

Central repo for pluck cms
http://www.pluck-cms.org
56 stars 39 forks source link

Pluck-4.7.15 admin background exists a remote command execution vulnerability when uploading files #98

Closed l0ners closed 2 years ago

l0ners commented 3 years ago

I uploaded any file in the "manage files" section, here I uploaded a "1.jpg".

image

Found two files at the upload folder.

image

Looked at the source code for the delete file function. On lines 21 and 22 of "data/in/deletefile.php", the logic is that the file ".htaccess" is not allowed to be deleted. But it can be bypassed.

image

I clicked on the delete button on the page for "1.jpg" and sniffered the packet.

image

Change the value of the request parameter "var" to ".Htaccess" (the suffix name is not case sensitive in Windows)

image

".Htaccess" is already in the trash.

image

The ".htaccess" in the upload folder has been copied to the trash folder.

image

Looked at the source code for the upload function, lines 34 to 52 of "data/in/file.php".

image

The code logic is as follows.

  1. First check if the file suffix is ".htaccess".
  2. then check if the file suffix is in the blacklist.
  3. If the suffix is in the blacklist, add the suffix ".txt" for renaming and give permission.
  4. If the suffix name is not in the blacklist, then give permission directly.

Use race condition for attacks. First I create a "phpinfo.php" file. poc: <?php phpinfo();?>

image

Upload the file and sniffer a packet of the upload request and send it to intruder (add variable a=1 to keep sniffering the request packet).

image

Then sniffer a packet that accesses the file and send it to intruder.

image

Both intruder types are selected as "Numbers" and the number is 10000.

image

Threads are set to 20. image

Start the attack, when the status of the request to access the file is 200, it means that the file was uploaded successfully and the code was executed.

image

image

Upload webshell with race condition and successfully gain access to the server. exploit:

image

image

(Note: the ".php" file only exists when the race condition is in place, if the race condition is stopped the ".php" file will still be a ".php.txt" file, so the shell will disconnect. The shell will then disconnect. (So maintaining permissions requires that race condition be maintained at all times)

From: huanyu@tsign.cn

BSteelooper commented 3 years ago

Could you please retest with this version? pluck-4.7.16-dev1.tar.gz

l0ners commented 3 years ago

您能重新测试这个版本吗? pluck-4.7.16-dev1.tar.gz

Ok, after testing, I can't delete ".htaccess".

l0ners commented 3 years ago

But I don't think it's good enough to use ".htaccess" to block access to ".php" type files, because it only works in apache and if I use nginx I can ignore it.

BSteelooper commented 3 years ago

How would you resolve this for ngnix? There it is a server config which we cannot control.

l0ners commented 3 years ago

您如何解决ngnix的问题? 这是我们无法控制的服务器配置。

The core of the solution is to make the upload folder unexecutable. My idea is to let the user choose whether the server is apache or nginx when installing the program, and if it is nginx, the program automatically or the user manually modifies the nginx configuration to make the upload folder unexecutable. Finally add a detection function to disallow the installation if the folder is executable. Sorry, I'm not a professional developer and not good at development, so I don't know if my idea is possible.

BSteelooper commented 3 years ago

The folder and the contents is not executed, PHP parses a php file and is the executer, not the file itself. that is why the .htaccess file disables php engine as a whole. For Nginx the contents of the .htaccess file needs to be included in the server config in another way. What we could do is make an instruction in the setup when we detect Nginx to modify the config with a set of config, but as I can find there is no way to detect if this configuration is made. With apache, we can pull it into the project and prevent some thing, but with Nginx this must be done by the person installing it.

l0ners commented 3 years ago

The folder and the contents is not executed, PHP parses a php file and is the executer, not the file itself. that is why the .htaccess file disables php engine as a whole. For Nginx the contents of the .htaccess file needs to be included in the server config in another way. What we could do is make an instruction in the setup when we detect Nginx to modify the config with a set of config, but as I can find there is no way to detect if this configuration is made. With apache, we can pull it into the project and prevent some thing, but with Nginx this must be done by the person installing it.

Can the php installer modify nginx.conf?

BSteelooper commented 3 years ago

It would be very bad if this would be possible since the install.php is just a script which lives as part of the website. The config of the webserver should not be available for the install script.

l0ners commented 3 years ago

如果这是可能的话,那将是非常糟糕的,因为install.php只是一个脚本,它作为网站的一部分存在。Web服务器的配置不应用于安装脚本。

Well, I don't have a good solution for now, I'll contact you later when I think of one.

l0ners commented 3 years ago

您能重新测试这个版本吗? pluck-4.7.16-dev1.tar.gz

I was able to successfully bypass and delete the .htaccess. The effect of the new code is to make the file name lowercase. 代码新增

Adding "/" to the file name successfully bypasses the restriction and removes the .htaccess. 增加斜杠 The next steps of the attack are the same as above, so I won't repeat them.

BSteelooper commented 3 years ago

Could you perform a retest with the latest dev version?