Exemple #1
0
        /// <summary>
        /// Manually map module into current process.
        /// </summary>
        /// <author>Ruben Boonen (@FuzzySec)</author>
        /// <param name="pModule">Pointer to the module base.</param>
        /// <param name="pImage">Pointer to the PEINFO image.</param>
        /// <param name="PEINFO">PE_META_DATA of the module being mapped.</param>
        /// <returns>PE_MANUAL_MAP object</returns>
        public static Data.PE.PE_MANUAL_MAP MapModuleToMemory(IntPtr pModule, IntPtr pImage, Data.PE.PE_META_DATA PEINFO)
        {
            // Check module matches the process architecture
            if ((PEINFO.Is32Bit && IntPtr.Size == 8) || (!PEINFO.Is32Bit && IntPtr.Size == 4))
            {
                Marshal.FreeHGlobal(pModule);
                throw new InvalidOperationException("The module architecture does not match the process architecture.");
            }

            // Write PE header to memory
            UInt32 SizeOfHeaders = PEINFO.Is32Bit ? PEINFO.OptHeader32.SizeOfHeaders : PEINFO.OptHeader64.SizeOfHeaders;
            UInt32 BytesWritten  = DynamicInvoke.Native.NtWriteVirtualMemory((IntPtr)(-1), pImage, pModule, SizeOfHeaders);

            // Write sections to memory
            foreach (Data.PE.IMAGE_SECTION_HEADER ish in PEINFO.Sections)
            {
                // Calculate offsets
                IntPtr pVirtualSectionBase = (IntPtr)((UInt64)pImage + ish.VirtualAddress);
                IntPtr pRawSectionBase     = (IntPtr)((UInt64)pModule + ish.PointerToRawData);

                // Write data
                BytesWritten = DynamicInvoke.Native.NtWriteVirtualMemory((IntPtr)(-1), pVirtualSectionBase, pRawSectionBase, ish.SizeOfRawData);
                if (BytesWritten != ish.SizeOfRawData)
                {
                    throw new InvalidOperationException("Failed to write to memory.");
                }
            }

            // Perform relocations
            RelocateModule(PEINFO, pImage);

            // Rewrite IAT
            RewriteModuleIAT(PEINFO, pImage);

            // Set memory protections
            SetModuleSectionPermissions(PEINFO, pImage);

            // Free temp HGlobal
            Marshal.FreeHGlobal(pModule);

            // Prepare return object
            Data.PE.PE_MANUAL_MAP ManMapObject = new Data.PE.PE_MANUAL_MAP
            {
                ModuleBase = pImage,
                PEINFO     = PEINFO
            };

            return(ManMapObject);
        }
Exemple #2
0
        /// <summary>
        /// Free a module that was mapped into the current process.
        /// </summary>
        /// <author>The Wover (@TheRealWover)</author>
        /// <param name="peManualMap">The metadata of the manually mapped module.</param>
        public static void FreeModule(Data.PE.PE_MANUAL_MAP peManualMap)
        {
            // Check if PE was mapped via module overloading
            if (!string.IsNullOrEmpty(peManualMap.DecoyModule))
            {
                Native.NtUnmapViewOfSection((IntPtr)(-1), peManualMap.ModuleBase);
            }
            else
            {
                var peMetaData = peManualMap.PEINFO;

                var size    = peMetaData.Is32Bit ? (IntPtr)peMetaData.OptHeader32.SizeOfImage : (IntPtr)peMetaData.OptHeader64.SizeOfImage;
                var pModule = peManualMap.ModuleBase;

                Native.NtFreeVirtualMemory((IntPtr)(-1), ref pModule, ref size, Data.Win32.Kernel32.MEM_RELEASE);
            }
        }
Exemple #3
0
        /// <summary>
        /// Free a module that was mapped into the current process.
        /// </summary>
        /// <author>The Wover (@TheRealWover)</author>
        /// <param name="PEMapped">The metadata of the manually mapped module.</param>
        public static void FreeModule(Data.PE.PE_MANUAL_MAP PEMapped)
        {
            // Check if PE was mapped via module overloading
            if (!string.IsNullOrEmpty(PEMapped.DecoyModule))
            {
                DynamicInvoke.Native.NtUnmapViewOfSection((IntPtr)(-1), PEMapped.ModuleBase);
            }
            // If PE not mapped via module overloading, free the memory.
            else
            {
                Data.PE.PE_META_DATA PEINFO = PEMapped.PEINFO;

                // Get the size of the module in memory
                IntPtr size    = PEINFO.Is32Bit ? (IntPtr)PEINFO.OptHeader32.SizeOfImage : (IntPtr)PEINFO.OptHeader64.SizeOfImage;
                IntPtr pModule = PEMapped.ModuleBase;

                DynamicInvoke.Native.NtFreeVirtualMemory((IntPtr)(-1), ref pModule, ref size, Data.Win32.Kernel32.MEM_RELEASE);
            }
        }
