33package vmdetect
44
55import (
6+ "errors"
67 "fmt"
78 "golang.org/x/sys/windows/registry"
89 "os"
910 "path"
11+ "path/filepath"
1012 "strings"
1113)
1214
13- func doesRegistryKeyExist (key string ) bool {
14-
15- subkeyPrefix := ""
16-
17- // Handle trailing wildcard
18- if key [len (key )- 1 :] == "*" {
19- key , subkeyPrefix = path .Split (key )
20- subkeyPrefix = subkeyPrefix [:len (subkeyPrefix )- 1 ] // remove *
21- }
22-
23- firstSeparatorIndex := strings .Index (key , string (os .PathSeparator ))
24- keyTypeStr := key [:firstSeparatorIndex ]
25- keyPath := key [firstSeparatorIndex + 1 :]
15+ func extractKeyTypeFrom (registryKey string ) (registry.Key , string , error ) {
16+ firstSeparatorIndex := strings .Index (registryKey , string (os .PathSeparator ))
17+ keyTypeStr := registryKey [:firstSeparatorIndex ]
18+ keyPath := registryKey [firstSeparatorIndex + 1 :]
2619
2720 var keyType registry.Key
2821 switch keyTypeStr {
@@ -42,14 +35,62 @@ func doesRegistryKeyExist(key string) bool {
4235 keyType = registry .CURRENT_CONFIG
4336 break
4437 default :
45- PrintError (fmt .Sprintf ("Invalid keytype (%v)" , keyTypeStr ))
38+ return keyType , "" , errors .New (fmt .Sprintf ("Invalid keytype (%v)" , keyTypeStr ))
39+ }
40+
41+ return keyType , keyPath , nil
42+ }
43+
44+ func doesRegistryKeyContain (registryKey string , expectedSubString string ) bool {
45+
46+ keyType , keyPath , err := extractKeyTypeFrom (registryKey )
47+
48+ if err != nil {
49+ PrintError (err )
50+ return false
51+ }
52+
53+ keyPath , keyName := filepath .Split (keyPath )
54+
55+ keyHandle , err := registry .OpenKey (keyType , keyPath , registry .QUERY_VALUE )
56+
57+ if err != nil {
58+ PrintError (fmt .Sprintf ("Cannot open %v : %v" , registryKey , err ))
59+ return false
60+ }
61+
62+ defer keyHandle .Close ()
63+
64+ valueFound , _ , err := keyHandle .GetStringValue (keyName )
65+
66+ if err != nil {
67+ PrintError (err )
68+ }
69+
70+ return strings .Contains (valueFound , expectedSubString )
71+ }
72+
73+ func doesRegistryKeyExist (registryKey string ) bool {
74+
75+ subkeyPrefix := ""
76+
77+ // Handle trailing wildcard
78+ if registryKey [len (registryKey )- 1 :] == "*" {
79+ registryKey , subkeyPrefix = path .Split (registryKey )
80+ subkeyPrefix = subkeyPrefix [:len (subkeyPrefix )- 1 ] // remove *
81+ }
82+
83+ keyType , keyPath , err := extractKeyTypeFrom (registryKey )
84+
85+ if err != nil {
86+ PrintError (err )
4687 return false
4788 }
4889
4990 keyHandle , err := registry .OpenKey (keyType , keyPath , registry .QUERY_VALUE )
5091
5192 if err != nil {
52- PrintError (fmt .Sprintf ("Cannot open %v : %v" , key , err ))
93+ PrintError (fmt .Sprintf ("Cannot open %v : %v" , registryKey , err ))
5394 return false
5495 }
5596
@@ -73,7 +114,7 @@ func doesRegistryKeyExist(key string) bool {
73114
74115 return false
75116 } else {
76- // The key we were looking for has been found
117+ // The registryKey we were looking for has been found
77118 return true
78119 }
79120}
@@ -143,6 +184,35 @@ func checkRegistry() (bool, string) {
143184 `HKLM\SYSTEM\ControlSet001\Services\xenvdb` ,
144185 }
145186
187+ // TODO : fill with https://evasions.checkpoint.com/techniques/registry.html#check-if-keys-contain-strings
188+ blacklistedValuesPerKeyPerVendor := map [string ]map [string ]string {
189+ "Anubis" : {
190+ `HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\ProductID` : "76487-337-8429955-22614" ,
191+ `HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProductID` : "76487-337-8429955-22614" ,
192+ },
193+ "QEMU" : {
194+ `HKLM\HARDWARE\DEVICEMAP\Scsi\Scsi Port 0\Scsi Bus 0\Target Id 0\Logical Unit Id 0\Identifier` : "QEMU" ,
195+ `HKLM\HARDWARE\Description\System\SystemBiosVersion` : "QEMU" ,
196+ `HKLM\HARDWARE\Description\System\VideoBiosVersion` : "QEMU" ,
197+ `HKLM\HARDWARE\Description\System\BIOS\SystemManufacturer` : "QEMU" ,
198+ },
199+ "VirtualBox" : {
200+ `HKLM\HARDWARE\DEVICEMAP\Scsi\Scsi Port 0\Scsi Bus 0\Target Id 0\Logical Unit Id 0\Identifier` : "VBOX" ,
201+ `HKLM\HARDWARE\DEVICEMAP\Scsi\Scsi Port 1\Scsi Bus 0\Target Id 0\Logical Unit Id 0\Identifier` : "VBOX" ,
202+ `HKLM\HARDWARE\DEVICEMAP\Scsi\Scsi Port 2\Scsi Bus 0\Target Id 0\Logical Unit Id 0\Identifier` : "VBOX" ,
203+ `HKLM\HARDWARE\Description\System\SystemBiosVersion` : "VBOX" ,
204+ `HKLM\HARDWARE\Description\System\VideoBiosVersion` : "VIRTUALBOX" ,
205+ `HKLM\HARDWARE\Description\System\BIOS\SystemProductName` : "VIRTUAL" ,
206+ `HKLM\SYSTEM\ControlSet001\Services\Disk\Enum\DeviceDesc` : "VBOX" ,
207+ `HKLM\SYSTEM\ControlSet001\Services\Disk\Enum\FriendlyName` : "VBOX" ,
208+ `HKLM\SYSTEM\ControlSet002\Services\Disk\Enum\DeviceDesc` : "VBOX" ,
209+ `HKLM\SYSTEM\ControlSet002\Services\Disk\Enum\FriendlyName` : "VBOX" ,
210+ `HKLM\SYSTEM\ControlSet003\Services\Disk\Enum\DeviceDesc` : "VBOX" ,
211+ `HKLM\SYSTEM\ControlSet003\Services\Disk\Enum\FriendlyName` : "VBOX" ,
212+ `HKLM\SYSTEM\CurrentControlSet\Control\SystemInformation\SystemProductName` : "VIRTUAL" ,
213+ },
214+ }
215+
146216 allKeys := [][]string {hyperVKeys , parallelsKeys , virtualBoxKeys , virtualPCKeys , vmwareKeys , xenKeys }
147217
148218 for _ , keys := range allKeys {
@@ -153,18 +223,25 @@ func checkRegistry() (bool, string) {
153223 }
154224 }
155225
226+ for /*vendor*/ _ , registryValuesPerPath := range blacklistedValuesPerKeyPerVendor {
227+ for registryPath , expectedValue := range registryValuesPerPath {
228+ if doesRegistryKeyContain (registryPath , expectedValue ) {
229+ return true , registryPath + " contains " + expectedValue
230+ }
231+ }
232+ }
233+
156234 return false , "none"
157235}
158236
159- func checkFileSystem () bool {
237+ func checkFileSystem () ( bool , string ) {
160238 // check for known path on the filesystem, either files or directories
161239 generalPath := []string {
162240 `c:\take_screenshot.ps1` ,
163241 `c:\loaddll.exe` ,
164242 `c:\symbols\aagmmc.pdb` ,
165243 }
166244
167-
168245 prlPath := []string {
169246 `c:\windows\system32\drivers\prleth.sys` ,
170247 `c:\windows\system32\drivers\prlfs.sys` ,
@@ -201,26 +278,25 @@ func checkFileSystem() bool {
201278 `c:\windows\system32\drivers\vmxnet.sys` ,
202279 `c:\windows\system32\drivers\vmhgfs.sys` ,
203280 `c:\windows\system32\drivers\vmx86.sys` ,
204- `c:\windows\system32\drivers\hgfs.sys`
281+ `c:\windows\system32\drivers\hgfs.sys` ,
205282 }
206283
207284 virtualpcPath := []string {
208285 `c:\windows\system32\drivers\vmsrvc.sys` ,
209- `c:\windows\system32\drivers\vpc-s3.sys`
286+ `c:\windows\system32\drivers\vpc-s3.sys` ,
210287 }
211288
212289 allPath := [][]string {virtualpcPath , prlPath , vmwarePath , vboxPath , generalPath }
213290
214291 for _ , paths := range allPath {
215- for _ , path := range paths {
216- if DoesFileExist (path ) {
217- return true , path
292+ for _ , p := range paths {
293+ if DoesFileExist (p ) {
294+ return true , p
218295 }
219296 }
220297 }
221298
222299 return false , "none"
223-
224300}
225301
226302/*
@@ -236,8 +312,8 @@ func IsRunningInVirtualMachine() (bool, string) {
236312 return vmDetected , fmt .Sprintf ("Registry key (%v)" , registryKey )
237313 }
238314
239- if vmDetected , path := checkFileSystem (); vmDetected {
240- return vmDetected , fmt .Sprintf ("Path (%v)" , path )
315+ if vmDetected , filePath := checkFileSystem (); vmDetected {
316+ return vmDetected , fmt .Sprintf ("Known path found (%v)" , filePath )
241317 }
242318
243319 return false , "nothing"
0 commit comments