Skip to content

Commit 8294984

Browse files
committed
Some cleaning + read /dev/kmsg
1 parent 6f303c2 commit 8294984

File tree

6 files changed

+64
-107
lines changed

6 files changed

+64
-107
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,8 @@
1111
# Output of the go coverage tool, specifically when used with LiteIDE
1212
*.out
1313

14+
# Goland
15+
.idea/
16+
1417
# Dependency directories (remove the comment below to include it)
1518
# vendor/

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,5 @@ Coming soon...
1717
## Resources
1818

1919
![systemd-detect-virt source code](https://github.com/systemd/systemd/blob/master/src/basic/virt.c)
20+
2021
![Malware evasion techniques](https://www.deepinstinct.com/2019/10/29/malware-evasion-techniques-part-2-anti-vm-blog/)

main.go

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,19 @@
11
package main
22

33
import (
4-
"VMDetect/vmdetect"
4+
"VM-Detection/vmdetect"
55
"fmt"
66
)
77

88
func main() {
9-
fmt.Println("Trying to vmdetect if a VM is running...")
9+
fmt.Println("Trying to detect if a VM is running...")
1010

11-
isInsideVM, reason, err := vmdetect.IsRunningInVirtualMachine()
12-
13-
if err != nil {
14-
panic(err)
15-
}
11+
isInsideVM, reason := vmdetect.IsRunningInVirtualMachine()
1612

1713
if isInsideVM {
18-
fmt.Printf("VM detected thanks to %v\n", reason)
14+
fmt.Printf("\nVM detected thanks to %v\n", reason)
1915
} else {
20-
fmt.Println("No VM has been detected")
16+
fmt.Println("\nNo VM detected")
2117
}
2218

2319
}

vmdetect/common.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package vmdetect
2+
3+
import "fmt"
4+
5+
func PrintError(loggee interface{}) {
6+
fmt.Printf("[x] %v\n", loggee)
7+
}
8+
9+
func PrintWarning(loggee interface{}) {
10+
fmt.Printf("[!] %v\n", loggee)
11+
}

vmdetect/linux.go

Lines changed: 41 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,85 +1,72 @@
1-
// +build linux darwin
1+
// +build linux
22

33
package vmdetect
44

55
import (
66
"bytes"
7-
"fmt"
7+
"os"
88
"os/exec"
9-
"os/user"
109
)
1110

1211
/*
13-
Checks if the program is being run using root.
14-
*/
15-
func isRunningWithAdminRights() (bool, error) {
16-
if currentUser, err := user.Current(); err != nil {
17-
return false, err
18-
} else {
19-
return currentUser.Uid == "0", nil
12+
Checks if the DMI table contains vendor strings of known VMs.
13+
*/
14+
func checkDMITable() bool {
15+
// TODO : instead of running a command, read files in /sys/class/dmi/id/* and look for vendor strings below
16+
output, err := exec.Command("dmidecode").Output()
17+
18+
if err != nil {
19+
PrintError(err)
20+
return false
2021
}
22+
23+
return bytes.Contains(output, []byte("innotek")) ||
24+
bytes.Contains(output, []byte("VirtualBox")) ||
25+
bytes.Contains(output, []byte("vbox"))
2126
}
2227

2328
/*
24-
Tries to vmdetect VM using privileged access.
25-
*/
26-
func privilegedChecks() (bool, string, error) {
29+
Checks printk messages to see if Linux detected an hypervisor.
30+
*/
31+
func checkKernelRingBuffer() bool {
2732

28-
output, err := exec.Command("dmidecode").Output()
33+
file, err := os.Open("/dev/kmsg")
2934

30-
if err == nil &&
31-
(bytes.Contains(output, []byte("innotek")) ||
32-
bytes.Contains(output, []byte("VirtualBox")) ||
33-
bytes.Contains(output, []byte("vbox"))){
34-
return true, "dmidecode", nil
35+
if err != nil {
36+
PrintError(err)
37+
return false
3538
}
3639

37-
output, err = exec.Command("dmesg").Output()
40+
buffer := make([]byte, 1024*8)
3841

39-
if err == nil && bytes.Contains(output, []byte("Hypervisor detected")) {
40-
return true, "dmesg", nil
41-
}
42-
43-
return false, "", nil
44-
}
45-
46-
/*
47-
Tries to vmdetect VM using unprivileged access.
48-
*/
49-
func unprivilegedChecks() (bool, string, error) {
50-
output, err := exec.Command("hostnamectl").Output()
42+
// Only reads the first 100 lines (reading character device in Go is annoying)
43+
for i := 0; i < 100; i++ {
44+
if _, err = file.Read(buffer); err != nil {
45+
PrintError(err)
46+
return false
47+
}
5148

52-
if err == nil && bytes.Contains(output, []byte(" vm\n")) {
53-
return true, "hostnamectl", nil
49+
if bytes.Contains(buffer, []byte("Hypervisor detected")) {
50+
return true
51+
}
5452
}
5553

56-
return false, "", nil
54+
return false
5755
}
5856

5957
/*
6058
Public function returning true if a VM is detected.
6159
If so, a non-empty string is also returned to tell how it was detected.
62-
*/
63-
func IsRunningInVirtualMachine() (bool, string, error) {
64-
isAdmin, err := isRunningWithAdminRights()
60+
*/
61+
func IsRunningInVirtualMachine() (bool, string) {
6562

66-
if err != nil {
67-
return false, "", err
63+
if checkDMITable() {
64+
return true, "DMI Table"
6865
}
6966

70-
if isAdmin {
71-
vmDetected, reason, err := privilegedChecks()
72-
73-
if err != nil {
74-
return false, "", err
75-
}
76-
77-
if vmDetected {
78-
return true, reason, nil
79-
}
80-
} else {
81-
fmt.Println("[WARNING] Running as unprivileged user")
67+
if checkKernelRingBuffer() {
68+
return true, "Kernel Ring Buffer"
8269
}
8370

84-
return unprivilegedChecks()
85-
}
71+
return false, "nothing"
72+
}

vmdetect/windows.go

Lines changed: 3 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -2,51 +2,10 @@
22

33
package vmdetect
44

5-
/*
6-
Checks if the program is being run in a privileged context.
7-
*/
8-
func isRunningWithAdminRights() (bool, error) {
9-
return false, nil
10-
}
11-
12-
/*
13-
Tries to vmdetect VM using privileged access.
14-
*/
15-
func privilegedChecks() (bool, string, error) {
16-
return false, "", nil
17-
}
18-
19-
/*
20-
Tries to vmdetect VM using unprivileged access.
21-
*/
22-
func unprivilegedChecks() (bool, string, error) {
23-
return false, "", nil
24-
}
25-
265
/*
276
Public function returning true if a VM is detected.
287
If so, a non-empty string is also returned to tell how it was detected.
298
*/
30-
func IsRunningInVirtualMachine() (bool, string, error) {
31-
isAdmin, err := isRunningWithAdminRights()
32-
33-
if err != nil {
34-
return false, "", err
35-
}
36-
37-
if isAdmin {
38-
vmDetected, reason, err := privilegedChecks()
39-
40-
if err != nil {
41-
return false, "", err
42-
}
43-
44-
if vmDetected {
45-
return true, reason, nil
46-
}
47-
} else {
48-
fmt.Println("[WARNING] Running as unprivileged user")
49-
}
50-
51-
return unprivilegedChecks()
52-
}
9+
func IsRunningInVirtualMachine() (bool, string) {
10+
return false, "nothing"
11+
}

0 commit comments

Comments
 (0)