wordpress插件wpdiscuz任意文件上傳漏洞分析


下載鏈接

https://downloads.wordpress.org/plugin/wpdiscuz.7.0.3.zip

測試

環境

  • windows phpstudy
  • phpstorm

解壓插件到wp-content/plugins目錄下

登錄管理員啟用插件,這時文章下面評論區

上傳帶GIF頭的php文件

可以看到上傳成功,圖片地址也在回顯中

http://127.0.0.1/wordpress/wp-content/uploads/2020/08/1-1598075857.9448.php

分析

wp-setting.php 將wp_ajax_nopriv_wmuUploadFiles寫入了$wp_filter

foreach ( wp_get_active_and_valid_plugins() as $plugin ) {
 wp_register_plugin_realpath( $plugin );  include_once $plugin;  /**  * Fires once a single activated plugin has loaded.  *  * @since 5.1.0  *  * @param string $plugin Full path to the plugin's main file.  */  do_action( 'plugin_loaded', $plugin ); } 

通過表單action參數插件加載

$action = ( isset( $_REQUEST['action'] ) ) ? $_REQUEST['action'] : '';

wordpress先加載插件

入口文件

上傳的關鍵代碼在wp-content\plugins\wpdiscuz\utils\class.WpdiscuzHelperUpload.php376行

public function uploadFiles() {
…… require_once(ABSPATH . "wp-admin/includes/image.php"); foreach ($files as $file) { $error = false; $extension = pathinfo($file["name"], PATHINFO_EXTENSION); //$extension="php" $mimeType = $this->getMimeType($file, $extension); 

檢測文件mime類型

private function getMimeType($file, $extension) {
 $mimeType = "";  if (function_exists("mime_content_type")) {  $mimeType = mime_content_type($file["tmp_name"]); //image/gif  } elseif (function_exists("finfo_open") && function_exists("finfo_file")) {  $finfo = finfo_open(FILEINFO_MIME_TYPE);  $mimeType = finfo_file($finfo, $file["tmp_name"]);  } elseif ($extension) {  $matches = wp_check_filetype($file["name"], $this->options->content["wmuMimeTypes"]);  $mimeType = empty($matches["type"]) ? "" : $matches["type"];  }  return $mimeType; } 

繼續跟進

……
if ($this->isAllowedFileType($mimeType)) {  if (empty($extension)) { //$extension="php" 沒進入  ……  }  $file["type"] = $mimeType; } else {  …… } do_action("wpdiscuz_mu_preupload", $file); //沒什么用 if (!$error) {  $attachmentData = $this->uploadSingleFile($file); 

isAllowedFileType

private function isAllowedFileType($mimeType) {
 $isAllowed = false;  if (!empty($this->options->content["wmuMimeTypes"]) && is_array($this->options->content["wmuMimeTypes"])) {  $isAllowed = in_array($mimeType, $this->options->content["wmuMimeTypes"]);  }  return $isAllowed; } 

$this->options->content["wmuMimeTypes"] 內容

在數組內

$isAllowed=true

上傳操作在

340行 $attachmentData = $this->uploadSingleFile($file);

uploadSingleFile

private function uploadSingleFile($file) {
$currentTime = WpdiscuzHelper::getMicrotime(); $attachmentData = []; $path = $this->wpUploadsPath . "/"; $fName = $file["name"]; $pathInfo = pathinfo($fName); $realFileName = $pathInfo["filename"]; $ext = empty($pathInfo["extension"]) ? "" : strtolower($pathInfo["extension"]); $sanitizedName = sanitize_file_name($realFileName); $cleanFileName = $sanitizedName . "-" . $currentTime . "." . $ext; $cleanRealFileName = $sanitizedName . "." . $ext; $fileName = $path . $cleanFileName; if (in_array($ext, ["jpeg", "jpg"])) { $this->imageFixOrientation($file["tmp_name"]); } $success = apply_filters("wpdiscuz_mu_compress_image", false, $file["tmp_name"], $fileName, $q = 60); if ($success || @move_uploaded_file($file["tmp_name"], $fileName)) { 

到這里已經把文件上傳了
上傳文件名為原文件名+時間戳+后綴

v7.0.5的改進

isAllowedFileType 對mime的后綴和文件后綴進行比較

private function isAllowedFileType($mimeType, $extension) {
 $isAllowed = false;  if (!empty($this->mimeTypes) && is_array($this->mimeTypes)) {  foreach ($this->mimeTypes as $ext => $mimes) {  if ($ext === $extension) {  if ($isAllowed = in_array($mimeType, explode("|", $mimes))) {  break;  }  }  }  }  return $isAllowed; } 

總結

整個上傳過程只對文件頭進行檢測,並沒有對文件后綴進行檢測,導致可以設置一句話木馬內容為

圖片文件頭+php代碼

,進行getshell


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM