Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,8 @@ Please, if you encounter any of the anti-analysis tricks which you have seen in
- prl_tools.exe(Parallels)
- xenservice.exe(Citrix Xen)
- qemu-ga.exe (QEMU)
- looking-glass-host.exe (GENERIC)
- VDDSysTray.exe (GENERIC)
- **WMI**
- SELECT * FROM Win32_Bios (SerialNumber) (GENERIC)
- SELECT * FROM Win32_PnPEntity (DeviceId) (VBOX)
Expand Down
10 changes: 7 additions & 3 deletions al-khaser/Al-khaser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ int main(int argc, char* argv[])
known_usernames();
known_hostnames();
other_known_sandbox_environment_checks();
looking_glass_vdd_processes();
exec_check(&NumberOfProcessors, TEXT("Checking Number of processors in machine "));
exec_check(&idt_trick, TEXT("Checking Interupt Descriptor Table location "));
exec_check(&ldt_trick, TEXT("Checking Local Descriptor Table location "));
Expand Down Expand Up @@ -267,6 +268,7 @@ int main(int argc, char* argv[])
if (ENABLE_QEMU_CHECKS) {
print_category(TEXT("QEMU Detection"));
qemu_reg_key_value();
qemu_reg_keys();
qemu_processes();
qemu_dir();
exec_check(&qemu_firmware_SMBIOS, TEXT("Checking SMBIOS firmware "));
Expand All @@ -277,13 +279,14 @@ int main(int argc, char* argv[])
/* Xen Detection */
if (ENABLE_XEN_CHECKS) {
print_category(TEXT("Xen Detection"));
xen_reg_keys();
xen_process();
exec_check(&xen_check_mac, TEXT("Checking Mac Address start with 08:16:3E "));
}

/* KVM Detection */
if (ENABLE_KVM_CHECKS) {
print_category(TEXT("Xen Detection"));
print_category(TEXT("KVM Detection"));
kvm_files();
kvm_reg_keys();
exec_check(&kvm_dir, TEXT("Checking KVM virio directory "));
Expand All @@ -296,9 +299,10 @@ int main(int argc, char* argv[])
wine_reg_keys();
}

/* Paralles Detection */
/* Parallels Detection */
if (ENABLE_PARALLELS_CHECKS) {
print_category(TEXT("Paralles Detection"));
print_category(TEXT("Parallels Detection"));
parallels_reg_keys();
parallels_process();
exec_check(&parallels_check_mac, TEXT("Checking Mac Address start with 00:1C:42 "));
}
Expand Down
33 changes: 32 additions & 1 deletion al-khaser/AntiVM/Generic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2174,4 +2174,35 @@ BOOL hosting_check()
if (sock != INVALID_SOCKET) closesocket(sock);
WSACleanup();
return retVal;
}
}

/*
Check for looking-glass-host & VDD processes list.exe
https://looking-glass.io (Used in Hypervisor Phantom)
https://github.com/Scrut1ny/Hypervisor-Phantom
Looking-glass requires at least one of them:
1. Physical monitor (undetectable)
2. HDMI emulator stub (undetectable?)
3. VirtualDisplayDriver (https://github.com/VirtualDrivers/Virtual-Display-Driver)
*/
VOID looking_glass_vdd_processes()
{
const TCHAR *szProcesses[] = {
_T("looking-glass-host.exe"), // Looking-Glass.io
_T("VDDSysTray.exe"), // VirtualDisplayDriver, used in conjunction
};

WORD iLength = sizeof(szProcesses) / sizeof(szProcesses[0]);

for (int i = 0; i < iLength; i++)
{
TCHAR msg[256] = _T("");
_stprintf_s(msg, sizeof(msg) / sizeof(TCHAR), _T("Checking processes %s "), szProcesses[i]);

if (GetProcessIdFromName(szProcesses[i]))
print_results(TRUE, msg);
else
print_results(FALSE, msg);
}
}
3 changes: 2 additions & 1 deletion al-khaser/AntiVM/Generic.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,5 @@ BOOL registry_services_disk_enum();
BOOL registry_disk_enum();
BOOL number_SMBIOS_tables();
BOOL firmware_ACPI_WAET();
BOOL hosting_check();
BOOL hosting_check();
VOID looking_glass_vdd_processes();
1 change: 1 addition & 0 deletions al-khaser/AntiVM/KVM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ VOID kvm_reg_keys()
_T("SYSTEM\\ControlSet001\\Services\\BALLOON"),
_T("SYSTEM\\ControlSet001\\Services\\BalloonService"),
_T("SYSTEM\\ControlSet001\\Services\\netkvm"),
_T("SYSTEM\\CurrentControlSet\\Enum\\PCI\\VEN_1AF4*"),
};