Exemple #4
0
        /// <summary>
        /// Load a signed decoy module into memory creating legitimate file-backed memory sections within the process. Afterwards overload that
        /// module by manually mapping a payload in it's place causing the payload to execute from what appears to be file-backed memory.
        /// </summary>
        /// <author>The Wover (@TheRealWover), Ruben Boonen (@FuzzySec)</author>
        /// <param name="Payload">Full byte array for the payload module.</param>
        /// <param name="DecoyModulePath">Optional, full path the decoy module to overload in memory.</param>
        /// <returns>PE.PE_MANUAL_MAP</returns>
        public static Data.PE.PE_MANUAL_MAP OverloadModule(byte[] Payload, string DecoyModulePath = null, bool LegitSigned = true)
        {
            // Did we get a DecoyModule?
            if (!string.IsNullOrEmpty(DecoyModulePath))
            {
                if (!File.Exists(DecoyModulePath))
                {
                    throw new InvalidOperationException("Decoy filepath not found.");
                }
                byte[] DecoyFileBytes = File.ReadAllBytes(DecoyModulePath);
                if (DecoyFileBytes.Length < Payload.Length)
                {
                    throw new InvalidOperationException("Decoy module is too small to host the payload.");
                }
            }
            else
            {
                DecoyModulePath = FindDecoyModule(Payload.Length);
                if (string.IsNullOrEmpty(DecoyModulePath))
                {
                    throw new InvalidOperationException("Failed to find suitable decoy module.");
                }
            }

            // Map decoy from disk
            Data.PE.PE_MANUAL_MAP DecoyMetaData = Map.MapModuleFromDisk(DecoyModulePath);
            IntPtr RegionSize = DecoyMetaData.PEINFO.Is32Bit ? (IntPtr)DecoyMetaData.PEINFO.OptHeader32.SizeOfImage : (IntPtr)DecoyMetaData.PEINFO.OptHeader64.SizeOfImage;

            // Change permissions to RW
            DynamicInvoke.Native.NtProtectVirtualMemory((IntPtr)(-1), ref DecoyMetaData.ModuleBase, ref RegionSize, Data.Win32.WinNT.PAGE_READWRITE);

            // Zero out memory
            DynamicInvoke.Native.RtlZeroMemory(DecoyMetaData.ModuleBase, (int)RegionSize);

            // Overload module in memory
            Data.PE.PE_MANUAL_MAP OverloadedModuleMetaData = Map.MapModuleToMemory(Payload, DecoyMetaData.ModuleBase);
            OverloadedModuleMetaData.DecoyModule = DecoyModulePath;

            return(OverloadedModuleMetaData);
        }
