Security-Oriented C Tutorial 0xFA - Enhancing Our Crypter
Hello again, readers! In our previous crypter tutorial, we looked at how we could obfuscate our malware (or any program) by using a simple one-byte XOR key. In this quick tutorial, we will be looking at how a simple little tweak can create a better means of obfuscation. Let's get right into it!
With a couple of tests, we saw that the obfuscation method worked however, our real-world test with the RAT, Dark Comet, proved that our crypter was not robust enough as it was still detected by common antiviruses such as AVG, Avira and Bitdefender. A very simple way to strengthen our obfuscation method is by modifying our XOR key. All we have to do is to expand our key with more keys and then have it cycle through while encrypting our file. How do we do this? Why, with an array, of course!
We can see our previous definition of the single-byte XOR key, XOR_KEY. We've now defined an array of bytes in an unsigned char array called key. Note that it's of type unsigned char because we want to use the entire range from 0-255. For our encrypting method in our xorFile function, we need to be able to cycle through our array for each byte we read and encrypt. How we can do this is by using the modulus operator (%). A brief description of what it does: it is an operator which obtains the remainder of a division. Here's a demonstration of how it works in calculating the position inside our key array.
- First character read is XORed with 0x03 (element 0),
- Second XORed with 0x12 (element 1),
- Sixth character is XORed with 0x6f (element 5),
- Our seventh needs to be XORed with 0x03 (element 6?),
- Eighth with 0x12 (element 7?).
If we take element "6" and divide it by the size of the array, 6, the remainder is 0, so therefore, our seventh character will roll back to the first element, AKA 0x03. Our eighth is element "7" divided by size of the array, 6, we get the remainder 1 which is element 1, i.e. 0x12. It will keep doing this until it finishes the entire encryption. How do we do it in code? Let's check it out:
Using our loop incrementer, i, we can obtain the element of our array starting from 0 and as i increases, so does the element number. We also use the sizeof operator on our key array to obtain the total number of elements (6). With these two together along with our modulus operation from above, it will work perfectly, cycling through the keys as we need.
Here are our new results with our tweaked crypter with the Dark Comet RAT in VirusTotal.
Well then, that is much MUCH better! Look at that, only a single detection by a "CAT-QuickHeal" antivirus. Well I've never heard of that so I'm guessing it's safe to assume that the typical user wouldn't have either. Excellent! In fact, our file didn't even get flagged as a PUA (Possibly Unwanted Application) which is nice!
By using a multi-key method, we were able to deny any form of brute force method that might've revealed the signature of our malware (or any other program) as it would take much more time and resources to decrypt. Of course, any forensics analysis or reverse engineering method would unveil our encryption key, method and ultimately the true face of our file.
That's it for our crypter program. If you'd like to go even further, perhaps you could implement some sort of array which stores the entire encrypted binary file inside the crypter and have it decrypt and write out to a file (also known as dropping which could be detected by heuristics) on execution so it wouldn't be two separate files and require that dependency.
If you want to go even further and try writing your own runtime crypter, you would need to explore and learn how executables are loaded into memory according to their headers and segments (which is pretty advanced).
See you in the next tutorial!