WORD dwlength = sizeof(szKeys) / sizeof(szKeys[0]);
Expand Down
25 changes: 25 additions & 0 deletions al-khaser/AntiVM/Parallels.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,31 @@

#include "Parallels.h"

/*
Check against Parallels registry keys
*/
VOID parallels_reg_keys()
{
/* Array of strings of blacklisted registry keys */
const TCHAR* szKeys[] = {
_T("SYSTEM\\CurrentControlSet\\Enum\\PCI\\VEN_1AB8*"),
};

WORD dwlength = sizeof(szKeys) / sizeof(szKeys[0]);

/* Check one by one */
for (int i = 0; i < dwlength; i++)
{
TCHAR msg[256] = _T("");
_stprintf_s(msg, sizeof(msg) / sizeof(TCHAR), _T("Checking reg key %s "), szKeys[i]);

if (Is_RegKeyExists(HKEY_LOCAL_MACHINE, szKeys[i]))
print_results(TRUE, msg);
else
print_results(FALSE, msg);
}
}

/*
Check for process list
*/
Expand Down
1 change: 1 addition & 0 deletions al-khaser/AntiVM/Parallels.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#pragma once

VOID parallels_reg_keys();
VOID parallels_process();
BOOL parallels_check_mac();
24 changes: 24 additions & 0 deletions al-khaser/AntiVM/Qemu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,30 @@ VOID qemu_reg_key_value()
}


/*
Check against QEMU registry keys
*/
VOID qemu_reg_keys()
{
/* Array of strings of blacklisted registry keys */
const TCHAR* szKeys[] = {
_T("SYSTEM\\CurrentControlSet\\Enum\\PCI\\VEN_1B36*"),
};

WORD dwlength = sizeof(szKeys) / sizeof(szKeys[0]);

/* Check one by one */
for (int i = 0; i < dwlength; i++)
{
TCHAR msg[256] = _T("");
_stprintf_s(msg, sizeof(msg) / sizeof(TCHAR), _T("Checking reg key %s "), szKeys[i]);

if (Is_RegKeyExists(HKEY_LOCAL_MACHINE, szKeys[i]))
print_results(TRUE, msg);
else
print_results(FALSE, msg);
}
}

/*
Check for process list
Expand Down
1 change: 1 addition & 0 deletions al-khaser/AntiVM/Qemu.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once

VOID qemu_reg_key_value();
VOID qemu_reg_keys();
VOID qemu_processes();
VOID qemu_dir();
BOOL qemu_firmware_ACPI();
Expand Down
1 change: 1 addition & 0 deletions al-khaser/AntiVM/VMWare.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ VOID vmware_reg_keys()
/* Array of strings of blacklisted registry keys */
const TCHAR* szKeys[] = {
_T("SOFTWARE\\VMware, Inc.\\VMware Tools"),
_T("SYSTEM\\CurrentControlSet\\Enum\\PCI\\VEN_15AD*"),
};

WORD dwlength = sizeof(szKeys) / sizeof(szKeys[0]);
Expand Down
3 changes: 2 additions & 1 deletion al-khaser/AntiVM/VirtualBox.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ VOID vbox_reg_keys()
_T("SYSTEM\\ControlSet001\\Services\\VBoxMouse"),
_T("SYSTEM\\ControlSet001\\Services\\VBoxService"),
_T("SYSTEM\\ControlSet001\\Services\\VBoxSF"),
_T("SYSTEM\\ControlSet001\\Services\\VBoxVideo")
_T("SYSTEM\\ControlSet001\\Services\\VBoxVideo"),
_T("SYSTEM\\CurrentControlSet\\Enum\\PCI\\VEN_5333*"),
};

WORD dwlength = sizeof(szKeys) / sizeof(szKeys[0]);
Expand Down
1 change: 1 addition & 0 deletions al-khaser/AntiVM/VirtualPC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ VOID virtual_pc_reg_keys()
/* Array of strings of blacklisted registry keys */
const TCHAR* szKeys[] = {
_T("SOFTWARE\\Microsoft\\Virtual Machine\\Guest\\Parameters"),
_T("SYSTEM\\CurrentControlSet\\Enum\\PCI\\VEN_5333*"),
};