Exemple #5
0
        /// <summary>
        /// Maps a DLL from disk into a Section using NtCreateSection.
        /// </summary>
        /// <author>The Wover (@TheRealWover), Ruben Boonen (@FuzzySec)</author>
        /// <param name="dllPath">Full path fo the DLL on disk.</param>
        /// <returns>PE.PE_MANUAL_MAP</returns>
        public static Data.PE.PE_MANUAL_MAP MapModuleFromDiskToSection(string dllPath)
        {
            if (!File.Exists(dllPath))
            {
                throw new InvalidOperationException("Filepath not found.");
            }

            var objectName = new Data.Native.UNICODE_STRING();

            Native.RtlInitUnicodeString(ref objectName, @"\??\" + dllPath);

            var pObjectName = Marshal.AllocHGlobal(Marshal.SizeOf(objectName));

            Marshal.StructureToPtr(objectName, pObjectName, true);

            var objectAttributes = new Data.Native.OBJECT_ATTRIBUTES();

            objectAttributes.Length     = Marshal.SizeOf(objectAttributes);
            objectAttributes.ObjectName = pObjectName;
            objectAttributes.Attributes = 0x40;

            var ioStatusBlock = new Data.Native.IO_STATUS_BLOCK();

            var hFile = IntPtr.Zero;

            Native.NtOpenFile(
                ref hFile,
                Data.Win32.Kernel32.FileAccessFlags.FILE_READ_DATA |
                Data.Win32.Kernel32.FileAccessFlags.FILE_EXECUTE |
                Data.Win32.Kernel32.FileAccessFlags.FILE_READ_ATTRIBUTES |
                Data.Win32.Kernel32.FileAccessFlags.SYNCHRONIZE,
                ref objectAttributes, ref ioStatusBlock,
                Data.Win32.Kernel32.FileShareFlags.FILE_SHARE_READ |
                Data.Win32.Kernel32.FileShareFlags.FILE_SHARE_DELETE,
                Data.Win32.Kernel32.FileOpenFlags.FILE_SYNCHRONOUS_IO_NONALERT |
                Data.Win32.Kernel32.FileOpenFlags.FILE_NON_DIRECTORY_FILE
                );

            var   hSection = IntPtr.Zero;
            ulong maxSize  = 0;

            var ret = Native.NtCreateSection(
                ref hSection,
                (uint)Data.Win32.WinNT.ACCESS_MASK.SECTION_ALL_ACCESS,
                IntPtr.Zero,
                ref maxSize,
                Data.Win32.WinNT.PAGE_READONLY,
                Data.Win32.WinNT.SEC_IMAGE,
                hFile
                );

            var pBaseAddress = IntPtr.Zero;

            Native.NtMapViewOfSection(
                hSection, (IntPtr)(-1), ref pBaseAddress,
                IntPtr.Zero, IntPtr.Zero, IntPtr.Zero,
                ref maxSize, 0x2, 0x0,
                Data.Win32.WinNT.PAGE_READWRITE
                );

            var secMapObject = new Data.PE.PE_MANUAL_MAP
            {
                PEINFO     = Generic.GetPeMetaData(pBaseAddress),
                ModuleBase = pBaseAddress
            };

            Win32.CloseHandle(hFile);

            return(secMapObject);
        }
Exemple #6
0
        /// <summary>
        /// Maps a DLL from disk into a Section using NtCreateSection.
        /// </summary>
        /// <author>The Wover (@TheRealWover), Ruben Boonen (@FuzzySec)</author>
        /// <param name="DLLPath">Full path fo the DLL on disk.</param>
        /// <returns>PE.PE_MANUAL_MAP</returns>
        public static Data.PE.PE_MANUAL_MAP MapModuleFromDisk(string DLLPath)
        {
            // Check file exists
            if (!File.Exists(DLLPath))
            {
                throw new InvalidOperationException("Filepath not found.");
            }

            // Open file handle
            Data.Native.UNICODE_STRING ObjectName = new Data.Native.UNICODE_STRING();
            DynamicInvoke.Native.RtlInitUnicodeString(ref ObjectName, (@"\??\" + DLLPath));
            IntPtr pObjectName = Marshal.AllocHGlobal(Marshal.SizeOf(ObjectName));

            Marshal.StructureToPtr(ObjectName, pObjectName, true);

            Data.Native.OBJECT_ATTRIBUTES objectAttributes = new Data.Native.OBJECT_ATTRIBUTES();
            objectAttributes.Length     = Marshal.SizeOf(objectAttributes);
            objectAttributes.ObjectName = pObjectName;
            objectAttributes.Attributes = 0x40; // OBJ_CASE_INSENSITIVE

            Data.Native.IO_STATUS_BLOCK ioStatusBlock = new Data.Native.IO_STATUS_BLOCK();

            IntPtr hFile = IntPtr.Zero;

            DynamicInvoke.Native.NtOpenFile(
                ref hFile,
                Data.Win32.Kernel32.FileAccessFlags.FILE_READ_DATA |
                Data.Win32.Kernel32.FileAccessFlags.FILE_EXECUTE |
                Data.Win32.Kernel32.FileAccessFlags.FILE_READ_ATTRIBUTES |
                Data.Win32.Kernel32.FileAccessFlags.SYNCHRONIZE,
                ref objectAttributes, ref ioStatusBlock,
                Data.Win32.Kernel32.FileShareFlags.FILE_SHARE_READ |
                Data.Win32.Kernel32.FileShareFlags.FILE_SHARE_DELETE,
                Data.Win32.Kernel32.FileOpenFlags.FILE_SYNCHRONOUS_IO_NONALERT |
                Data.Win32.Kernel32.FileOpenFlags.FILE_NON_DIRECTORY_FILE
                );

            // Create section from hFile
            IntPtr hSection = IntPtr.Zero;
            ulong  MaxSize  = 0;

            Data.Native.NTSTATUS ret = DynamicInvoke.Native.NtCreateSection(
                ref hSection,
                (UInt32)Data.Win32.WinNT.ACCESS_MASK.SECTION_ALL_ACCESS,
                IntPtr.Zero,
                ref MaxSize,
                Data.Win32.WinNT.PAGE_READONLY,
                Data.Win32.WinNT.SEC_IMAGE,
                hFile
                );

            // Map view of file
            IntPtr pBaseAddress = IntPtr.Zero;

            DynamicInvoke.Native.NtMapViewOfSection(
                hSection, (IntPtr)(-1), ref pBaseAddress,
                IntPtr.Zero, IntPtr.Zero, IntPtr.Zero,
                ref MaxSize, 0x2, 0x0,
                Data.Win32.WinNT.PAGE_READWRITE
                );

            // Prepare return object
            Data.PE.PE_MANUAL_MAP SecMapObject = new Data.PE.PE_MANUAL_MAP
            {
                PEINFO     = DynamicInvoke.Generic.GetPeMetaData(pBaseAddress),
                ModuleBase = pBaseAddress
            };

            return(SecMapObject);
        }