From c07b87a04d0250f8b4a1ef5016cd2e2ebccf6081 Mon Sep 17 00:00:00 2001 From: Gerardo Grignoli Date: Fri, 15 Dec 2023 19:46:22 -0300 Subject: [PATCH 1/4] Removed deprecated & unused AttachRunCommand --- src/gsudo/Commands/AttachRunCommand.cs | 60 -------------------------- src/gsudo/Helpers/CommandLineParser.cs | 3 -- 2 files changed, 63 deletions(-) delete mode 100644 src/gsudo/Commands/AttachRunCommand.cs diff --git a/src/gsudo/Commands/AttachRunCommand.cs b/src/gsudo/Commands/AttachRunCommand.cs deleted file mode 100644 index cc8a5184..00000000 --- a/src/gsudo/Commands/AttachRunCommand.cs +++ /dev/null @@ -1,60 +0,0 @@ -using System; -using gsudo.Helpers; -using System.Collections.Generic; -using System.ComponentModel; -using System.IO; -using System.Linq; -using System.Threading.Tasks; -using gsudo.Native; - -namespace gsudo.Commands -{ - /// - /// This command attaches to the parent console, then executes the command. - /// This works even if the parent has higher integrity level than us. - /// This must be launched by the caller gsudo and not the elevated service, because the parent process id must have the user console. - /// - class AttachRunCommand : ICommand - { - public IEnumerable CommandToRun { get; private set; } - - public AttachRunCommand(IEnumerable commandToRun) - { - CommandToRun = commandToRun; - } - - public Task Execute() - { - ConsoleApi.FreeConsole(); - if (!ConsoleApi.AttachConsole(-1)) - { - ConsoleApi.AllocConsole(); - throw new ApplicationException($"Failed to attach console: {new Win32Exception()}"); - } - - var app = CommandToRun.First(); - var args = string.Join(" ", CommandToRun.Skip(1).ToArray()); - - if (InputArguments.IntegrityLevel.HasValue && - (int) InputArguments.IntegrityLevel != SecurityHelper.GetCurrentIntegrityLevel() && - Environment.GetEnvironmentVariable("gsudoAttachRun") != "1") - { - Environment.SetEnvironmentVariable("gsudoAttachRun", "1"); // prevents infinite loop on machines with UAC disabled. - - var process = ProcessFactory.StartAttachedWithIntegrity( - InputArguments.GetIntegrityLevel(), app, args, Directory.GetCurrentDirectory(), false, true); - - process.GetProcessWaitHandle().WaitOne(); - - if (ProcessApi.GetExitCodeProcess(process, out var exitCode)) - return Task.FromResult(exitCode); - } - else - { - ProcessFactory.StartAttached(app, args).WaitForExit(); - } - - return Task.FromResult(0); - } - } -} diff --git a/src/gsudo/Helpers/CommandLineParser.cs b/src/gsudo/Helpers/CommandLineParser.cs index 5bc10b94..cb405d2f 100644 --- a/src/gsudo/Helpers/CommandLineParser.cs +++ b/src/gsudo/Helpers/CommandLineParser.cs @@ -274,9 +274,6 @@ private ICommand ParseVerb() if (arg.In("run")) return new RunCommand(commandToRun: args.ToArray()); - if (arg.In("AttachRun")) - return new AttachRunCommand(commandToRun: args.ToArray()); - args.AddFirst(arg); if (arg == "!!" || arg.StartsWith("!", StringComparison.InvariantCulture)) From 9d3fafc6c35a760686f0de43d88cceda3704bc5a Mon Sep 17 00:00:00 2001 From: Gerardo Grignoli Date: Mon, 18 Dec 2023 09:55:58 -0300 Subject: [PATCH 2/4] Add 'whoami.exe' to exception list (forced cmd /c whoami.exe) --- src/gsudo/AppSettings/Settings.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gsudo/AppSettings/Settings.cs b/src/gsudo/AppSettings/Settings.cs index d1003511..ae85bd3e 100644 --- a/src/gsudo/AppSettings/Settings.cs +++ b/src/gsudo/AppSettings/Settings.cs @@ -82,7 +82,7 @@ class Settings public static RegistrySetting ExceptionList { get; } = new RegistrySetting(nameof(ExceptionList), - defaultValue: "notepad.exe;powershell.exe;", + defaultValue: "notepad.exe;powershell.exe;whoami.exe;", deserializer: (string s)=>s, scope: RegistrySettingScope.GlobalOnly); From fd523ce5352801f1c3839d20e5471e4a2b4b0b5c Mon Sep 17 00:00:00 2001 From: Gerardo Grignoli Date: Mon, 18 Dec 2023 09:56:21 -0300 Subject: [PATCH 3/4] - Rearrange service location check in RunCommand.cs for better error handling. --- src/gsudo/Commands/RunCommand.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/gsudo/Commands/RunCommand.cs b/src/gsudo/Commands/RunCommand.cs index 0302ef66..58dc5667 100644 --- a/src/gsudo/Commands/RunCommand.cs +++ b/src/gsudo/Commands/RunCommand.cs @@ -120,15 +120,15 @@ private async Task RunUsingService(ElevationRequest elevationRequest) serviceLocation = await ServiceHelper.WaitForNewService(callingPid).ConfigureAwait(false); } + if (serviceLocation==null) + throw new ApplicationException("Unable to connect to the elevated service."); + if (!InputArguments.IntegrityLevel.HasValue) { // This is the edge case where user does `gsudo -u SomeOne` and we dont know if SomeOne can elevate or not. elevationRequest.IntegrityLevel = serviceLocation.IsHighIntegrity ? IntegrityLevel.High : IntegrityLevel.Medium; } - if (serviceLocation==null) - throw new ApplicationException("Unable to connect to the elevated service."); - connection = await ServiceHelper.Connect(serviceLocation).ConfigureAwait(false); if (connection == null) // service is not running or listening. { From 49738f066fe27168ce7fb000a66ce7f27674cea1 Mon Sep 17 00:00:00 2001 From: Gerardo Grignoli Date: Mon, 18 Dec 2023 09:56:43 -0300 Subject: [PATCH 4/4] - Update NamedPipeNameFactory.cs to incorporate system run flag in pipe naming. - Adjust ServiceHelper.cs to support system run scenarios with target user SID. --- src/gsudo/Helpers/ServiceHelper.cs | 5 ++++- src/gsudo/Rpc/NamedPipeNameFactory.cs | 5 +++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/gsudo/Helpers/ServiceHelper.cs b/src/gsudo/Helpers/ServiceHelper.cs index c777e6f8..c615c0be 100644 --- a/src/gsudo/Helpers/ServiceHelper.cs +++ b/src/gsudo/Helpers/ServiceHelper.cs @@ -71,9 +71,12 @@ private static ServiceLocation FindServiceByIntegrity(int? clientPid, string use var anyIntegrity = InputArguments.UserName != null; var tryHighIntegrity = !InputArguments.IntegrityLevel.HasValue || InputArguments.IntegrityLevel.Value >= IntegrityLevel.High; var tryLowIntegrity = !InputArguments.IntegrityLevel.HasValue || InputArguments.IntegrityLevel.Value < IntegrityLevel.High; + + var targetUserSid = InputArguments.RunAsSystem ? "S-1-5-18" : InputArguments.UserSid; + if (tryHighIntegrity) { - var pipeName = NamedPipeClient.TryGetServicePipe(user, clientPid.Value, true); + var pipeName = NamedPipeClient.TryGetServicePipe(user, clientPid.Value, true, null); if (pipeName != null) { return new ServiceLocation diff --git a/src/gsudo/Rpc/NamedPipeNameFactory.cs b/src/gsudo/Rpc/NamedPipeNameFactory.cs index 362b5b6c..d0484279 100644 --- a/src/gsudo/Rpc/NamedPipeNameFactory.cs +++ b/src/gsudo/Rpc/NamedPipeNameFactory.cs @@ -13,9 +13,10 @@ public static string GetPipeName(string allowedSid, int allowedPid, string targe if (allowedPid < 0) allowedPid = 0; var ti = InputArguments.TrustedInstaller ? "_TI" : string.Empty; - var admin = !isAdmin ? "_NonAdmin" : string.Empty; + var s = InputArguments.RunAsSystem ? "_S" : string.Empty; + var admin = !isAdmin ? "_NonAdmin" : string.Empty; - var data = $"{allowedSid}_{targetSid}_{allowedPid}_{ti}{admin}"; + var data = $"allowedSid-{allowedSid}_targetSid-{targetSid}{allowedPid}{s}{ti}{admin}"; #if !DEBUG data = GetHash(data); #endif