Do you want to fool antivirus software? When you look through hacking forums for a solution to this, you will likely encounter the term “crypter”. You will also find this tool in the arsenal of every advanced penetration tester and it is the obvious standard for an advanced persistent threat (APT). This blog post gives you some insights about crypters and finalizes my SecurityTube Linux Assembly Expert (SLAE) certification. The task was to:
Create a custom crypter
Use any existing encryption schema (including own)
Use any programming language
But before digging into the technical details of my crypter, let’s first discuss the basics.
What is a crypter?
Basically the term “crypter” is derived from “encryption”, which means its purpose is to encrypt and decrypt a specific payload using a cryptographic encryption algorithm like 3DES, AES, CAMELLIA or even RSA. So why do you encrypt things? Because you don’t want them to be read, which means you want to primarily secure its confidentiality (with some encryption algorithms like AES-GCM you secure the integrity as well). Basically, this principle also applies to a crypter - its main purpose is to conceal the real identity and functionality of a payload from antivirus software (henceforth referred to as “AV”).
AV software (just like provided by Avira, Kasperky or Bitdefender) uses mostly a signature-based approach. This means all AV vendors maintain a database of virus signatures, which is built from detected viruses and specific patterns found in them. If such a pattern is detected by an AV, the file is marked as a virus. This principle is extended by some heuristic techniques aimed to detect new viruses as well as variants of existing ones by simulating what happen upon execution of a malicious file.
Therefore to bypass these signature-based AVs and make the crypter “FUD” (fully undetectable), crypters are a widely used approach. A list of crypter techniques can be found on malwarebytes.org.
Choosing an encryption cipher and programming language
As a personal goal, I wanted to do something different than all other SLAE students have done so far. After having a quick look at blog posts of some other student’s about this assignment, I decided to go the following way:
Use Camellia as an encryption algorithm
Use C++ as the programming language
Use the Crypto++ library to keep the wheel invented
Camellia was developed by Misubishi Electric and NTT Japan and is a symmetric key block cipher such as AES. Although it is not widely used but part of the offered TLS ciphers-suites, it is has the security levels comparable to AES. It has a block size of 128 bits and key sizes of either 128, 192 or 256 bits. It supports modes, such as Cipher Block Chaining (CBC) and authenticated encryption using Galois Counter Mode (GCM). I’m not going to dig into how that cipher is working internally as it is highly mathematical and reserved for universities ;-)
For this assignment, I’ve chosen to use the CBC mode and the 256 bit-key variant, which means that the encryption key is 32 bytes strong. Although the authenticated GCM mode is stronger than the CBC mode (which has known weaknesses), it does not add any additional security here.
Wikipedia supplied a really nice graph describing encryption using the CBC mode:
With CBC mode each plaintext block of 128bit (16 bytes) is first XORed with the previous cipher-text. Except the first block, which obviously does not have a preceding block, is XORed with a random Initialization Vector (IV). After XORing, the encryption algorithm is applied to the XORed block using the 256bit key and outputs an encrypted block of the same size. Since this is repeated until the end of the plaintext string, this clearly shows that the plaintext string must be a multiple of the block size. If the plaintext does not meet this requirement, the plaintext is filled up using a padding.
Nearly the same schema is applied to the decryption part:
As I have mentioned before, my whole crypter and my corresponding decrypter are based on the excellent Crypto++ library, which also brings some very good explanatory examples of code. So here’s the first part of my crypter - the idea is to generate a random Key and IV to encrypt the supplied payload and output each value hex-encoded to the console to take it up again later. The crypter includes a predefined 5-round shikata_ga_nai encoded Metasploit meterpreter bind payload, which was previously generated using msfvenom:
The source code of my crypter is commented inline for a better understanding:
The crypter can be compiled on a x64 system using:
When executed it outputs all the previously discussed values needed for decryption of the payload:
Since crypter.cpp does only encrypt the payload, a separate decrypter needs to take up the key, IV and ciphertext, which was generated by the crypte, decrypt it in memory and execute the final payload on the target system:
When the decrypter is executed on a target machine, it performs its intended action and opens a meterpreter bind shell:
Et voila, the crypter is working! :-)
This blog post has been created for completing the requirements of the SecurityTube Linux Assembly Expert certification: