C ා implement shellcode process start injection eip injection

Keywords: encoding

First of all, code principle

1. Use CreateProcess to create a process marked with create "suspend

The natural process will be suspended after the DLL is created and loaded. The create? Suspend tag was originally prepared for the debugger.

2. Then use GetThreadContext to get the thread context of the process and save it (important)....

3. Use VirtualAllocEx to apply for a section of dll path length + 32 bytes of memory in process space (1K is directly applied here) to store shellcode

And dll path.  

4. Use WriteProcessMemory to write the DLL path to the requested memory address

5. Then combine and calculate shellcode code (calculation will not be explained here, see code Notes for details)

6. Write shellcode to the memory address of the application with WriteProcessMemory

7. Modify the Eip of context state to the memory address just applied for by VirtualAllocEx

8. Set thread context state with SetThreadContext

9. Resume the thread with ResumeThread.


Here are two classes of code: an injection and an API

How to use

 Win32.Injection.EipInject EI = new Win32.Injection.EipInject();

EI.CreateProcess(@"D:\Test.exe",@"D:\Test.dll");

using System;
using System.Runtime.InteropServices;

namespace Win32.Injection
{
    public static class WinApi
    {
        public const int CREATE_SUSPENDED = 0x00000004;
        public const UInt32 MEM_COMMIT = 0x00001000;
        public const UInt32 CONTEXT_i386 = 0x00010000;   // this assumes that i386 and
        public const UInt32 CONTEXT_CONTROL = (CONTEXT_i386 | 0x00000001); // SS:SP, CS:IP, FLAGS, BP

        [DllImport("kernel32")]
        public static extern IntPtr LoadLibrary(string lpLibFileName);
        [DllImport("kernel32")]
        public static extern IntPtr GetProcAddress(IntPtr hModule, string lpProcName);
        [DllImport("kernel32", EntryPoint = "VirtualAllocEx")]
        public static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress, Int32 dwSize, UInt32 flAllocationType, PAGE_EXECUTE_ENUM flProtect);
        [DllImport("kernel32", EntryPoint = "GetThreadContext")]
        public static extern int GetThreadContext(IntPtr hThread, ref CONTEXT lpContext);
        [DllImport("kernel32")]
        public static extern Int32 WriteProcessMemory(IntPtr hProcess, IntPtr lpBassAddress, byte[] lpBuffer, Int32 nSize, IntPtr lpNumberOfBytesRead);
        [DllImport("kernel32", EntryPoint = "SetThreadContext")]
        public static extern int SetThreadContext(IntPtr hThread, ref CONTEXT lpContext);
        [DllImport("kernel32", EntryPoint = "ResumeThread")]
        public static extern int ResumeThread(IntPtr hThread);


        public enum PAGE_EXECUTE_ENUM
        {
            PAGE_EXECUTE_READ = 0x20,
            PAGE_EXECUTE_READWRITE = 0x40
        }

        public struct STARTUPINFO
        {
            public int cb;
            public string lpReserved;
            public string lpDesktop;
            public string 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 int lpReserved2;
            public IntPtr hStdInput;
            public IntPtr hStdOutput;
            public IntPtr hStdError;
        }
        public struct PROCESS_INFORMATION
        {
            public IntPtr hProcess;
            public IntPtr hThread;
            public int dwProcessId;
            public int dwThreadId;
        }

        [DllImport("kernel32", EntryPoint = "CreateProcess")]
        public static extern int CreateProcess(
            string lpApplicationName,
            string lpCommandLine,
            IntPtr lpProcessAttributes,
            IntPtr lpThreadAttributes,
            bool bInheritHandles,
            int dwCreationFlags,
            IntPtr lpEnvironment,
            String lpCurrentDriectory,
            ref STARTUPINFO lpStartupInfo,
            ref PROCESS_INFORMATION lpProcessInformation);

