static void Main(string[] args) { try { if (!IsInAppContainer()) { if (args.Length > 0) { throw new ArgumentException("Already started"); } Win32ProcessConfig config = new Win32ProcessConfig(); config.ApplicationName = CopyToTempDir(); config.CommandLine = "run abc"; config.AppContainerSid = TokenUtils.DerivePackageSidFromName("microsoft.windowscalculator_8wekyb3d8bbwe"); config.CreationFlags = CreateProcessFlags.NewConsole; using (var p = Win32Process.CreateProcess(config)) { p.Process.Wait(); } } else { Console.WriteLine("In AC"); Console.WriteLine("idiot"); // Spawn an OOP process to init Guid clsid = new Guid("ce0e0be8-cf56-4577-9577-34cc96ac087c"); Guid iid = new Guid("00000000-0000-0000-c000-000000000046"); CoCreateInstance(ref clsid, IntPtr.Zero, CLSCTX.LOCAL_SERVER, ref iid); using (var client = new Client()) { client.Connect("actkernel"); uint res = client.PrivGetPsmToken(0x40000001, 0, "Microsoft.MicrosoftEdge_44.18362.1.0_neutral__8wekyb3d8bbwe", "Microsoft.MicrosoftEdge_8wekyb3d8bbwe!MicrosoftEdge", out NtToken token, out int a); if (res != 0) { throw new SafeWin32Exception((int)res); } using (token) { Console.WriteLine("{0} - Handle: {1:X}", token, token.Handle.DangerousGetHandle().ToInt32()); Console.WriteLine("Package Sid: {0}", token.AppContainerSid.Name); Console.WriteLine("AppId: {0}", token.PackageFullName); Console.ReadLine(); } } } } catch (Exception ex) { Console.WriteLine(ex); Console.ReadLine(); } }
static bool RestartInAppContainer(string[] args) { string FakeFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyPictures), "1.txt"); if (!File.Exists(FakeFile)) { File.WriteAllText(FakeFile, "fake"); } FixSecurity(Path.GetDirectoryName(typeof(Program).Assembly.Location)); FixSecurity(Environment.GetFolderPath(Environment.SpecialFolder.MyPictures)); List <Sid> caps = new List <Sid> { KnownSids.CapabilityInternetClient, KnownSids.CapabilityInternetClientServer, KnownSids.CapabilityPrivateNetworkClientServer, KnownSids.CapabilityPicturesLibrary }; Win32ProcessConfig config = new Win32ProcessConfig { CreationFlags = CreateProcessFlags.NewConsole, CurrentDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures), ApplicationName = mainExe, CommandLine = mainExe + " " + FakeFile }; config.SetAppContainerSidFromName("microsoft.windowscalculator_8wekyb3d8bbwe"); config.Capabilities.AddRange(caps); using (var p = Win32Process.CreateProcess(config)) { p.Process.Wait(); } return(true); }
static void Main(string[] args) { Win32Process new_process = null; try { CreateProcessFlags flags = CreateProcessFlags.None; bool parent_process = false; bool set_il = false; TokenIntegrityLevel il = 0; bool show_help = false; OptionSet opts = new OptionSet() { { "p", "Use parent technique to create the new process", v => parent_process = v != null }, { "j", "Try and break away from the current process job", v => flags |= v != null ? CreateProcessFlags.BreakawayFromJob : 0 }, { "c", "Create a new console for the process", v => flags |= v != null ? CreateProcessFlags.NewConsole : 0 }, { "s", "Create the process suspended", v => flags |= v != null ? CreateProcessFlags.Suspended : 0 }, { "i|il=", "Set the process IL level", v => { il = ParseIL(v); set_il = true; } }, { "h|help", "show this message and exit", v => show_help = v != null }, }; int pid; List <string> commands = opts.Parse(args); if (show_help || commands.Count < 2) { ShowHelp(opts); } if (!int.TryParse(commands[0], out pid)) { throw new ArgumentException("Couldn't parse PID value"); } if (!NtToken.EnableDebugPrivilege()) { Console.WriteLine("WARNING: Couldn't enable Debug privilege"); } using (NtProcess process = NtProcess.Open(pid, ProcessAccessRights.MaximumAllowed)) { if (parent_process) { new_process = Win32Process.CreateProcess(process, null, commands[1], set_il ? flags | CreateProcessFlags.Suspended : flags, null); if (set_il) { using (NtToken token = new_process.Process.OpenToken()) { token.SetIntegrityLevel(il); } if ((flags & CreateProcessFlags.Suspended) == 0) { new_process.Thread.Resume(); } } } else { using (NtToken token = process.OpenToken()) { using (NtToken target_token = token.DuplicateToken(TokenType.Primary, SecurityImpersonationLevel.Anonymous, TokenAccessRights.MaximumAllowed)) { if (set_il) { target_token.SetIntegrityLevel(il); } new_process = Win32Process.CreateProcessAsUser(target_token, null, commands[1], flags, null); } } } using (new_process) { Console.WriteLine("Created Process: PID: {0}, SID {1}", new_process.Pid, new_process.Process.SessionId); } } } catch (Exception ex) { Console.WriteLine("ERROR: {0}", ex.Message); if (new_process != null && new_process.Process != null) { try { new_process.Process.Terminate(NtStatus.STATUS_WAIT_1); } catch { } } } }
/// <summary> /// Starts the process isolated. /// </summary> /// <param name="isolationIdentifier">Name identifier for the isolation. This has to be unique. Under windows this is the name of the AppContainerIsolator.</param> /// <param name="path">The path to the executable.</param> /// <param name="commandLineArguments">The command line arguments.</param> /// <param name="networkPermissions">The network permissions the process should have.</param> /// <param name="attachToCurrentProcess"> /// If set to <c>true</c> the started process will be terminated when the current /// process exits. /// </param> /// <param name="fileAccess">The extended file access. Allows for custom file and folder access rights.</param> /// <param name="makeApplicationDirectoryReadable"> /// By default the folder containing the executable will be made available to the process to allow loading dependencies. /// Set this to false to suppress this behaviour. /// </param> /// <param name="workingDirectory"> /// The working directory of the process. /// </param> /// <returns> /// The process object. Needs to be disposed. /// </returns> /// <exception cref="ArgumentException">$"Couldn't resolve directory for '{path}'.</exception> public IIsolatedProcess StartIsolatedProcess( string isolationIdentifier, string path, string[]?commandLineArguments = null, NetworkPermissions networkPermissions = NetworkPermissions.None, bool attachToCurrentProcess = true, IEnumerable <FileAccess>?fileAccess = null, bool makeApplicationDirectoryReadable = true, string?workingDirectory = null) { string applicationName = Path.GetFileNameWithoutExtension(path); var container = AppContainerProfile.Create( isolationIdentifier, $"{applicationName} Container ({isolationIdentifier})", $"Application container for {applicationName}"); var config = new Win32ProcessConfig { ApplicationName = path, CommandLine = commandLineArguments is not null?string.Join(" ", commandLineArguments) : string.Empty, ChildProcessMitigations = ChildProcessMitigationFlags.Restricted, AppContainerSid = container.Sid, TerminateOnDispose = true, CurrentDirectory = workingDirectory is null ? null : Path.GetFullPath(workingDirectory), }; // Allow the process to access it's own files. if (makeApplicationDirectoryReadable) { var appDirectory = Path.GetDirectoryName(path) ?? throw new ArgumentException($"Couldn't resolve directory for '{path}'."); AllowFileAccess(container, appDirectory, FileAccessRights.GenericRead); } // Apply user folder and file permissions if (fileAccess is not null) { foreach (var cur in fileAccess) { if (!Directory.Exists(cur.Path) && !File.Exists(cur.Path)) { throw new ArgumentException($"The file or folder '{cur.Path}' does not exist."); } AllowFileAccess( container, cur.Path, (FileAccessRights)cur.AccessRight); } } // Apply network networkPermissions if ((networkPermissions & NetworkPermissions.LocalNetwork) != 0) { config.AddCapability(KnownSids.CapabilityPrivateNetworkClientServer); } if ((networkPermissions & NetworkPermissions.Internet) != 0) { config.AddCapability(KnownSids.CapabilityInternetClient); } var process = Win32Process.CreateProcess(config); // Make sure the new process gets killed when the current process stops. if (attachToCurrentProcess) { _childProcessCascadeCloseJob.Value.AssignProcess(process.Process); } return(new IsolatedWin32Process(process, container)); }