Beispiel #1
0
        public UInt32 MapImage(string imageName, byte[] rawImage)
        {
            Log.LogInfo($"Mapping {imageName}");

            // GET HEADERS
            Tools.GetImageHeaders(rawImage, out NT.IMAGE_DOS_HEADER dosHeader, out NT.IMAGE_FILE_HEADER fileHeader, out NT.IMAGE_OPTIONAL_HEADER64 optionalHeader);

            // CREATE A MEMORY SECTION IN TARGET PROCESS
            UInt32 sectionHandle = (UInt32)TargetProcess.CreateSection(NT.MemoryProtection.ExecuteReadWrite, optionalHeader.SizeOfImage);

            // MAP THE SECTION INTO BOTH OUR OWN AND THE TARGET PROCESS
            // THIS WILL RESULT IN A MIRRORED MEMORY SECTION, WHERE EVERY CHANGE
            // TO THE LOCAL SECTION WILL ALSO CHANGE IN THE TARGET PROCESS
            // AND VICE VERSA
            UInt32 remoteImage = (UInt32)TargetProcess.MapSection(sectionHandle, NT.MemoryProtection.ExecuteReadWrite);
            UInt32 localImage  = (UInt32)Process.GetCurrentProcess().MapSection(sectionHandle, NT.MemoryProtection.ExecuteReadWrite);

            // SAVE MAPPED EXECUTABLES IN A LIST
            // SO WE CAN RECURSIVELY MAP DEPENDENCIES, AND THEIR DEPENDENCIES
            // WITHOUT BEING STUCK IN A LOOP :)
            MappedModules[imageName]   = remoteImage;
            MappedRawImages[imageName] = rawImage;

            // ADD LOADER REFERENCE
            if (imageName == Options.LoaderImagePath)
            {
                if (Options.CreateLoaderReference)
                {
                    AddLoaderEntry(imageName, remoteImage);
                }
            }
            else // ALWAYS CREATE REFERENCE FOR DEPENDENCIES
            {
                AddLoaderEntry(imageName, remoteImage);
            }

            // COPY HEADERS TO SECTION
            Marshal.Copy(rawImage, 0, (IntPtr)localImage, (int)optionalHeader.SizeOfHeaders);

            // DO THE ACTUAL MANUALMAPPING
            this.WriteImageSections(rawImage, dosHeader, localImage, fileHeader.NumberOfSections);
            this.RelocateImageByDelta(localImage, remoteImage, optionalHeader);
            this.FixImportTable(localImage, optionalHeader);

            // NUKE HEADERS
            // TODO: DONT WRITE THEM IN THE FIRST PLACE
            if (Options.EraseHeaders)
            {
                byte[] headerBuffer = new byte[(int)optionalHeader.SizeOfHeaders];
                NTM.RandomEngine.NextBytes(headerBuffer);

                Marshal.Copy(headerBuffer, 0, (IntPtr)localImage, (int)optionalHeader.SizeOfHeaders);
            }

            NT.CloseHandle(sectionHandle);
            Process.GetCurrentProcess().UnmapSection(localImage);

            return(remoteImage);
        }