        public struct FLOATING_SAVE_AREA
        {
            public UInt32 ControlWord;
            public UInt32 StatusWord;
            public UInt32 TagWord;
            public UInt32 ErrorOffset;
            public UInt32 ErrorSelector;
            public UInt32 DataOffset;
            public UInt32 DataSelector;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 80)]
            public Byte[] RegisterArea;
            public UInt32 Spare0;
        }
        /// <summary>
        ///Register context
        /// </summary>
        public struct CONTEXT
        {
            public UInt32 ContextFlags;
            //
            // This section is specified/returned if CONTEXT_DEBUG_REGISTERS is
            // set in ContextFlags.  Note that CONTEXT_DEBUG_REGISTERS is NOT
            // included in CONTEXT_FULL.
            //
            public UInt32 Dr0;
            public UInt32 Dr1;
            public UInt32 Dr2;
            public UInt32 Dr3;
            public UInt32 Dr6;
            public UInt32 Dr7;

            //
            // This section is specified/returned if the
            // ContextFlags word contians the flag CONTEXT_FLOATING_POINT.
            //

            public FLOATING_SAVE_AREA FloatSave;

            //
            // This section is specified/returned if the
            // ContextFlags word contians the flag CONTEXT_SEGMENTS.
            //

            public UInt32 SegGs;
            public UInt32 SegFs;
            public UInt32 SegEs;
            public UInt32 SegDs;

            //
            // This section is specified/returned if the
            // ContextFlags word contians the flag CONTEXT_INTEGER.
            //

            public UInt32 Edi;
            public UInt32 Esi;
            public UInt32 Ebx;
            public UInt32 Edx;
            public UInt32 Ecx;
            public UInt32 Eax;

            //
            // This section is specified/returned if the
            // ContextFlags word contians the flag CONTEXT_CONTROL.
            //

            public UInt32 Ebp;
            public UInt32 Eip;
            public UInt32 SegCs;              // MUST BE SANITIZED
            public UInt32 EFlags;             // MUST BE SANITIZED
            public UInt32 Esp;
            public UInt32 SegSs;

            //
            // This section is specified/returned if the ContextFlags word
            // contains the flag CONTEXT_EXTENDED_REGISTERS.
            // The format and contexts are processor specific
            //

            //BYTE ExtendedRegisters[MAXIMUM_SUPPORTED_EXTENSION];

            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 512)]
            public Byte[] ExtendedRegisters;
        }



    }
}

using System;
using System.Text;

namespace Win32.Injection
{
    public class EipInject
    {

        public EipInject()
        {
            // pushad  
            ShellCode[0] = 0x60;
            // pushfd  
            ShellCode[1] = 0x9c;
            // push  
            ShellCode[2] = 0x68;
            //call  
            ShellCode[7] = 0xE8;
            // popfd 
            ShellCode[12] = 0x9d;
            // popad
            ShellCode[13] = 0x61;
            // jmp 
            ShellCode[14] = 0xE9;
            hModule = WinApi.LoadLibrary("Kernel32.dll");
            //Get MessageBoxA address
            LoadLibrary_addr = WinApi.GetProcAddress(hModule, "LoadLibraryA");
        }

