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/post/windows/gather/checkvm.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::Post
7
include Msf::Post::Windows::Process
8
include Msf::Post::Windows::Registry
9
include Msf::Auxiliary::Report
10
11
def initialize(info = {})
12
super(
13
update_info(
14
info,
15
'Name' => 'Windows Gather Virtual Environment Detection',
16
'Description' => %q{
17
This module attempts to determine whether the system is running
18
inside of a virtual environment and if so, which one. This
19
module supports detection of Hyper-V, VMWare, VirtualBox, Xen, QEMU,
20
and Parallels.
21
},
22
'License' => MSF_LICENSE,
23
'Author' => [
24
'Carlos Perez <carlos_perez[at]darkoperator.com>',
25
'Aaron Soto <aaron_soto[at]rapid7.com>'
26
],
27
'Platform' => [ 'win' ],
28
'SessionTypes' => %w[meterpreter powershell shell],
29
'References' => [
30
['URL', 'https://handlers.sans.org/tliston/ThwartingVMDetection_Liston_Skoudis.pdf'],
31
['URL', 'https://www.heise.de/security/downloads/07/1/1/8/3/5/5/9/vmde.pdf'],
32
['URL', 'https://evasions.checkpoint.com/techniques/registry.html']
33
],
34
'Notes' => {
35
'Stability' => [CRASH_SAFE],
36
'Reliability' => [],
37
'SideEffects' => []
38
}
39
)
40
)
41
end
42
43
# enumerates through a list of VM signature processes and compares them to
44
# the processes running, returns true upon a match.
45
def processes_exist?(vm_processes)
46
vm_processes.each do |x|
47
@processes.each do |p|
48
return true if p['name'].casecmp?(x)
49
end
50
end
51
false
52
end
53
54
# loops over a list of services that are known to be signatures of vm's and
55
# compares them to the list of running services.
56
def services_exist?(vm_services)
57
vm_services.each do |srvc|
58
return true if service_exists?(srvc)
59
end
60
false
61
end
62
63
def service_exists?(service)
64
@services.include?(service)
65
end
66
67
# registers relevant keys and stores them in a hash
68
def register_keys(key_list)
69
@keys = {}
70
key_list.each do |k|
71
srvals = get_srval(k)
72
srvals = [] if srvals.nil?
73
@keys.store(k, srvals)
74
end
75
@keys
76
end
77
78
# checks the values of the keys and compares them to vm_k
79
def key_present?(vm_k)
80
@keys.each_value do |v|
81
return true if v.include?(vm_k)
82
end
83
false
84
end
85
86
def get_srval(key)
87
srvals = registry_enumkeys(key)
88
srvals = [] if srvals.nil?
89
srvals
90
end
91
92
# returns true if regval matches a regex
93
def regval_match?(key, val, rgx)
94
return true if get_regval_str(key, val) =~ rgx
95
96
false
97
end
98
99
# returns true if regval is eql to a string
100
def regval_eql?(key, val, str)
101
get_regval_str(key, val) == str
102
end
103
104
def get_regval_str(key, valname)
105
ret = registry_getvaldata(key, valname)
106
if ret.is_a?(Array)
107
ret = ret.join
108
end
109
ret
110
end
111
112
def parallels?
113
@system_bios_version = get_regval_str('HKLM\\HARDWARE\\DESCRIPTION\\System', 'SystemBiosVersion')
114
115
@video_bios_version = get_regval_str('HKLM\\HARDWARE\\DESCRIPTION\\System', 'VideoBiosVersion')
116
117
if @system_bios_version =~ /parallels/i || @video_bios_version =~ /parallels/i
118
return true
119
end
120
121
false
122
end
123
124
def hyperv?
125
physical_host = get_regval_str('HKLM\\SOFTWARE\\Microsoft\\Virtual Machine\\Guest\\Parameters', 'PhysicalHostNameFullyQualified')
126
127
if physical_host
128
report_note(
129
host: session,
130
type: 'host.physicalHost',
131
data: { physicalHost: physical_host },
132
update: :unique_data
133
)
134
135
print_good("This is a Hyper-V Virtual Machine running on physical host #{physical_host}")
136
return true
137
end
138
139
sfmsvals = registry_enumkeys('HKLM\\SOFTWARE\\Microsoft')
140
if sfmsvals
141
%w[Hyper-V VirtualMachine].each do |vm|
142
return true if sfmsvals.include?(vm)
143
end
144
end
145
146
if @system_bios_version =~ /vrtual/i || @system_bios_version == 'Hyper-V'
147
return true
148
end
149
150
keys = %w[HKLM\\HARDWARE\\ACPI\\FADT HKLM\\HARDWARE\\ACPI\\RSDT HKLM\\HARDWARE\\ACPI\\DSDT]
151
152
register_keys(keys)
153
154
return true if key_present?('VRTUAL')
155
156
hyperv_services = %w[vmicexchange]
157
158
return true if services_exist?(hyperv_services)
159
160
false
161
end
162
163
def vmware?
164
vmware_services = %w[
165
vmdebug vmmouse VMTools VMMEMCTL tpautoconnsvc
166
tpvcgateway vmware wmci vmx86
167
]
168
169
return true if services_exist?(vmware_services)
170
171
@system_manufacturer = get_regval_str('HKLM\\HARDWARE\\DESCRIPTION\\System\\BIOS',
172
'SystemManufacturer')
173
174
return true if @system_manufacturer =~ /vmware/i
175
176
@scsi_port_1 = get_regval_str('HKLM\\HARDWARE\\DEVICEMAP\\Scsi\\Scsi Port 1\\Scsi Bus 0\\Target Id 0\\Logical Unit Id 0',
177
'Identifier')
178
179
return true if @scsi_port_1 =~ /vmware/i
180
181
return true if regval_match?(
182
'HKLM\\SYSTEM\\ControlSet001\\Control\\Class\\{4D36E968-E325-11CE-BFC1-08002BE10318}\\0000',
183
'DriverDesc',
184
/cl_vmx_svga|VMWare/i
185
)
186
187
188
vmwareprocs = [
189
'vmtoolsd.exe',
190
'vmwareservice.exe',
191
'vmwaretray.exe',
192
'vmwareuser.exe'
193
]
194
195
return true if processes_exist?(vmwareprocs)
196
197
false
198
end
199
200
def virtualbox?
201
vboxprocs = [
202
'vboxservice.exe',
203
'vboxtray.exe'
204
]
205
206
vbox_srvcs = %w[VBoxMouse VBoxGuest VBoxService VBoxSF VBoxVideo]
207
208
if services_exist?(vbox_srvcs) || processes_exist?(vboxprocs)
209
return true
210
end
211
212
return true if key_present?('VBOX__')
213
214
for i in 0..2 do
215
return true if regval_match?(
216
"HKLM\\HARDWARE\\DEVICEMAP\\Scsi\\Scsi Port #{i}0\\Scsi Bus 0\\Target
217
Id 0\\Logical Unit Id 0",
218
'Identifier',
219
/vbox/i
220
)
221
end
222
223
return true if @system_bios_version =~ /vbox/i || @video_bios_version =~ /virtualbox/i
224
225
@system_product_name = get_regval_str('HKLM\\HARDWARE\\DESCRIPTION\\System\\BIOS', 'SystemProductName')
226
227
return true if @system_product_name =~ /virtualbox/i
228
229
false
230
end
231
232
def xen?
233
xenprocs = [
234
'xenservice.exe'
235
]
236
237
xen_srvcs = %w[xenevtchn xennet xennet6 xensvc xenvdb]
238
239
if processes_exist?(xenprocs) || services_exist?(xen_srvcs)
240
return true
241
end
242
243
return true if key_present?('Xen')
244
245
return true if @system_product_name =~ /xen/i
246
247
false
248
end
249
250
def qemu?
251
if @system_bios_version =~ /qemu/i || @video_bios_version =~ /qemu/i
252
return true
253
end
254
255
if @scsi_port_0 =~ /qemu|virtio/i || @system_manufacturer =~ /qemu/i
256
return true
257
end
258
259
return true if regval_match?(
260
'HKLM\\HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0',
261
'ProcessorNameString',
262
/qemu/i
263
)
264
265
return true if key_present?('BOCHS_')
266
267
false
268
end
269
270
def report_vm(hypervisor)
271
print_good("This is a #{hypervisor} Virtual Machine")
272
report_note(
273
host: session,
274
type: 'host.hypervisor',
275
data: { hypervisor: hypervisor },
276
update: :unique_data
277
)
278
report_virtualization(hypervisor)
279
end
280
281
def run
282
print_status('Checking if the target is a Virtual Machine ...')
283
@processes = get_processes
284
@processes = [] if @processes.nil?
285
286
@services = registry_enumkeys('HKLM\\SYSTEM\\ControlSet001\\Services')
287
@services = [] if @services.nil?
288
289
if parallels?
290
report_vm('Parallels')
291
elsif hyperv?
292
report_vm('Hyper-V')
293
elsif vmware?
294
report_vm('VMware')
295
elsif virtualbox?
296
report_vm('VirtualBox')
297
elsif xen?
298
report_vm('Xen')
299
elsif qemu?
300
report_vm('Qemu/KVM')
301
else
302
print_status('The target appears to be a Physical Machine')
303
end
304
end
305
end
306
307