Skip to content

Commit 6c8966b

Browse files
committed
spoofability report
1 parent 02f6744 commit 6c8966b

4 files changed

Lines changed: 379 additions & 229 deletions

File tree

README.md

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -26,16 +26,6 @@ The library is:
2626
- Contains separate MIT and GPL-3.0 compliant library header files
2727

2828

29-
> [!NOTE]
30-
> The library doesn't guarantee it'll be accurate. I've received a lot of false positives in the past from various people, and it's impossible to 100% detect a VM either due to:
31-
- VM artifacts such as system files being left from past VM usage depending on the brand
32-
- Unfamiliar mechanisms that are not widely known
33-
-
34-
35-
If you found a false positive or a false negative then please create an issue with information on what your VM is, what OS you're using, and other relevant details.
36-
>
37-
38-
3929
<br>
4030

4131
## Example 🧪

docs/documentation.md

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -45,14 +45,24 @@ int main() {
4545
bool is_vm3 = VM::detect(VM::CPU_BRAND, VM::MAC, VM::HYPERVISOR_BIT);
4646

4747

48+
/**
49+
* There are roughly 1/3 of all techniques that are considered to be "spoofable",
50+
* meaning that anybody can potentially cause a false positive by exploiting the
51+
* fact that the "spoofable" techniques checks for things that anybody can modify
52+
* (file, registry, directories, etc...). This category of techniques are disabled
53+
* by default, but they can be enabled with the VM::SPOOFABLE flag.
54+
*/
55+
bool is_vm4 = VM::detect(VM::SPOOFABLE);
56+
57+
4858
/**
4959
* All checks are performed including the cursor check,
5060
* which waits 5 seconds for any human mouse interaction
5161
* to detect automated virtual environments. This is the
5262
* only technique that's disabled by default but if you're
5363
* fine with having a 5 second delay, add VM::ALL
5464
*/
55-
bool is_vm4 = VM::detect(VM::ALL);
65+
bool is_vm5 = VM::detect(VM::ALL);
5666

5767

5868
/**
@@ -63,29 +73,29 @@ int main() {
6373
* caching will be operated when you're not going to re-use the previously
6474
* stored result at the end.
6575
*/
66-
bool is_vm5 = VM::detect(VM::NO_MEMO);
76+
bool is_vm6 = VM::detect(VM::NO_MEMO);
6777

6878

6979
/**
7080
* This will set the threshold bar to detect a VM higher than the default threshold.
7181
* Use this if you want to be extremely sure if it's a VM, but this can risk the result
7282
* to be a false negative. Use VM::percentage() for a more precise result if you want.
7383
*/
74-
bool is_vm6 = VM::detect(VM::HIGH_THRESHOLD);
84+
bool is_vm7 = VM::detect(VM::HIGH_THRESHOLD);
7585

7686

7787
/**
7888
* If you want to disable any technique for whatever reason, use VM::DISABLE(...).
7989
* This code snippet essentially means "perform all the default flags, but only
8090
* disable the VM::RDTSC technique".
8191
*/
82-
bool is_vm7 = VM::detect(VM::DISABLE(VM::RDTSC));
92+
bool is_vm8 = VM::detect(VM::DISABLE(VM::RDTSC));
8393

8494

8595
/**
8696
* Same as above, but you can disable multiple techniques at the same time.
8797
*/
88-
bool is_vm8 = VM::detect(VM::DISABLE(VM::VMID, VM::RDTSC, VM::HYPERVISOR_BIT));
98+
bool is_vm9 = VM::detect(VM::DISABLE(VM::VMID, VM::RDTSC, VM::HYPERVISOR_BIT));
8999

90100

91101
/**
@@ -99,14 +109,14 @@ int main() {
99109
* For further information, please check the VM::ENABLE_HYPERV_HOST flag information
100110
* in the non-technique flags section (situated around the end of this documentation).
101111
*/
102-
bool is_vm9 = VM::detect(VM::ENABLE_HYPERV_HOST);
112+
bool is_vm10 = VM::detect(VM::ENABLE_HYPERV_HOST);
103113

104114

105115
/**
106116
* This is just an example to show that you can use a combination of different
107117
* flags and non-technique flags with the above examples.
108118
*/
109-
bool is_vm10 = VM::detect(VM::DEFAULT, VM::NO_MEMO, VM::HIGH_THRESHOLD, VM::DISABLE(VM::RDTSC, VM::VMID));
119+
bool is_vm11 = VM::detect(VM::DEFAULT, VM::NO_MEMO, VM::HIGH_THRESHOLD, VM::DISABLE(VM::RDTSC, VM::VMID));
110120

111121
}
112122
```
@@ -326,7 +336,7 @@ VMAware provides a convenient way to not only check for VMs, but also have the f
326336
| `VM::CTYPE` | Check if the chassis type is valid (it's very often invalid in VMs) | Linux | 10% | | | |
327337
| `VM::DOCKERENV` | Check if /.dockerenv or /.dockerinit file is present | Linux | 80% | | | |
328338
| `VM::DMIDECODE` | Check if dmidecode output matches a VM brand | Linux | 55% | Admin | | |
329-
| `VM::DMESG` | Check if dmesg output matches a VM brand | Linux | 55% | | | |
339+
| `VM::DMESG` | Check if dmesg output matches a VM brand | Linux | 55% | Admin | | |
330340
| `VM::HWMON` | Check if /sys/class/hwmon/ directory is present. If not, likely a VM | Linux | 75% | | | |
331341
| `VM::SIDT5` | Check if the 5th byte after sidt is null | Linux | 45% | | | |
332342
| `VM::CURSOR` | Check if cursor isn't active for 5 seconds (sign of automated VM environment) | Windows | 5% | | | |
@@ -389,7 +399,7 @@ VMAware provides a convenient way to not only check for VMs, but also have the f
389399
| `VM::VMWARE_IOMEM` | Check for VMware string in /proc/iomem | Linux | 65% | | | |
390400
| `VM::VMWARE_IOPORTS` | Check for VMware string in /proc/ioports | Linux | 70% | | | |
391401
| `VM::VMWARE_SCSI` | Check for VMware string in /proc/scsi/scsi | Linux | 40% | | | |
392-
| `VM::VMWARE_DMESG` | Check for VMware-specific device name in dmesg output | Linux | 65% | | | |
402+
| `VM::VMWARE_DMESG` | Check for VMware-specific device name in dmesg output | Linux | 65% | Admin | | |
393403
| `VM::VMWARE_STR` | Check str assembly instruction method for VMware | Windows | 35% | | | |
394404
| `VM::VMWARE_BACKDOOR` | Check for official VMware io port backdoor technique | Windows | 100% | | | 32-bit |
395405
| `VM::VMWARE_PORT_MEM` | Check for VMware memory using IO port backdoor | Windows | 85% | | | 32-bit |
@@ -426,6 +436,7 @@ VMAware provides a convenient way to not only check for VMs, but also have the f
426436
| `VM::ENABLE_HYPERV_HOST` | Windows 11 (and 10 if enabled manually) may have Hyper-V as a default virtualisation solution for any host program even if the OS is running as host. There isn't a way to detect whether the host program is ran in default virtualisation mode, or manually intended virtualisation. This is a Hyper-V specific problem, and the library will use heuristical methods to discard Hyper-V's host virtualiser as not running in a VM by default. But if this flag is enabled then it will still count it regardless of the risk that it might be Hyper-V's default host virtualisation for every host program. So basically this flag means that "I'm aware this program might be running in a default virtualised environment on host, but I'll still count this as running in a VM anyway whether it's default virtualisation or manually intended virtualisation". |
427437
| `VM::MULTIPLE` | This is specific to `VM::brand()`. This will basically return a `std::string` message of what brands could be involved. For example, it could return "`VMware or VirtualBox`" instead of having a single brand string output. This has no effect if applied to any other functions than `VM::brand()`. |
428438
| `VM::HIGH_THRESHOLD` | This is specific to `VM::detect()` and `VM::percentage()`, which will set the threshold bar to confidently detect a VM by 3x higher. |
439+
| `VM::SPOOFABLE` | This will enable all the "spoofable" techniques (which are 1/3 of the total amount of techniques) |
429440
430441
<br>
431442
@@ -449,7 +460,10 @@ VMAware provides a convenient way to not only check for VMs, but also have the f
449460
| -c | --conclusion | Prints the conclusion message string |
450461
| -p | --percent | Prints the VM likeliness percentage between 0 and 100 |
451462
| -n | --number | Prints the number of VM detection techniques it can performs |
463+
| -t | --type | Returns the VM type (if a VM was found) |
452464
| | --disable-hyperv-host | Disable the possibility of Hyper-V default virtualisation result on host OS (this can be used as a combination with the above commands) |
465+
| | --disable-notes | No notes will be provided |
466+
| | --spoofable | Allow spoofable techniques to be ran (not included by default)
453467
454468
> [!NOTE]
455469
> If you want a general result of everything combined above, do not put any arguments. This is the intended way to use the CLI tool.

0 commit comments

Comments
 (0)