        /// <summary>
        ///Create the specified process and load the DLL
        /// </summary>
        /// <param name="AppPath"></param>
        /// <param name="DllPath"></param>
        /// <returns></returns>
        public bool CreateProcess(String AppPath, String DllPath)
        {

            WinApi.CONTEXT context = new WinApi.CONTEXT();
            Byte[] DllPathData = Encoding.Default.GetBytes(DllPath);
            if (!_CreateProcess(AppPath))
            {
                return false;
            }
            //Get thread context
            context.ContextFlags = WinApi.CONTEXT_CONTROL;
            if (WinApi.GetThreadContext(hThread, ref context) != 0)
            {
                Int32 dwSize = 1024;
                //Request memory
                IntPtr pProcessMem = AllocMemory(dwSize);
                if (pProcessMem == IntPtr.Zero)
                {
                    return false;
                }
                //DLL path address pprocesmem + 0x100
                BuilderValue(ShellCode, 3, pProcessMem + 0x100);
                //LoadLibrary address is equal to CALL absolute address - next instruction address
                BuilderValue(ShellCode, 8, LoadLibrary_addr - (pProcessMem.ToInt32() + 12));
                // Skip back to the old EIP address ct.eip - (pprocesmem + 19); (absolute address next instruction address)
                BuilderValue(ShellCode, 15, (int)context.Eip - (pProcessMem.ToInt32() + 19));
                //First write the ShellCode in the address
                WinApi.WriteProcessMemory(hProcess, pProcessMem, ShellCode, ShellCode.Length, IntPtr.Zero);
                //Write DLL path to memory, starting from 0x100(256) 
                WinApi.WriteProcessMemory(hProcess, (pProcessMem + 0x100), DllPathData, DllPathData.Length, IntPtr.Zero);
                //Rewrite EIP
                context.Eip = (UInt32)pProcessMem;
                //Write thread context back
                WinApi.SetThreadContext(hThread, ref context);
                //Resume suspended threads
                WinApi.ResumeThread(hThread);
                return true;
            }
            else
            {
                return false;
            }
        }

        /// <summary>
        ///Responsible for creating a suspended process
        /// </summary>
        /// <param name="AppPath"></param>
        /// <returns></returns>
        private bool _CreateProcess(String AppPath)
        {
            WinApi.STARTUPINFO si = new WinApi.STARTUPINFO();
            WinApi.PROCESS_INFORMATION PI = new WinApi.PROCESS_INFORMATION();
            int HResult = WinApi.CreateProcess(
                null,
                //   Program path command line
                AppPath,
                IntPtr.Zero,
                IntPtr.Zero,
                false,
                //   Suspend process only debug this process
                WinApi.CREATE_SUSPENDED,
                IntPtr.Zero,
                //working directory
                System.IO.Path.GetDirectoryName(AppPath),
                ref si,
                ref PI);
            if (HResult == 0)
                return false;
            hProcess = PI.hProcess;
            hThread = PI.hThread;
            return true;
        }
        /// <summary>
        ///Responsible for applying for a section of memory
        /// </summary>
        /// <param name="Size"></param>
        /// <returns></returns>
        private IntPtr AllocMemory(Int32 Size)
        {
            return WinApi.VirtualAllocEx(hProcess, IntPtr.Zero, Size, WinApi.MEM_COMMIT, WinApi.PAGE_EXECUTE_ENUM.PAGE_EXECUTE_READWRITE);
        }

        /// <summary>
        ///Responsible for writing four byte integers into shellcode
        /// </summary>
        /// <param name="ShellCode"></param>
        /// <param name="Index"></param>
        /// <param name="Value"></param>
        private void BuilderValue(Byte[] ShellCode, Int32 Index, IntPtr Value)
        {
            Byte[] DATA = BitConverter.GetBytes(Value.ToInt32());
            Array.Copy(DATA, 0, ShellCode, Index, 4);
        }

        /// <summary>
        ///Responsible for writing four byte integers into shellcode
        /// </summary>
        /// <param name="ShellCode"></param>
        /// <param name="Index"></param>
        /// <param name="Value"></param>
        private void BuilderValue(Byte[] ShellCode, Int32 Index, Int32 Value)
        {
            Byte[] DATA = BitConverter.GetBytes(Value);
            Array.Copy(DATA, 0, ShellCode, Index, 4);
        }



        /// <summary>
        ///Create process handle
        /// </summary>
        public IntPtr hProcess = IntPtr.Zero;
        /// <summary>
        ///Create process thread handle
        /// </summary>
        public IntPtr hThread = IntPtr.Zero;
        private IntPtr hModule = IntPtr.Zero;
        private IntPtr LoadLibrary_addr = IntPtr.Zero;
        private Byte[] ShellCode = new byte[32];

    }
}







Posted by PHPFEEDER on Tue, 05 May 2020 18:29:28 -0700