Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve post/windows/gather/checkvm #18179

Merged
merged 14 commits into from
Sep 6, 2023
116 changes: 68 additions & 48 deletions modules/post/windows/gather/checkvm.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ def initialize(info = {})
'Description' => %q{
This module attempts to determine whether the system is running
inside of a virtual environment and if so, which one. This
module supports detection of Hyper-V, VMWare, Virtual PC,
VirtualBox, Xen, and QEMU.
module supports detection of Hyper-V, VMWare, VirtualBox, Xen, QEMU,
and Parallels.
},
'License' => MSF_LICENSE,
'Author' => [
Expand All @@ -26,6 +26,11 @@ module supports detection of Hyper-V, VMWare, Virtual PC,
],
'Platform' => [ 'win' ],
'SessionTypes' => %w[meterpreter powershell shell],
'References' => [
['URL', 'https://handlers.sans.org/tliston/ThwartingVMDetection_Liston_Skoudis.pdf'],
['URL', 'https://www.heise.de/security/downloads/07/1/1/8/3/5/5/9/vmde.pdf'],
['URL', 'https://evasions.checkpoint.com/techniques/registry.html']
],
'Notes' => {
'Stability' => [CRASH_SAFE],
'Reliability' => [],
Expand All @@ -36,16 +41,25 @@ module supports detection of Hyper-V, VMWare, Virtual PC,
end

def get_services
@services ||= registry_enumkeys('HKLM\SYSTEM\ControlSet001\Services')
@services ||= registry_enumkeys('HKLM\\SYSTEM\\ControlSet001\\Services')
@services
end

def service_exists?(service)
get_services && get_services.include?(service)
end

def get_regval_str(key, valname)
ret = registry_getvaldata(key, valname)
if ret.kind_of(Array)
jheysel-r7 marked this conversation as resolved.
Show resolved Hide resolved
ret = ret.join
end
ret
end


def hyperv?
physical_host = registry_getvaldata('HKLM\SOFTWARE\Microsoft\Virtual Machine\Guest\Parameters', 'PhysicalHostNameFullyQualified')
physical_host = get_regval_str('HKLM\\SOFTWARE\\Microsoft\\Virtual Machine\\Guest\\Parameters', 'PhysicalHostNameFullyQualified')
if physical_host
report_note(
host: session,
Expand All @@ -57,15 +71,15 @@ def hyperv?
return true
end

sfmsvals = registry_enumkeys('HKLM\SOFTWARE\Microsoft')
sfmsvals = registry_enumkeys('HKLM\\SOFTWARE\\Microsoft')
if sfmsvals
return true if sfmsvals.include?('Hyper-V')
return true if sfmsvals.include?('VirtualMachine')
end

return true if registry_getvaldata('HKLM\HARDWARE\DESCRIPTION\System', 'SystemBiosVersion') =~ /vrtual/i
return true if get_regval_str('HKLM\\HARDWARE\\DESCRIPTION\\System', 'SystemBiosVersion') =~ /vrtual/i

%w[HKLM\HARDWARE\ACPI\FADT HKLM\HARDWARE\ACPI\RSDT].each do |key|
%w[HKLM\\HARDWARE\\ACPI\\FADT HKLM\\HARDWARE\\ACPI\\RSDT].each do |key|
srvvals = registry_enumkeys(key)
return true if srvvals && srvvals.include?('VRTUAL')
end
Expand All @@ -74,27 +88,31 @@ def hyperv?
return true if service_exists?(service)
end

key_path = 'HKLM\HARDWARE\DESCRIPTION\System'
system_bios_version = registry_getvaldata(key_path, 'SystemBiosVersion')
key_path = 'HKLM\\HARDWARE\\DESCRIPTION\\System'
system_bios_version = get_regval_str(key_path, 'SystemBiosVersion')
return true if system_bios_version && system_bios_version.include?('Hyper-V')

key_path = 'HKLM\HARDWARE\DEVICEMAP\Scsi\Scsi Port 0\Scsi Bus 0\Target Id 0\Logical Unit Id 0'
return true if registry_getvaldata(key_path, 'Identifier') =~ /Msft Virtual Disk 1.0/i
key_path = 'HKLM\\HARDWARE\\DEVICEMAP\\Scsi\\Scsi Port 0\\Scsi Bus 0\\Target Id 0\\Logical Unit Id 0'
return true if get_regval_str(key_path, 'Identifier') =~ /Msft Virtual Disk 1.0/i

false
end

def vmware?
%w[vmdebug vmmouse VMTools VMMEMCTL].each do |service|
%w[vmdebug vmmouse VMTools VMMEMCTL tpautoconnsvc tpvcgateway vmware wmci vmx86].each do |service|
return true if service_exists?(service)
end

return true if registry_getvaldata('HKLM\HARDWARE\DESCRIPTION\System\BIOS', 'SystemManufacturer') =~ /vmware/i
return true if registry_getvaldata('HKLM\HARDWARE\DEVICEMAP\Scsi\Scsi Port 0\Scsi Bus 0\Target Id 0\Logical Unit Id 0', 'Identifier') =~ /vmware/i
return true if get_regval_str('HKLM\\HARDWARE\\DESCRIPTION\\System\\BIOS', 'SystemManufacturer') =~ /vmware/i
return true if get_regval_str('HKLM\\HARDWARE\\DEVICEMAP\\Scsi\\Scsi Port 0\\Scsi Bus 0\\Target Id 0\\Logical Unit Id 0', 'Identifier') =~ /vmware/i
return true if get_regval_str('HKLM\\HARDWARE\\DEVICEMAP\\Scsi\\Scsi Port 1\\Scsi Bus 0\\Target Id 0\\Logical Unit Id 0', 'Identifier') =~ /vmware/i
return true if get_regval_str('HKLM\\SYSTEM\\ControlSet001\\Control\\Class\\{4D36E968-E325-11CE-BFC1-08002BE10318}\\0000', 'DriverDesc') =~ /cl_vmx_svga|VMWare/i

vmwareprocs = [
'vmwareuser.exe',
'vmwaretray.exe'
'vmtoolsd.exe',
'vmwareservice.exe',
'vmwaretray.exe',
'vmwareuser.exe'
]
get_processes.each do |x|
vmwareprocs.each do |p|
Expand All @@ -105,24 +123,6 @@ def vmware?
false
end

def virtualpc?
%w[vpc-s3 vpcbus vpcuhub msvmmouf].each do |service|
return true if service_exists?(service)
end

vpcprocs = [
'vmusrvc.exe',
'vmsrvc.exe'
]
get_processes.each do |x|
vpcprocs.each do |p|
return true if p == x['name'].downcase
end
end

false
end

def virtualbox?
vboxprocs = [
'vboxservice.exe',
Expand All @@ -134,17 +134,20 @@ def virtualbox?
end
end

%w[HKLM\HARDWARE\ACPI\DSDT HKLM\HARDWARE\ACPI\FADT HKLM\HARDWARE\ACPI\RSDT].each do |key|
%w[HKLM\\HARDWARE\\ACPI\\DSDT HKLM\\HARDWARE\\ACPI\\FADT HKLM\\HARDWARE\\ACPI\\RSDT].each do |key|
srvvals = registry_enumkeys(key)
return true if srvvals && srvvals.include?('VBOX__')
end

key_path = 'HKLM\HARDWARE\DEVICEMAP\Scsi\Scsi Port 0\Scsi Bus 0\Target Id 0\Logical Unit Id 0'
return true if registry_getvaldata(key_path, 'Identifier') =~ /vbox/i
for i in 0..2 do
return true if get_regval_str("HKLM\\HARDWARE\\DEVICEMAP\\Scsi\\Scsi Port #{i}0\\Scsi Bus 0\\Target Id 0\\Logical Unit Id 0", 'Identifier') =~ /vbox/i
end

return true if registry_getvaldata('HKLM\HARDWARE\DESCRIPTION\System', 'SystemBiosVersion') =~ /vbox/i
return true if get_regval_str('HKLM\\HARDWARE\\DESCRIPTION\\System', 'SystemBiosVersion') =~ /vbox/i
return true if get_regval_str('HKLM\\HARDWARE\\DESCRIPTION\\System', 'VideoBiosVersion') =~ /virtualbox/i
return true if get_regval_str('HKLM\\HARDWARE\\DESCRIPTION\\System\\BIOS', 'SystemProductName') =~ /virtualbox/i

%w[VBoxMouse VBoxGuest VBoxService VBoxSF].each do |service|
%w[VBoxMouse VBoxGuest VBoxService VBoxSF VBoxVideo].each do |service|
return true if service_exists?(service)
end

Expand All @@ -161,7 +164,7 @@ def xen?
end
end

%w[HKLM\HARDWARE\ACPI\DSDT HKLM\HARDWARE\ACPI\FADT HKLM\HARDWARE\ACPI\RSDT].each do |key|
%w[HKLM\\HARDWARE\\ACPI\\DSDT HKLM\\HARDWARE\\ACPI\\FADT HKLM\\HARDWARE\\ACPI\\RSDT].each do |key|
srvvals = registry_enumkeys(key)
return true if srvvals && srvvals.include?('Xen')
end
Expand All @@ -170,24 +173,41 @@ def xen?
return true if service_exists?(service)
end

return true if get_regval_str('HKLM\\HARDWARE\\DESCRIPTION\\System\\BIOS', 'SystemProductName') =~ /xen/i

false
end

def qemu?
key_path = 'HKLM\HARDWARE\DEVICEMAP\Scsi\Scsi Port 0\Scsi Bus 0\Target Id 0\Logical Unit Id 0'
return true if registry_getvaldata(key_path, 'Identifier') =~ /qemu|virtio/i
key_path = 'HKLM\\HARDWARE\\DEVICEMAP\\Scsi\\Scsi Port 0\\Scsi Bus 0\\Target Id 0\\Logical Unit Id 0'
return true if get_regval_str(key_path, 'Identifier') =~ /qemu|virtio/i

key_path = 'HKLM\HARDWARE\DESCRIPTION\System\CentralProcessor\0'
return true if registry_getvaldata(key_path, 'ProcessorNameString') =~ /qemu/i
key_path = 'HKLM\\HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0'
return true if get_regval_str(key_path, 'ProcessorNameString') =~ /qemu/i

%w[HKLM\HARDWARE\ACPI\DSDT HKLM\HARDWARE\ACPI\FADT HKLM\HARDWARE\ACPI\RSDT].each do |key|
return true if get_regval_str('HKLM\\HARDWARE\\DESCRIPTION\\System', 'SystemBiosVersion') =~ /qemu/i
return true if get_regval_str('HKLM\\HARDWARE\\DESCRIPTION\\System', 'VideoBiosVersion') =~ /qemu/i
return true if get_regval_str('HKLM\\HARDWARE\\DESCRIPTION\\System\\BIOS', 'SystemManufacturer') =~ /qemu/i

%w[HKLM\\HARDWARE\\ACPI\\DSDT HKLM\\HARDWARE\\ACPI\\FADT HKLM\\HARDWARE\\ACPI\\RSDT].each do |key|
srvvals = registry_enumkeys(key)
return true if srvvals && srvvals.include?('BOCHS_')
end

false
end

def parallels?
jvoisin marked this conversation as resolved.
Show resolved Hide resolved
bios_version = get_regval_str('HKLM\\HARDWARE\\DESCRIPTION\\System', 'SystemBiosVersion')
if bios_version.kind_of?(Array)
bios_version = bios_version.join
end
return true if bios_version =~ /parallels/i
return true if get_regval_str('HKLM\\HARDWARE\\DESCRIPTION\\System', 'VideoBiosVersion') =~ /parallels/i

false
end

def report_vm(hypervisor)
print_good("This is a #{hypervisor} Virtual Machine")
report_note(
Expand All @@ -202,12 +222,12 @@ def report_vm(hypervisor)
def run
print_status('Checking if the target is a Virtual Machine ...')

if hyperv?
if parallels?
report_vm('Parallels')
elsif hyperv?
report_vm('Hyper-V')
elsif vmware?
report_vm('VMware')
jvoisin marked this conversation as resolved.
Show resolved Hide resolved
elsif virtualpc?
report_vm('VirtualPC')
elsif virtualbox?
report_vm('VirtualBox')
elsif xen?
Expand Down