Kyle Rosario

XOR Malware Encryption

What is Malware Encryption?

As the name suggests, Malware encryption is the encryption of the malware's code. Encrypting your code will make it more difficult for anti-viruses and EDRs to detect the malicious content. To avoid modern detection, it is a crucial technique to implement.

Did you know that the first virus to implement encryption was the Cascade virus in 1987?

Encrypted malware implements two very important functions:

  1. Encryption: This is the function where you will be implementing an encryption algorithm to obfuscate your code.
  1. Decryption: This is the function that will take the encrypted contents produced by the encryption function, and use a key or reverse algorithm to return the de-obfuscated code.

It is important to note that while encryption does aid in avoiding signature-based detection, more advanced detection methods such as heuristic analysis wont be fooled as easily. Additionally, the amount of data you encrypt may also raise suspicions for a security solution, as the entropy would be significantly higher than a non-malicious application. Therefore it is important to limit the sections which your malware is encrypted.

Encryption Types

Below are the encryption algorithms that I'll be covering in my blog:

In this post I will focusing on XOR encryption.

XOR Encryption

XOR encryption is a type of additive cipher (Caesar Cipher). An additive cipher encrypts content by shifting values a given number of places. For example, you are given the letter A in the alphabet and you apply an additive cipher that shifts the value by 4. The result you are left with is the letter E (you start with A and shift 4 places, -> B -> C -> D ->E). XOR implements an exclusive disjunction logic or modulus 2 (%2) to shift the bits of an input.

Here is a great example provided by Wikipedia (https://en.wikipedia.org/wiki/XOR_cipher):

The logic is as follows: "Wiki's" first octet is 01010111, lets apply the encryption key to it (11110011). First were compare Wiki's first bit to the Key's first bit (0 and 1). Since there exists a 1 exclusively, the new bit will equal 1. Now let's move on to the second bit (1 and 1). Since 1 is the value for both, it is not exclusive and the resulting bit is a 0! Here is a fun way to think of it, assume each bit from the original text is a potential romantic partner's personality, and each bit from the key is your competition's personality. Now, if your potential partner's personality (0) doesn't match your competition's personality (1), then they have no chemistry and you still have a shot, so the bit results in 1! On the other hand if your next partner's personality (1) matches your competition's personality (1), tough luck kiddo, they're soulmates and the resulting bit is a 0.

Implementation in C

I have done my best in adding comments to explain what the code is doing:

#include <stdio.h>
#include <Windows.h> // importing the Windows API library

// The XOR encryption algorithm
VOID XorByUserInputKey(IN PBYTE clearFlag, IN SIZE_T sClearFlagSize, IN PBYTE key, IN SIZE_T sKey) {

	for (int i = 0, j = 0; i < sClearFlagSize; i++, j++) {

		// if end of key, start again and reapply to remaining characters in flag
		if (j > sKey) {
			j = 0;
		}
		// applying XOR operator to bytes
		clearFlag[i] = clearFlag[i] ^ key[j];
	}
}

char clearFlag[] = {
	"Hello, World! This is some verrry scarrry stuff!"
};

char key[] = {
	0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07
};

int main() {

	// Print out pointer address for clearFlag variable
	printf("[+] Welcome to the duerme's encryption toolset! Here is the location of your pointer: %p\n", clearFlag);
	printf("[!] If you are ready to encrypt please press <Enter>...");
	getchar();

	// Calling the XOR function to encrypt and print out obfuscated flag
	XorByUserInputKey(clearFlag, sizeof(clearFlag), key, sizeof(key));
	printf("[+] Encrypting...\n[+] Success! Here is your encrypted flag: \"%s\"\n", clearFlag);
	printf("[!] If you are ready to decrypt please press <Enter>...");
	getchar();

	// Calling the XOR again to decrypt and print original flag
	XorByUserInputKey(clearFlag, sizeof(clearFlag), key, sizeof(key));
	printf("[+] Decrypting...\n[+] Success! Here is your decrypted flag: \"%s\"\n", clearFlag);

	// Exit
	printf("[#] Press <Enter> To Quit ...");
	getchar();
	return 0;

}

Deep dive into the code

This program demonstrates a simple XOR encryption and decryption process. It includes the Windows API library for some console interaction but doesn't use it for anything critical. Here's what the code does:

  1. It defines an XOR encryption function called XorByUserInputKey. This function takes two arrays of bytes (clearFlag and key) along with their respective sizes. It iterates through the clearFlag array, applying the XOR operator to each byte with the corresponding byte from the key array. If the key is shorter than the clearFlag, it starts over from the beginning of the key. This XOR operation is used for both encryption and decryption.
  1. It defines two arrays, clearFlag and key. clearFlag contains a message, and key is a fixed array of bytes used for XOR encryption.
  1. In the main function, it prints a message indicating that the program is a "duerme's encryption toolset" and displays the memory address of the clearFlag array. It then waits for user input by calling getchar().
  1. After the user presses Enter, it calls the XorByUserInputKey function to encrypt the message in clearFlag using the XOR operation and the key. It prints a message indicating that the encryption is in progress and then displays the encrypted message.
  1. It prompts the user to press Enter again to proceed with decryption.
  1. It calls the XorByUserInputKey function again with the same arguments to decrypt the message, printing a message indicating that decryption is in progress and then displaying the original message.
  1. Finally, it prints a message prompting the user to press Enter to quit the program.

In my next blog post I plan on covering a more advanced encryption method (AES). I will showcase a simple malicious script and bypass the Windows Defender anti-virus using the encryption method.

Wrapping things up

In this blog, we dove into the malware encryption realm and unveiled the intricate dance between threat-actors and defenders in the digital landscape. XOR encryption, as demonstrated in our code example, is just one piece of the puzzle, showcasing the creative tactics that malware authors employ to evade detection.

As we wrap up, it's important to recognize that the world of cybersecurity is ever-evolving. Malware authors continually adapt and refine their techniques, keeping cybersecurity professionals on their toes. Understanding the basics of malware encryption is a fundamental step in this ongoing battle.

Keep that curiosity alive and never stop learning. Remember, the best defense is staying informed and being prepared. Stay one step ahead by comprehending the tactics employed by adversaries. Thank you for reading!