Skip to content

Commit 32b918e

Browse files
committed
Now checking registry values + minor fixes
1 parent 7d746a8 commit 32b918e

File tree

1 file changed

+102
-26
lines changed

1 file changed

+102
-26
lines changed

vmdetect/windows.go

Lines changed: 102 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -3,26 +3,19 @@
33
package vmdetect
44

55
import (
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

Comments
 (0)