From f3b2da0595e6a7d862c39ff5d92b52c8b932d9e8 Mon Sep 17 00:00:00 2001 From: Violet Hansen Date: Thu, 26 Dec 2024 10:01:36 +0200 Subject: [PATCH 1/2] MDE Advanced Hunting menu icon no longer nested MDE Advanced Hunting menu icon no longer nested in the main navigation. --- AppControl Manager/MainWindow.xaml | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/AppControl Manager/MainWindow.xaml b/AppControl Manager/MainWindow.xaml index 4a2ec3cd6..5ac1f0ba5 100644 --- a/AppControl Manager/MainWindow.xaml +++ b/AppControl Manager/MainWindow.xaml @@ -194,14 +194,8 @@ - - - - - - - - + + From d9918294099366be7bb71d5291ca76e0f4cdc58d Mon Sep 17 00:00:00 2001 From: Violet Hansen Date: Thu, 26 Dec 2024 10:06:32 +0200 Subject: [PATCH 2/2] Added signed policy support to AllowNewApps page Added signed policy support to AllowNewApps page --- AppControl Manager/App.xaml.cs | 3 - .../SigningDetailsDialog.xaml.cs | 3 + .../SigningDetailsDialogForRemoval.xaml.cs | 3 + .../AllowNewApps/AllowNewAppsStart.xaml.cs | 207 ++++++++++++++---- 4 files changed, 176 insertions(+), 40 deletions(-) diff --git a/AppControl Manager/App.xaml.cs b/AppControl Manager/App.xaml.cs index 1cb8ce60d..9be248c3a 100644 --- a/AppControl Manager/App.xaml.cs +++ b/AppControl Manager/App.xaml.cs @@ -44,10 +44,7 @@ public App() { this.InitializeComponent(); -#if DEBUG - Logger.Write("App Startup"); -#endif // Give beautiful outline to the UI elements when using the tab key and keyboard for navigation // https://learn.microsoft.com/en-us/windows/apps/design/style/reveal-focus diff --git a/AppControl Manager/CustomUIElements/SigningDetailsDialog.xaml.cs b/AppControl Manager/CustomUIElements/SigningDetailsDialog.xaml.cs index 591ee4fbb..36f95381c 100644 --- a/AppControl Manager/CustomUIElements/SigningDetailsDialog.xaml.cs +++ b/AppControl Manager/CustomUIElements/SigningDetailsDialog.xaml.cs @@ -300,6 +300,9 @@ private async void VerifyButton_Click(object sender, RoutedEventArgs e) // Set the SignTool.exe path that was verified to be valid to the user configurations _ = UserConfiguration.Set(SignToolCustomPath: SignToolPath); + + // Set certificate details that were verified to the user configurations + _ = UserConfiguration.Set(CertificateCommonName: CertificateCommonNameAutoSuggestBox.Text, CertificatePath: CertFilePathTextBox.Text); } finally { diff --git a/AppControl Manager/CustomUIElements/SigningDetailsDialogForRemoval.xaml.cs b/AppControl Manager/CustomUIElements/SigningDetailsDialogForRemoval.xaml.cs index 095bf754c..9230db3fe 100644 --- a/AppControl Manager/CustomUIElements/SigningDetailsDialogForRemoval.xaml.cs +++ b/AppControl Manager/CustomUIElements/SigningDetailsDialogForRemoval.xaml.cs @@ -382,6 +382,9 @@ await Task.Run(() => // Set the SignTool.exe path that was verified to be valid to the user configurations _ = UserConfiguration.Set(SignToolCustomPath: SignToolPath); + + // Set certificate details that were verified to the user configurations + _ = UserConfiguration.Set(CertificateCommonName: CertificateCommonNameAutoSuggestBox.Text, CertificatePath: CertFilePathTextBox.Text); } finally { diff --git a/AppControl Manager/Pages/AllowNewApps/AllowNewAppsStart.xaml.cs b/AppControl Manager/Pages/AllowNewApps/AllowNewAppsStart.xaml.cs index e6f4490b3..78478ebb1 100644 --- a/AppControl Manager/Pages/AllowNewApps/AllowNewAppsStart.xaml.cs +++ b/AppControl Manager/Pages/AllowNewApps/AllowNewAppsStart.xaml.cs @@ -5,8 +5,11 @@ using System.Linq; using System.Numerics; using System.Threading.Tasks; +using AppControlManager.CustomUIElements; using AppControlManager.IntelGathering; using AppControlManager.Logging; +using AppControlManager.SiPolicy; +using AppControlManager.SiPolicyIntel; using AppControlManager.XMLOps; using Microsoft.UI; using Microsoft.UI.Xaml; @@ -14,10 +17,8 @@ using Microsoft.UI.Xaml.Media; using Microsoft.UI.Xaml.Navigation; - namespace AppControlManager.Pages; - public sealed partial class AllowNewAppsStart : Page, Sidebar.IAnimatedIconsManager { @@ -82,6 +83,18 @@ public sealed partial class AllowNewAppsStart : Page, Sidebar.IAnimatedIconsMana // The ThemeShadow defined in Grid XAML private readonly ThemeShadow sharedShadow; + // Will determine whether the user selected XML policy file is signed or unsigned + private bool _IsSignedPolicy; + + // The base policy XML objectified + private SiPolicy.SiPolicy? _BasePolicyObject; + + // To hold the necessary details for policy signing if the selected base policy is signed + // They will be retrieved from the content dialog + private string? _CertCN; + private string? _CertPath; + private string? _SignToolPath; + public AllowNewAppsStart() { this.InitializeComponent(); @@ -276,24 +289,21 @@ private async void GoToStep2Button_Click(object sender, RoutedEventArgs e) throw new InvalidOperationException("You need to select a XML policy file path"); } + // Ensure the selected XML file path exists on the disk + if (!File.Exists(selectedXMLFilePath)) + { + throw new InvalidOperationException($"The selected XML file path doesn't exist {selectedXMLFilePath}"); + } - // Create the required directory and file paths in step 1 - stagingArea = StagingArea.NewStagingArea("AllowNewApps"); - tempBasePolicyPath = Path.Combine(stagingArea.FullName, "BasePolicy.XML"); - AuditModeCIP = Path.Combine(stagingArea.FullName, "BaseAudit.cip"); - - // Make sure it stays unique because it's being put outside of the StagingArea and we don't want any other command to remove or overwrite it - EnforcedModeCIP = Path.Combine(GlobalVars.UserConfigDir, $"BaseEnforced-{SiPolicyIntel.GUIDGenerator.GenerateUniqueGUID()}.cip"); - - Step1InfoBar.IsOpen = true; - Step1InfoBar.Message = "Deploying the selected policy in Audit mode, please wait"; - - // Execute the main tasks of step 1 await Task.Run(() => { + // Instantiate the selected policy file + _BasePolicyObject = Management.Initialize(selectedXMLFilePath); - // Instantiate the policy - CodeIntegrityPolicy codeIntegrityPolicy = new(selectedXMLFilePath, null); + if (_BasePolicyObject.PolicyType is not PolicyType.BasePolicy) + { + throw new InvalidOperationException($"The selected XML policy file must be Base policy type, but its type is '{_BasePolicyObject.PolicyType}'"); + } // Get all deployed base policies List allDeployedBasePolicies = CiToolHelper.GetPolicies(false, true, false); @@ -302,32 +312,122 @@ await Task.Run(() => List CurrentlyDeployedBasePolicyIDs = [.. allDeployedBasePolicies.Select(p => p.BasePolicyID)]; // Trim the curly braces from the policyID - string trimmedPolicyID = codeIntegrityPolicy.PolicyID.TrimStart('{').TrimEnd('}'); + string trimmedPolicyID = _BasePolicyObject.PolicyID.TrimStart('{').TrimEnd('}'); - // Make sure the selected policy is a base and that it is deployed on the system + // Make sure the selected policy is deployed on the system if (!CurrentlyDeployedBasePolicyIDs.Any(id => string.Equals(id, trimmedPolicyID, StringComparison.OrdinalIgnoreCase))) { - throw new InvalidOperationException($"The selected policy file {selectedXMLFilePath} is not deployed on the system or it's not a base policy"); + throw new InvalidOperationException($"The selected policy file {selectedXMLFilePath} is not deployed on the system."); } - // Make sure the policy is not signed - CiPolicyInfo detectedBasePolicy = allDeployedBasePolicies.First(p => string.Equals(p.PolicyID, trimmedPolicyID, StringComparison.OrdinalIgnoreCase)); - if (detectedBasePolicy.IsSignedPolicy) + // If the policy doesn't have any rule options or it doesn't have the EnabledUnsignedSystemIntegrityPolicy rule option then it is signed + _IsSignedPolicy = (_BasePolicyObject.Rules is null || !_BasePolicyObject.Rules.Any(rule => rule.Item is OptionType.EnabledUnsignedSystemIntegrityPolicy)); + }); + + + if (_IsSignedPolicy) + { + + Logger.Write("Signed policy detected"); + + #region Signing Details acquisition + + // Instantiate the Content Dialog + SigningDetailsDialog customDialog = new(); + + // Show the dialog and await its result + ContentDialogResult result = await customDialog.ShowAsync(); + + // Ensure primary button was selected + if (result is ContentDialogResult.Primary) + { + _SignToolPath = customDialog.SignToolPath!; + _CertPath = customDialog.CertificatePath!; + _CertCN = customDialog.CertificateCommonName!; + } + else { - throw new InvalidOperationException("The selected policy is signed. Signed policies are not supported yet."); + GoToStep2Button.IsEnabled = true; + + return; } + #endregion + } + + + // Execute the main tasks of step 1 + await Task.Run(() => + { + + // Create the required directory and file paths in step 1 + stagingArea = StagingArea.NewStagingArea("AllowNewApps"); + tempBasePolicyPath = Path.Combine(stagingArea.FullName, "BasePolicy.XML"); + AuditModeCIP = Path.Combine(stagingArea.FullName, "BaseAudit.cip"); + + // Make sure it stays unique because it's being put outside of the StagingArea and we don't want any other command to remove or overwrite it + EnforcedModeCIP = Path.Combine(GlobalVars.UserConfigDir, $"BaseEnforced-{GUIDGenerator.GenerateUniqueGUID()}.cip"); + + _ = DispatcherQueue.TryEnqueue(() => + { + Step1InfoBar.IsOpen = true; + Step1InfoBar.Message = "Deploying the selected policy in Audit mode, please wait"; + }); + // Creating a copy of the original policy in the Staging Area so that the original one will be unaffected File.Copy(selectedXMLFilePath, tempBasePolicyPath, true); - // Create audit mode CIP - CiRuleOptions.Set(filePath: tempBasePolicyPath, rulesToAdd: [CiRuleOptions.PolicyRuleOptions.EnabledAuditMode]); - PolicyToCIPConverter.Convert(tempBasePolicyPath, AuditModeCIP); + // If the policy is Unsigned + if (!_IsSignedPolicy) + { + // Create audit mode CIP + CiRuleOptions.Set(filePath: tempBasePolicyPath, rulesToAdd: [CiRuleOptions.PolicyRuleOptions.EnabledAuditMode]); + PolicyToCIPConverter.Convert(tempBasePolicyPath, AuditModeCIP); + + // Create Enforced mode CIP + CiRuleOptions.Set(filePath: tempBasePolicyPath, rulesToRemove: [CiRuleOptions.PolicyRuleOptions.EnabledAuditMode]); + PolicyToCIPConverter.Convert(tempBasePolicyPath, EnforcedModeCIP); + } + + // If the policy is Signed + else + { + + // Create audit mode CIP + CiRuleOptions.Set(filePath: tempBasePolicyPath, rulesToAdd: [CiRuleOptions.PolicyRuleOptions.EnabledAuditMode], rulesToRemove: [CiRuleOptions.PolicyRuleOptions.EnabledUnsignedSystemIntegrityPolicy]); + + string CIPp7SignedFilePathAudit = Path.Combine(stagingArea.FullName, "BaseAudit.cip.p7"); + + // Convert the XML file to CIP + PolicyToCIPConverter.Convert(tempBasePolicyPath, AuditModeCIP); + + // Sign the CIP + SignToolHelper.Sign(new FileInfo(AuditModeCIP), new FileInfo(_SignToolPath!), _CertCN!); + + // Rename the .p7 signed file to .cip + File.Move(CIPp7SignedFilePathAudit, AuditModeCIP, true); + + + + // Create Enforced mode CIP + CiRuleOptions.Set(filePath: tempBasePolicyPath, rulesToRemove: [CiRuleOptions.PolicyRuleOptions.EnabledAuditMode, CiRuleOptions.PolicyRuleOptions.EnabledUnsignedSystemIntegrityPolicy]); + + string CIPp7SignedFilePathEnforced = Path.Combine(stagingArea.FullName, "BaseAuditTemp.cip.p7"); + + string tempEnforcedModeCIPPath = Path.Combine(stagingArea.FullName, "BaseAuditTemp.cip"); + + // Convert the XML file to CIP + PolicyToCIPConverter.Convert(tempBasePolicyPath, tempEnforcedModeCIPPath); + + // Sign the CIP + SignToolHelper.Sign(new FileInfo(tempEnforcedModeCIPPath), new FileInfo(_SignToolPath!), _CertCN!); + + // Rename the .p7 signed file to .cip + File.Move(CIPp7SignedFilePathEnforced, EnforcedModeCIP, true); + + } - // Create Enforced mode CIP - CiRuleOptions.Set(filePath: tempBasePolicyPath, rulesToRemove: [CiRuleOptions.PolicyRuleOptions.EnabledAuditMode]); - PolicyToCIPConverter.Convert(tempBasePolicyPath, EnforcedModeCIP); Logger.Write("Creating Enforced Mode SnapBack guarantee"); SnapBackGuarantee.Create(EnforcedModeCIP); @@ -579,6 +679,12 @@ private async void ResetStepsButton_Click(object sender, RoutedEventArgs e) selectedSupplementalPolicyName = null; selectedXMLFilePath = null; LogsScanStartTime = null; + tempBasePolicyPath = null; + _BasePolicyObject = null; + _CertCN = null; + _CertPath = null; + _SignToolPath = null; + _IsSignedPolicy = false; LogSizeNumberBox.Value = EventLogUtility.GetCurrentLogSize(); @@ -830,32 +936,58 @@ await Task.Run(() => FileBasedInfoPackage DataPackage = SignerAndHashBuilder.BuildSignerAndHashObjects(data: [.. fileIdentities.FileIdentitiesInternal], level: scanLevel); // Insert the data into the empty policy file - Master.Initiate(DataPackage, EmptyPolicyPath, SiPolicyIntel.Authorization.Allow); + Master.Initiate(DataPackage, EmptyPolicyPath, Authorization.Allow); string OutputPath = Path.Combine(GlobalVars.UserConfigDir, $"{selectedSupplementalPolicyName}.xml"); - // Instantiate the user selected Base policy - To get its BasePolicyID - CodeIntegrityPolicy codeIntegrityPolicy = new(selectedXMLFilePath, null); - // Set the BasePolicyID of our new policy to the one from user selected policy - string supplementalPolicyID = SetCiPolicyInfo.Set(EmptyPolicyPath, true, selectedSupplementalPolicyName, codeIntegrityPolicy.BasePolicyID, null); + string supplementalPolicyID = SetCiPolicyInfo.Set(EmptyPolicyPath, true, selectedSupplementalPolicyName, _BasePolicyObject!.BasePolicyID, null); // Configure policy rule options - CiRuleOptions.Set(filePath: EmptyPolicyPath, template: CiRuleOptions.PolicyTemplate.Supplemental); + if (!_IsSignedPolicy) + { + CiRuleOptions.Set(filePath: EmptyPolicyPath, template: CiRuleOptions.PolicyTemplate.Supplemental); + } + else + { + CiRuleOptions.Set(filePath: EmptyPolicyPath, template: CiRuleOptions.PolicyTemplate.Supplemental, rulesToRemove: [CiRuleOptions.PolicyRuleOptions.EnabledUnsignedSystemIntegrityPolicy]); + } // Set policy version SetCiPolicyInfo.Set(EmptyPolicyPath, new Version("1.0.0.0")); + if (_IsSignedPolicy) + { + // Add certificate's details to the supplemental policy + _ = AddSigningDetails.Add(EmptyPolicyPath, _CertPath!); + } + // Copying the policy file to the User Config directory - outside of the temporary staging area File.Copy(EmptyPolicyPath, OutputPath, true); - // If user selected to deploy the policy if (deployPolicy) { string CIPPath = Path.Combine(stagingArea.FullName, $"{supplementalPolicyID}.cip"); - PolicyToCIPConverter.Convert(OutputPath, CIPPath); + if (_IsSignedPolicy) + { + string CIPp7SignedFilePath = Path.Combine(stagingArea.FullName, $"{supplementalPolicyID}.cip.p7"); + + // Convert the XML file to CIP + PolicyToCIPConverter.Convert(OutputPath, CIPPath); + + // Sign the CIP + SignToolHelper.Sign(new FileInfo(CIPPath), new FileInfo(_SignToolPath!), _CertCN!); + + // Rename the .p7 signed file to .cip + File.Move(CIPp7SignedFilePath, CIPPath, true); + } + + else + { + PolicyToCIPConverter.Convert(OutputPath, CIPPath); + } CiToolHelper.UpdatePolicy(CIPPath); } @@ -912,5 +1044,6 @@ private void BrowseForXMLPolicyButton_Flyout_Clear_Click(object sender, RoutedEv { BrowseForXMLPolicyButton_SelectedBasePolicyTextBox.Text = null; selectedXMLFilePath = null; + tempBasePolicyPath = null; } }