malware development | anti-sandbox | anti-VM techniques in c
video out now but thanks for subscribing
Analyzing a malwareapp dynamically
Dynamic analysis of an executable may be performed either automatically by a sandbox or manually by a malware analyst. Malicious applications often use various methods to finger print the environment they’re being executed in and perform different actions based on a given execution environment situation.
Automated analysis is performed in a simplified sandbox environment which may have some specific traits; particularly it may not be able to emulate all execution nuances of a real environment.
Both automated and manual analysis have common characteristics, in particular they are usually performed in virtual environments which can be easily detected if not configured properly.
Most sandbox detection techniques revolve around checking specific environment attributes
Example
limited resources, indicative device names artifacts ,presence of specific files, registry keys
Detecting virtual environments
Both sandboxes and analyst’s virtual Operating Systems usually can’t 100% emulate actual execution environment like typical user workstations). Virtual environments have limited resources ,corresponding device names whch can also provide useful information, may have VM-specific tools and drivers installed, often look like fresh Windows installations and sometimes use hardcoded user or computer names.
Hardware resources information retrieval
sandboxes /VM boxes used by analysts are subjected to some constraints - they often have limited resources.
Typical user workstation have processors with at least 2 cores, a minimum of 2 GB of RAM and a 100 GB hard drive space. We can verify if the environment our malicious application is being executed in is a subject to these constrains:
// check CPU
SYSTEM_INFO systemInfo;
GetSystemInfo(&systemInfo);
DWORD numberOfProcessors = systemInfo.dwNumberOfProcessors;
if (numberOfProcessors < 2) return false;
// check RAM
MEMORYSTATUSEX memoryStatus;
memoryStatus.dwLength = sizeof(memoryStatus);
GlobalMemoryStatusEx(&memoryStatus);
DWORD RAMMB = memoryStatus.ullTotalPhys / 1024 / 1024;
if (RAMMB < 2048) return false;
// check HDD
HANDLE hDevice = CreateFileW(L"\\.\PhysicalDrive0", 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
DISK_GEOMETRY pDiskGeometry;
DWORD bytesReturned;
DeviceIoControl(hDevice, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0,&pDiskGeometry, sizeof(pDiskGeometry), &bytesReturned, (LPOVERLAPPED)NULL);
DWORD diskSizeGB;
diskSizeGB = pDiskGeometry.Cylinders.QuadPart * (ULONG)pDiskGeometry.TracksPerCylinder * (ULONG)pDiskGeometry.SectorsPerTrack * (ULONG)pDiskGeometry.BytesPerSector / 1024 / 1024 / 1024;
if (diskSizeGB < 100) return false;
Devices and vendor names
On default VM installations, devices often have predictable names, for example containing strings associated with the specific hypervisor. We can check for hard drive name, optical disk drive name, BIOS version, computer manufacturer and model name, graphics controller name etc. Relevant information can be retrieved with WMI queries (check properties like “Name”, “Description”, “Caption”).
Below you can see an example of HDD name retrieval using native Windows API functions (without WMI):
HDEVINFO hDeviceInfo = SetupDiGetClassDevs(&GUID_DEVCLASS_DISKDRIVE, 0, 0, DIGCF_PRESENT);
SP_DEVINFO_DATA deviceInfoData;
deviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
SetupDiEnumDeviceInfo(hDeviceInfo, 0, &deviceInfoData);
DWORD propertyBufferSize;
SetupDiGetDeviceRegistryPropertyW(hDeviceInfo, &deviceInfoData, SPDRP_FRIENDLYNAME, NULL, NULL, 0, &propertyBufferSize);
PWSTR HDDName = (PWSTR)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, propertyBufferSize);SetupDiGetDeviceRegistryPropertyW(hDeviceInfo, &deviceInfoData, SPDRP_FRIENDLYNAME, NULL, (PBYTE)HDDName, propertyBufferSize, NULL);
CharUpperW(HDDName);
if (wcsstr(HDDName, L"VBOX")) return false;