WORD dwlength = sizeof(szKeys) / sizeof(szKeys[0]);
Expand Down
24 changes: 24 additions & 0 deletions al-khaser/AntiVM/Xen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,30 @@

#include "Xen.h"

/*
Check against Xen registry keys
*/
VOID xen_reg_keys()
{
/* Array of strings of blacklisted registry keys */
const TCHAR* szKeys[] = {
_T("SYSTEM\\CurrentControlSet\\Enum\\PCI\\VEN_5853*"),
};

WORD dwlength = sizeof(szKeys) / sizeof(szKeys[0]);

/* Check one by one */
for (int i = 0; i < dwlength; i++)
{
TCHAR msg[256] = _T("");
_stprintf_s(msg, sizeof(msg) / sizeof(TCHAR), _T("Checking reg key %s "), szKeys[i]);
if (Is_RegKeyExists(HKEY_LOCAL_MACHINE, szKeys[i]))
print_results(TRUE, msg);
else
print_results(FALSE, msg);
}
}

/*
Check for process list
*/
Expand Down
1 change: 1 addition & 0 deletions al-khaser/AntiVM/Xen.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#pragma once

VOID xen_reg_keys();
VOID xen_process();
BOOL xen_check_mac();
80 changes: 69 additions & 11 deletions al-khaser/Shared/Utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,17 +58,75 @@ BOOL Is_RegKeyValueExists(HKEY hKey, const TCHAR* lpSubKey, const TCHAR* lpValue

BOOL Is_RegKeyExists(HKEY hKey, const TCHAR* lpSubKey)
{
HKEY hkResult = NULL;
TCHAR lpData[1024] = { 0 };
DWORD cbData = MAX_PATH;

if (RegOpenKeyEx(hKey, lpSubKey, NULL, KEY_READ, &hkResult) == ERROR_SUCCESS)
{
RegCloseKey(hkResult);
return TRUE;
}

return FALSE;
if (_tcschr(lpSubKey, _T('*')) == NULL && _tcschr(lpSubKey, _T('?')) == NULL)
{
HKEY hkResult = NULL;
if (RegOpenKeyEx(hKey, lpSubKey, 0, KEY_READ, &hkResult) == ERROR_SUCCESS)
{
RegCloseKey(hkResult);
return TRUE;
}
return FALSE;
}
else
{
const TCHAR* lastBackslash = _tcsrchr(lpSubKey, _T('\\'));
TCHAR parentPath[MAX_PATH] = {0};
TCHAR childPattern[MAX_PATH] = {0};

if (lastBackslash != NULL)
{
size_t parentLen = lastBackslash - lpSubKey;
_tcsncpy_s(parentPath, _countof(parentPath), lpSubKey, parentLen);
_tcscpy_s(childPattern, _countof(childPattern), lastBackslash + 1);
}
else
{
_tcscpy_s(childPattern, _countof(childPattern), lpSubKey);
}

HKEY hKeyParent = NULL;
LONG lResult = RegOpenKeyEx(hKey, parentPath, 0, KEY_READ, &hKeyParent);
if (lResult != ERROR_SUCCESS)
{
return FALSE;
}

TCHAR childPatternUpper[MAX_PATH];
_tcscpy_s(childPatternUpper, _countof(childPatternUpper), childPattern);
_tcsupr_s(childPatternUpper, _countof(childPatternUpper));

DWORD dwIndex = 0;
TCHAR subkeyName[MAX_PATH];
DWORD cchName = MAX_PATH;
BOOL bFound = FALSE;

while (1)
{
cchName = MAX_PATH;
lResult = RegEnumKeyEx(hKeyParent, dwIndex, subkeyName, &cchName, NULL, NULL, NULL, NULL);
if (lResult == ERROR_NO_MORE_ITEMS)
break;
if (lResult != ERROR_SUCCESS)
break;

TCHAR subkeyUpper[MAX_PATH];
_tcscpy_s(subkeyUpper, _countof(subkeyUpper), subkeyName);
_tcsupr_s(subkeyUpper, _countof(subkeyUpper));

// Check if the subkey matches the pattern
if (PathMatchSpec(subkeyUpper, childPatternUpper))
{
bFound = TRUE;
break;
}

dwIndex++;
}

RegCloseKey(hKeyParent);
return bFound;
}
}

BOOL is_FileExists(TCHAR* szPath)
Expand Down