System Information Discovery — Gathering System Information For Malware Infections

Kamran Saifullah
4 min readApr 29, 2021

When we take a look at MITRE Discovery Techniques we find that System Information Discovery is there. This is crucially important as it yields a huge amount of information of a particular system. In the past there have been huge kind of malware attacks in which it looked at the system information to check whether the system is a VM or HW. When the system is installed. Is the system sandbox, honeypot. How many processors does the system have, how much is the memory there.

There is a lot of information, system information can yield. Adversaries have been using it to deliver the exact malware which suits the environment and also the architecture of the system.

https://attack.mitre.org/techniques/T1082/

In Windows operating system there are multiple ways on gathering system information. We can leverage “systeminfo” command, WMIs and Windows Native APIs to gather such information.

Similarly in MacOS, we can take leverage of built-in commands, also in Linux and now in Cloud Environments we can take leverage of APIs to find all system related information.

In this article we will stick to Windows Operating System. The first command is.

SYSTEMINFO

We can run the systeminfo command as a singleton, but yes we can leverage this command to check the information of other systems as well.

/S → We can use this to specify the host of which we require to know information about.

What if the the system has usernames and passwords set? We can use the /U and /P command respectively.

There is one more good thing about this utility i.e. we can specify the format in which we want to output the information. It can be done via /FO command.

WMI

The second and the most commonly used functionality by adversaries is WMI to query the operating system for quite a good amount of information.

Although it has already been deprecated but we can still use it until it’s available on Windows Systems.

There is a loads of information. Suppose we want to check the OS and CPU details. We can issue the OS and CPU aliases.

As, it has been deprecated, we can now call the WMI using PowerShell.

Also we can utilize CIMInstance to query for system information.

Windows API

Finally we can take leverage of Windows API. For that case we need to import the DLLs and then we can call the functions to find all the required information. This is a long process, but the code can be customized as per the needs and thus, attackers can take advantage of these APIs.

As, per the documentation provided by Microsoft, this code is used to gather the system information.

#include <windows.h>
#include <tchar.h>
#include <stdio.h>
TCHAR* envVarStrings[] =
{
TEXT("OS = %OS%"),
TEXT("PATH = %PATH%"),
TEXT("HOMEPATH = %HOMEPATH%"),
TEXT("TEMP = %TEMP%")
};
#define ENV_VAR_STRING_COUNT (sizeof(envVarStrings)/sizeof(TCHAR*))
#define INFO_BUFFER_SIZE 32767
void printError( TCHAR* msg );
void main( )
{
DWORD i;
TCHAR infoBuf[INFO_BUFFER_SIZE];
DWORD bufCharCount = INFO_BUFFER_SIZE;

// Get and display the name of the computer.
bufCharCount = INFO_BUFFER_SIZE;
if( !GetComputerName( infoBuf, &bufCharCount ) )
printError( TEXT("GetComputerName") );
_tprintf( TEXT("\nComputer name: %s"), infoBuf );

// Get and display the user name.
bufCharCount = INFO_BUFFER_SIZE;
if( !GetUserName( infoBuf, &bufCharCount ) )
printError( TEXT("GetUserName") );
_tprintf( TEXT("\nUser name: %s"), infoBuf );

// Get and display the system directory.
if( !GetSystemDirectory( infoBuf, INFO_BUFFER_SIZE ) )
printError( TEXT("GetSystemDirectory") );
_tprintf( TEXT("\nSystem Directory: %s"), infoBuf );

// Get and display the Windows directory.
if( !GetWindowsDirectory( infoBuf, INFO_BUFFER_SIZE ) )
printError( TEXT("GetWindowsDirectory") );
_tprintf( TEXT("\nWindows Directory: %s"), infoBuf );

// Expand and display a few environment variables.
_tprintf( TEXT("\n\nSmall selection of Environment Variables:") );
for( i = 0; i < ENV_VAR_STRING_COUNT; ++i )
{
bufCharCount = ExpandEnvironmentStrings(envVarStrings[i], infoBuf,
INFO_BUFFER_SIZE );
if( bufCharCount > INFO_BUFFER_SIZE )
_tprintf( TEXT("\n\t(Buffer too small to expand: \"%s\")"),
envVarStrings[i] );
else if( !bufCharCount )
printError( TEXT("ExpandEnvironmentStrings") );
else
_tprintf( TEXT("\n %s"), infoBuf );
}
_tprintf( TEXT("\n\n"));
}
void printError( TCHAR* msg )
{
DWORD eNum;
TCHAR sysMsg[256];
TCHAR* p;
eNum = GetLastError( );
FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, eNum,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
sysMsg, 256, NULL );
// Trim the end of the line and terminate it with a null
p = sysMsg;
while( ( *p > 31 ) || ( *p == 9 ) )
++p;
do { *p-- = 0; } while( ( p >= sysMsg ) &&
( ( *p == '.' ) || ( *p < 33 ) ) );
// Display the message
_tprintf( TEXT("\n\t%s failed with error %d (%s)"), msg, eNum, sysMsg );
}

You can have a deeper look into Windows APIs and Native Functions at https://docs.microsoft.com/en-us/windows/win32/sysinfo/getting-system-information/.

--

--

Kamran Saifullah

Malware/RE/Firmware Analysis, App Sec/Off Sec, VAPT, Phishing Simulations/SE | Risk Management, IS Governance, Audits, ISO 27001 LI