Beispiel #2
0
        public void CallEntrypoint(byte[] rawImage, UInt32 moduleHandle)
        {
            // GET HEADERS
            Tools.GetImageHeaders(rawImage, out NT.IMAGE_DOS_HEADER dosHeader, out NT.IMAGE_FILE_HEADER fileHeader, out NT.IMAGE_OPTIONAL_HEADER64 optionalHeader);

            // GET DLLMAIN
            UInt32 entrypoint = moduleHandle + optionalHeader.AddressOfEntryPoint;

            if (optionalHeader.AddressOfEntryPoint == 0)
            {
                Log.LogError($"Invalid Entrypoint - skipping {moduleHandle.ToString("x2")}");
                return;
            }

            Log.LogVariable("AddressOfEntryPoint", optionalHeader.AddressOfEntryPoint.ToString("x2"));

            // GET PROPER SHELLCODE FOR EXECUTION TYPE
            byte[] shellcode = ShellcodeGenerator.CallDllMain(moduleHandle, entrypoint, TypeOfExecution == ExecutionType.HijackThread);

            // EXECUTE DLLMAIN
            switch (TypeOfExecution)
            {
                #region Create Thread
            case ExecutionType.CreateThread:
                // INJECT OUR SHELLCODE -> REMOTE PROCESS TO CALL DLLMAIN REMOTELY :)
                TargetProcess.InjectShellcode(shellcode);
                break;
                #endregion

                #region Hijack Thread
            case ExecutionType.HijackThread:
                // WRITE SHELLCODE TO TARGET MEMORY
                var remoteShellcodePointer = TargetProcess.AllocateAndWrite(shellcode, NT.AllocationType.Commit | NT.AllocationType.Reserve, NT.MemoryProtection.ExecuteReadWrite);

                // GET THREAD HANDLE WITH PROPER ACCESS RIGHTS
                // I FILTER THE THREADS LIKE THIS BECAUSE FROM
                // EXPERIENCE SOME THREADS WITH TimeCritical PRIORITY
                // ETC WILL CAUSE SOME WONKY CRASHES
                var usableThreads = TargetProcess.Threads.Cast <ProcessThread>().Where(
                    x => x.ThreadState == System.Diagnostics.ThreadState.Wait && x.WaitReason == ThreadWaitReason.UserRequest);
                ProcessThread targetThread = usableThreads.ElementAt(NTM.RandomEngine.Next(usableThreads.Count()));
                var           threadHandle = targetThread.GetNativeHandle((NT.ThreadAccess) 0x1FFFFF);

                // ELEVATE HANDLE VIA DRIVER EXPLOIT
                if (Options.ElevateHandle)
                {
                    ElevateHandle.Elevate(threadHandle, 0x1FFFFF);
                }

                Log.LogInfo($"Thread {targetThread.Id} - {targetThread.ThreadState} - {targetThread.PriorityLevel} - {targetThread.CurrentPriority}");

                // INITIALISE THREAD CONTEXT STRUCT
                NT.CONTEXT64 ctx = new NT.CONTEXT64()
                {
                    ContextFlags = NT.CONTEXT_FLAGS.CONTEXT_FULL
                };

                // SUSPEND THE THREAD SO WE CAN MODIFY REGISTERS
                if (NT.SuspendThread(threadHandle) == uint.MaxValue)
                {
                    Log.LogError($"Failed to suspend thread - {Marshal.GetLastWin32Error().ToString("x2")}");
                }

                // GET CONTEXT
                if (!NT.GetThreadContext(threadHandle, ref ctx))
                {
                    throw new Win32Exception("GetThreadContext");
                }

                // ALLOCATE 8 BYTES ON STACK
                ctx.Rsp -= sizeof(ulong);

                // 'RET' WILL CALL POP AND JUMP TO THAT VALUE
                // SO WE WRITE OLD INSTRUCTION POINTER TO THE STACK SO WE CAN RETURN
                // SO DONT F**K UP THE STACK
                // F*****G RETARD
                TargetProcess.WriteRawMemory(BitConverter.GetBytes(ctx.Rip), ctx.Rsp);

                Log.LogInfo($"{ctx.Rip.ToString("x2")} -> {remoteShellcodePointer.ToString("x2")}");

                // OVERWRITE INSTRUCTION POINTER
                ctx.Rip = remoteShellcodePointer;

                // SET THREAD CONTEXT TO APPLY CHANGES
                if (!NT.SetThreadContext(threadHandle, ref ctx))
                {
                    throw new Win32Exception("SetThreadContext");
                }

                // RESUME THREAD
                Log.LogVariable("Resumed?", NT.ResumeThread(threadHandle));
                //if ( == uint.MaxValue/*-1*/)
                //     Log.LogError($"Failed to resume thread - {Marshal.GetLastWin32Error().ToString("x2")}");

                // CLOSE THREAD HANDLE
                NT.CloseHandle(threadHandle);

                // WAIT FOR MODULE TO LOAD FULLY BEFORE FREEING SHELLCODE
                // GHETTO SLEEP
                Thread.Sleep(1000);

                // MEMORY LEAKS ARE BAD
                TargetProcess.FreeMemory(remoteShellcodePointer);
                break;
                #endregion
            }
        }
        public bool InjectImage(string imagePath)
        {
            Log.LogGeneral($"Injecting {imagePath} -> {TargetProcess.ProcessName}_{TargetProcess.Id}");

            // GET MODULE NAME FOR LATER USE
            string moduleName = Path.GetFileName(imagePath);

            // GET LOAD LIBRARY POINTER
            ulong loadLibraryPointer = NTM.GetModuleFunction("kernel32.dll", "LoadLibraryA");

            // ALLOCATE IMAGE PATH IN TARGET PROCESS
            var   rawImagePath       = Encoding.Default.GetBytes(imagePath);
            ulong allocatedImagePath = TargetProcess.AllocateAndWrite(rawImagePath, NT.AllocationType.Commit | NT.AllocationType.Reserve, NT.MemoryProtection.ReadWrite);

            ulong threadHandle    = 0;
            ulong moduleHandle    = 0;
            bool  injectionFailed = false;

            switch (TypeOfExecution)
            {
                #region Create Thread
            case ExecutionType.CreateThread:
                // CREATE A THREAD TO REMOTELY CALL LOADLIBRARY
                TargetProcess.CreateAndWaitForThread(loadLibraryPointer, allocatedImagePath, out threadHandle);

                // GET MODULE HANDLE FOR LATER USE
                moduleHandle = TargetProcess.GetModuleByName(moduleName);
                break;
                #endregion

                #region Hijack Thread
            case ExecutionType.HijackThread:
                byte[] shellcode = ShellcodeGenerator.CallLoadLibrary(allocatedImagePath, loadLibraryPointer);

                // ALLOCATE AND WRITE SHELLCODE TO TARGET
                ulong remoteShellcodePointer = TargetProcess.AllocateAndWrite(shellcode, NT.AllocationType.Commit | NT.AllocationType.Reserve, NT.MemoryProtection.ExecuteReadWrite);

                // GET THREAD HANDLE WITH PROPER ACCESS RIGHTS
                var usableThreads = TargetProcess.Threads.Cast <ProcessThread>().Where(
                    x => x.ThreadState == System.Diagnostics.ThreadState.Wait && x.WaitReason == ThreadWaitReason.UserRequest);
                ProcessThread targetThread = usableThreads.ElementAt(NTM.RandomEngine.Next(usableThreads.Count()));
                threadHandle = targetThread.GetNativeHandle((NT.ThreadAccess) 0x1FFFFF);

                // ELEVATE HANDLE VIA DRIVER EXPLOIT
                if (Options.ElevateHandle)
                {
                    ElevateHandle.Elevate(threadHandle, 0x1FFFFF);
                }

                Log.LogInfo($"Thread {targetThread.Id} - {targetThread.ThreadState} - {/*targetThread.WaitReason} - {targetThread.PriorityLevel} - {*/targetThread.CurrentPriority}");

                // INITIALISE THREAD CONTEXT STRUCT
                NT.CONTEXT64 ctx = new NT.CONTEXT64()
                {
                    ContextFlags = NT.CONTEXT_FLAGS.CONTEXT_FULL
                };

                // SUSPEND THE THREAD SO WE CAN MODIFY REGISTERS
                if (NT.SuspendThread(threadHandle) == uint.MaxValue /*-1*/)
                {
                    Log.LogError($"Failed to suspend thread - {Marshal.GetLastWin32Error().ToString("x2")}");
                }

                // GET CONTEXT
                if (!NT.GetThreadContext(threadHandle, ref ctx))
                {
                    throw new Win32Exception($"GetThreadContext - {Marshal.GetLastWin32Error().ToString("x2")}");
                }

                Log.LogInfo($"Stack Pointer: {ctx.Rsp.ToString("x2")} - {ctx.Rsp % 0x10}");

                // ALLOCATE 8 BYTES ON STACK
                ctx.Rsp -= sizeof(ulong);

                // 'RET' WILL CALL POP AND JUMP TO THAT VALUE
                // SO WE WRITE OLD INSTRUCTION POINTER TO THE STACK SO WE CAN RETURN
                // SO DONT F**K UP THE STACK
                // F*****G RETARD
                TargetProcess.WriteRawMemory(BitConverter.GetBytes(ctx.Rip), ctx.Rsp);

                // OVERWRITE INSTRUCTION POINTER
                ctx.Rip = remoteShellcodePointer;

                // SET THREAD CONTEXT TO APPLY CHANGES
                if (!NT.SetThreadContext(threadHandle, ref ctx))
                {
                    throw new Win32Exception($"SetThreadContext- {Marshal.GetLastWin32Error().ToString("x2")}");
                }

                // RESUME THREAD
                if (NT.ResumeThread(threadHandle) == uint.MaxValue /*-1*/)
                {
                    Log.LogError($"Failed to resume thread - {Marshal.GetLastWin32Error().ToString("x2")}");
                }

                // CLOSE THREAD HANDLE
                NT.CloseHandle(threadHandle);

                // WAIT FOR MODULE TO LOAD FULLY BEFORE FREEING SHELLCODE
                // IF WE DONT WAIT, WE MIGHT FREE BEFORE LOADLIBRARY HAS FINISHED
                // WHICH MEANS IT WILL JUMP BACK TO A NON-EXISTING MEMORY PAGE
                // ALSO WE DO LIMIT HOW LONG WE WAIT, AS WE MIGHT HAVE HIJACKED
                // A STUBBORN, RETARDED, SHITTY, USELESS, FILTHY NIGGER THREAD
                // THAT ISN'T GOING TO DO SHIT BUT SLEEP, LEAVING US HANGING
                // todo: look into stubborn threads

                Stopwatch watch = Stopwatch.StartNew();
                while (watch.ElapsedMilliseconds < 2500)
                {
                    moduleHandle = TargetProcess.GetModuleByName(moduleName);

                    if (moduleHandle != 0)
                    {
                        break;
                    }

                    Thread.Sleep(1);
                }

                // IF WE HIJACKED A STUBBORN THREAD
                // WE CAN'T JUST FREE THE SHELLCODE NOR
                // THE ALLOCATED IMAGE PATH
                // AS IT MIGHT JUST RUN IT AFTER SOME TIME
                // RAISING AN EXCEPTION
                if (!(injectionFailed = moduleHandle == 0))
                {
                    TargetProcess.FreeMemory(remoteShellcodePointer);
                }

                //Console.ReadLine();

                break;
                #endregion
            }

            // ERASE PE HEADERS
            if (Options.EraseHeaders && moduleHandle != 0)
            {
                TargetProcess.NukeMemoryPage(moduleHandle);
            }

            if (!injectionFailed)
            {
                TargetProcess.FreeMemory(allocatedImagePath);
            }

            // WE'LL HAVE TO REDO IF WE HIJACKED A STUBBORN THREAD
            return(injectionFailed ?
                   new LoadLibraryInjection(TargetProcess, TypeOfExecution, Options).InjectImage(imagePath) :
                   true);
        }