Skip to content

Commit

Permalink
Implemented Apps and Windows Features Removal
Browse files Browse the repository at this point in the history
You can now remove a lot of built-in apps and also many optional Windows features in a new dedicated page in the Harden Windows Security Module.
  • Loading branch information
HotCakeX committed Jan 5, 2025
1 parent 3ac0f72 commit 3350479
Show file tree
Hide file tree
Showing 76 changed files with 1,413 additions and 1,068 deletions.
3 changes: 3 additions & 0 deletions Harden-Windows-Security Module/.editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -1039,3 +1039,6 @@ dotnet_diagnostic.CA1002.severity = error

# SYSLIB1054: Use 'LibraryImportAttribute' instead of 'DllImportAttribute' to generate P/Invoke marshalling code at compile time
dotnet_diagnostic.SYSLIB1054.severity = silent

# CA1060: Move P/Invokes to NativeMethods class
dotnet_diagnostic.CA1060.severity = error
10 changes: 10 additions & 0 deletions Harden-Windows-Security Module/Harden Windows Security.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@
</Content>
</ItemGroup>

<ItemGroup>
<Page Remove="Main files\Resources\XAML\OptionalFeatures.xaml" />
</ItemGroup>

<ItemGroup>
<None Include="..\LICENSE">
<Pack>True</Pack>
Expand Down Expand Up @@ -87,6 +91,12 @@
</Compile>
</ItemGroup>

<ItemGroup>
<Content Update="Main files\Resources\XAML\OptionalFeatures.xaml">
<Generator>MSBuild:Compile</Generator>
</Content>
</ItemGroup>

<ItemGroup>
<EmbeddedResource Update="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,7 @@ internal static Dictionary<string, List<Dictionary<string, object>>> Get()
private static async Task<Dictionary<string, List<Dictionary<string, object>>>> GetAsync()
{
// Set the location of the CSV file containing the MDM list
string path = GlobalVars.path ?? throw new InvalidOperationException("GlobalVars.path is null");
string csvFilePath = Path.Combine(path, "Resources", "MDMResultClasses.csv");
string csvFilePath = Path.Combine(GlobalVars.path, "Resources", "MDMResultClasses.csv");

// Create a dictionary where keys are the class names and values are lists of dictionaries
Dictionary<string, List<Dictionary<string, object>>> results = [];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ internal static void Invoke()
Logger.LogMessage("Collecting Intune applied policy details from the System", LogTypeIntel.Information);

// Path to the PowerShell script
string scriptPath = Path.Combine(GlobalVars.path!, "Shared", "SYSTEMInfoGathering.ps1");
string scriptPath = Path.Combine(GlobalVars.path, "Shared", "SYSTEMInfoGathering.ps1");

// Load the PowerShell script into a string
string script = File.ReadAllText(scriptPath);
Expand Down
63 changes: 9 additions & 54 deletions Harden-Windows-Security Module/Main files/C#/GUI/ASRRules/View.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,9 @@
using System.Globalization;
using System.IO;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Markup;
using System.Windows.Media.Imaging;

namespace HardenWindowsSecurity;

Expand All @@ -27,11 +26,6 @@ private void ASRRulesView(object obj)
return;
}

if (GlobalVars.path is null)
{
throw new InvalidOperationException("GlobalVars.path cannot be null.");
}

// if Admin privileges are not available, return and do not proceed any further
// Will prevent the page from being loaded since the CurrentView won't be set/changed
if (!UserPrivCheck.IsAdmin())
Expand All @@ -54,35 +48,8 @@ private void ASRRulesView(object obj)

#region finding elements

// Finding the Execute Button Grid
Grid? ExecuteButtonGrid = GUIASRRules.ParentGrid.FindName("ExecuteButtonGrid") as Grid ?? throw new InvalidOperationException("ExecuteButtonGrid is null in the ASRRules View");

// Finding the Execute Button
if (ExecuteButtonGrid.FindName("ExecuteButton") is not ToggleButton ExecuteButton)
{
throw new InvalidOperationException("Couldn't find the ExecuteButton in ASRRules view");
}

// Apply the template to make sure it's available
_ = ExecuteButton.ApplyTemplate();

// Access the image within the Execute Button's template
if (ExecuteButton.Template.FindName("RefreshIconImage", ExecuteButton) is not Image RefreshIconImage)
{
throw new InvalidOperationException("RefreshIconImage could not be found in the ASRRules view");
}

// Update the image source for the Refresh button
// Load the Refresh icon image into memory and set it as the source
BitmapImage RefreshIconBitmapImage = new();
RefreshIconBitmapImage.BeginInit();
RefreshIconBitmapImage.UriSource = new Uri(Path.Combine(GlobalVars.path!, "Resources", "Media", "ExecuteButton.png"));
RefreshIconBitmapImage.CacheOption = BitmapCacheOption.OnLoad; // Load the image data into memory
RefreshIconBitmapImage.EndInit();

RefreshIconImage.Source = RefreshIconBitmapImage;

Button RetrieveASRStatusButton = GUIASRRules.ParentGrid.FindName("RetrieveASRStatus") as Button ?? throw new InvalidOperationException("RetrieveASRStatus could not be found in the ASRRules view");
Button ApplyASRRulesButton = GUIASRRules.ParentGrid.FindName("ApplyASRRulesButton") as Button ?? throw new InvalidOperationException("ApplyASRRulesButton could not be found in the ASRRules view");

#endregion

Expand Down Expand Up @@ -121,11 +88,6 @@ void ProcessListViewItems(ListView listView)
string GetASRRuleConfig(string ASRRuleName, byte ComboBoxIndex)
{

if (GlobalVars.path is null)
{
throw new InvalidOperationException("GlobalVars.path is null.");
}

if (AttackSurfaceReductionIntel.ASRRulesCorrelation is null)
{
throw new InvalidOperationException("ASRRulesCorrelation is null");
Expand Down Expand Up @@ -169,12 +131,12 @@ string GetASRRuleConfig(string ASRRuleName, byte ComboBoxIndex)
}


// Register the ExecuteButton as an element that will be enabled/disabled based on current activity
ActivityTracker.RegisterUIElement(ExecuteButton);
// Register the ApplyASRRulesButton as an element that will be enabled/disabled based on current activity
ActivityTracker.RegisterUIElement(ApplyASRRulesButton);


// Set up the Click event handler for the ExecuteButton button
ExecuteButton.Click += async (sender, e) =>
// Set up the Click event handler for the ApplyASRRulesButton button
ApplyASRRulesButton.Click += async (sender, e) =>
{
// Only continue if there is no activity other places
if (!ActivityTracker.IsActive)
Expand All @@ -183,7 +145,7 @@ string GetASRRuleConfig(string ASRRuleName, byte ComboBoxIndex)
ActivityTracker.IsActive = true;

// Set text blocks to empty while new data is being generated
System.Windows.Application.Current.Dispatcher.Invoke(() =>
Application.Current.Dispatcher.Invoke(() =>
{
// Get the ListViews
if (GUIASRRules.ParentGrid.FindName("ASRRuleSet1") is not ListView ASRRuleSet1 || GUIASRRules.ParentGrid.FindName("ASRRuleSet2") is not ListView ASRRuleSet2)
Expand Down Expand Up @@ -259,12 +221,6 @@ await System.Threading.Tasks.Task.Run(() =>

});

// Update the UI Elements at the end of the run
await System.Windows.Application.Current.Dispatcher.InvokeAsync(() =>
{
ExecuteButton.IsChecked = false; // Uncheck the ExecuteButton button to start the reverse animation
});

// mark as activity completed
ActivityTracker.IsActive = false;

Expand All @@ -286,7 +242,7 @@ await System.Windows.Application.Current.Dispatcher.InvokeAsync(() =>
// Dictionary of ComboBoxes, key is ComboBox name and value is ComboBox element itself
Dictionary<string, ComboBox> ComboBoxList = [];

System.Windows.Application.Current.Dispatcher.Invoke(() =>
Application.Current.Dispatcher.Invoke(() =>
{
// Get the ListViews
if (GUIASRRules.ParentGrid.FindName("ASRRuleSet1") is not ListView ASRRuleSet1 ||
Expand Down Expand Up @@ -369,7 +325,7 @@ await System.Threading.Tasks.Task.Run(() =>
_ = ComboBoxList.TryGetValue(ComboBoxName!, out ComboBox? currentMatchingComboBox);

// Use the GUI dispatcher to set the ComboBox selected index to the currently applied ASR rule's action
System.Windows.Application.Current.Dispatcher.Invoke(() =>
Application.Current.Dispatcher.Invoke(() =>
{
// Make the connection between ASR rule applied action and the ComboBox Item Indexes
int selectedIndex = Convert.ToInt32(action, CultureInfo.InvariantCulture) switch
Expand All @@ -395,7 +351,6 @@ await System.Threading.Tasks.Task.Run(() =>
};



// Cache the view before setting it as the CurrentView
_viewCache["ASRRulesView"] = GUIASRRules.View;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,6 @@ private void BitLockerView(object obj)
return;
}

if (GlobalVars.path is null)
{
throw new InvalidOperationException("GlobalVars.path cannot be null.");
}

// if Admin privileges are not available, return and do not proceed any further
// Will prevent the page from being loaded since the CurrentView won't be set/changed
if (!UserPrivCheck.IsAdmin())
Expand Down Expand Up @@ -208,7 +203,7 @@ await Task.Run(() =>
// Add image to the BackupButtonIcon
BitmapImage BackupButtonIconBitmapImage = new();
BackupButtonIconBitmapImage.BeginInit();
BackupButtonIconBitmapImage.UriSource = new Uri(Path.Combine(GlobalVars.path!, "Resources", "Media", "ExportIconBlack.png"));
BackupButtonIconBitmapImage.UriSource = new Uri(Path.Combine(GlobalVars.path, "Resources", "Media", "ExportIconBlack.png"));
BackupButtonIconBitmapImage.CacheOption = BitmapCacheOption.OnLoad; // Load the image data into memory
BackupButtonIconBitmapImage.EndInit();
BackupButtonIcon.Source = BackupButtonIconBitmapImage;
Expand Down Expand Up @@ -265,7 +260,7 @@ await Task.Run(() =>
// Add the same Refresh image to multiple sources
BitmapImage RefreshButtonIcon1BitmapImage = new();
RefreshButtonIcon1BitmapImage.BeginInit();
RefreshButtonIcon1BitmapImage.UriSource = new Uri(Path.Combine(GlobalVars.path!, "Resources", "Media", "RefreshButtonIcon.png"));
RefreshButtonIcon1BitmapImage.UriSource = new Uri(Path.Combine(GlobalVars.path, "Resources", "Media", "RefreshButtonIcon.png"));
RefreshButtonIcon1BitmapImage.CacheOption = BitmapCacheOption.OnLoad; // Load the image data into memory
RefreshButtonIcon1BitmapImage.EndInit();
RefreshButtonIcon1.Source = RefreshButtonIcon1BitmapImage;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ protected void OnPropertyChanged(string propertyName)
private static BitmapImage LoadImage(string fileName)
{
// Construct the full path to the image file
string imagePath = Path.Combine(GlobalVars.path!, "Resources", "Media", fileName);
string imagePath = Path.Combine(GlobalVars.path, "Resources", "Media", fileName);
// Return the loaded image as a BitmapImage
return new BitmapImage(new Uri(imagePath, UriKind.Absolute));
}
Expand Down
44 changes: 25 additions & 19 deletions Harden-Windows-Security Module/Main files/C#/GUI/Confirm/View.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Markup;
using System.Windows.Media;
using System.Windows.Media.Imaging;

#nullable disable
Expand All @@ -25,7 +31,7 @@ public partial class NavigationVM : ViewModelBase
private ICollectionView _SecOpsCollectionView;

// Collection of SecOp objects
private System.Collections.ObjectModel.ObservableCollection<SecOp> __SecOpses;
private ObservableCollection<SecOp> __SecOpses;

// Method to handle the "Confirm" view, including loading and modifying it
private void ConfirmView(object obj)
Expand Down Expand Up @@ -61,7 +67,7 @@ private void ConfirmView(object obj)
string xamlContent = File.ReadAllText(xamlPath);

// Parse the XAML content to create a UserControl object
GUIConfirmSystemCompliance.View = (UserControl)System.Windows.Markup.XamlReader.Parse(xamlContent);
GUIConfirmSystemCompliance.View = (UserControl)XamlReader.Parse(xamlContent);

// Set the DataContext for the Confirm view
GUIConfirmSystemCompliance.View.DataContext = new ConfirmVM();
Expand Down Expand Up @@ -131,7 +137,7 @@ void ApplyFilters(string filterText, bool includeCompliant, bool includeNonCompl
__SecOpses = [];

// Create a collection view based on the security options collection
_SecOpsCollectionView = System.Windows.Data.CollectionViewSource.GetDefaultView(__SecOpses);
_SecOpsCollectionView = CollectionViewSource.GetDefaultView(__SecOpses);

// Set the ItemSource of the DataGrid in the Confirm view to the collection view
if (GUIConfirmSystemCompliance.SecOpsDataGrid is not null)
Expand Down Expand Up @@ -173,7 +179,7 @@ void ApplyFilters(string filterText, bool includeCompliant, bool includeNonCompl
// Load the Refresh icon image into memory and set it as the source
BitmapImage RefreshIconBitmapImage = new();
RefreshIconBitmapImage.BeginInit();
RefreshIconBitmapImage.UriSource = new Uri(Path.Combine(GlobalVars.path!, "Resources", "Media", "ExecuteButton.png"));
RefreshIconBitmapImage.UriSource = new Uri(Path.Combine(GlobalVars.path, "Resources", "Media", "ExecuteButton.png"));
RefreshIconBitmapImage.CacheOption = BitmapCacheOption.OnLoad; // Load the image data into memory
RefreshIconBitmapImage.EndInit();

Expand Down Expand Up @@ -221,7 +227,7 @@ void ApplyFilters(string filterText, bool includeCompliant, bool includeNonCompl

// Disable the Refresh button while processing
// Set text blocks to empty while new data is being generated
System.Windows.Application.Current.Dispatcher.Invoke(() =>
Application.Current.Dispatcher.Invoke(() =>
{
// Finding the elements
TextBlock CompliantItemsTextBlock = (TextBlock)GUIConfirmSystemCompliance.View.FindName("CompliantItemsTextBlock");
Expand All @@ -243,7 +249,7 @@ void ApplyFilters(string filterText, bool includeCompliant, bool includeNonCompl
});

// Run the method asynchronously in a different thread
await System.Threading.Tasks.Task.Run(() =>
await Task.Run(() =>
{
// Get fresh data for compliance checking
Initializer.Initialize(null, true);
Expand Down Expand Up @@ -280,7 +286,7 @@ await System.Threading.Tasks.Task.Run(() =>
});

// After InvokeConfirmation is completed, update the security options collection
await System.Windows.Application.Current.Dispatcher.InvokeAsync(() =>
await Application.Current.Dispatcher.InvokeAsync(() =>
{
LoadMembers(); // Load updated security options
RefreshButton.IsChecked = false; // Uncheck the Refresh button
Expand All @@ -307,33 +313,33 @@ await System.Windows.Application.Current.Dispatcher.InvokeAsync(() =>
/// </summary>
/// <param name="category">Name of the category</param>
/// <returns>The color of the category to be used for display purposes on the DataGrid GUI</returns>
private static System.Windows.Media.Brush GetCategoryColor(string category)
private static Brush GetCategoryColor(string category)
{
// Determine the background color for each category
return category switch
{
// Light Pastel Sky Blue
"MicrosoftDefender" => new System.Windows.Media.BrushConverter().ConvertFromString("#B3E5FC") as System.Windows.Media.Brush,
"MicrosoftDefender" => new BrushConverter().ConvertFromString("#B3E5FC") as Brush,
// Light Pastel Coral
"AttackSurfaceReductionRules" => new System.Windows.Media.BrushConverter().ConvertFromString("#FFDAB9") as System.Windows.Media.Brush,
"AttackSurfaceReductionRules" => new BrushConverter().ConvertFromString("#FFDAB9") as Brush,
// Light Pastel Green
"BitLockerSettings" => new System.Windows.Media.BrushConverter().ConvertFromString("#C3FDB8") as System.Windows.Media.Brush,
"BitLockerSettings" => new BrushConverter().ConvertFromString("#C3FDB8") as Brush,
// Light Pastel Lemon
"TLSSecurity" => new System.Windows.Media.BrushConverter().ConvertFromString("#FFFACD") as System.Windows.Media.Brush,
"TLSSecurity" => new BrushConverter().ConvertFromString("#FFFACD") as Brush,
// Light Pastel Lavender
"LockScreen" => new System.Windows.Media.BrushConverter().ConvertFromString("#E6E6FA") as System.Windows.Media.Brush,
"LockScreen" => new BrushConverter().ConvertFromString("#E6E6FA") as Brush,
// Light Pastel Aqua
"UserAccountControl" => new System.Windows.Media.BrushConverter().ConvertFromString("#C1F0F6") as System.Windows.Media.Brush,
"UserAccountControl" => new BrushConverter().ConvertFromString("#C1F0F6") as Brush,
// Light Pastel Teal
"DeviceGuard" => new System.Windows.Media.BrushConverter().ConvertFromString("#B2DFDB") as System.Windows.Media.Brush,
"DeviceGuard" => new BrushConverter().ConvertFromString("#B2DFDB") as Brush,
// Light Pastel Pink
"WindowsFirewall" => new System.Windows.Media.BrushConverter().ConvertFromString("#F8BBD0") as System.Windows.Media.Brush,
"WindowsFirewall" => new BrushConverter().ConvertFromString("#F8BBD0") as Brush,
// Light Pastel Peach
"OptionalWindowsFeatures" => new System.Windows.Media.BrushConverter().ConvertFromString("#FFE4E1") as System.Windows.Media.Brush,
"OptionalWindowsFeatures" => new BrushConverter().ConvertFromString("#FFE4E1") as Brush,
// Light Pastel Mint
"WindowsNetworking" => new System.Windows.Media.BrushConverter().ConvertFromString("#F5FFFA") as System.Windows.Media.Brush,
"WindowsNetworking" => new BrushConverter().ConvertFromString("#F5FFFA") as Brush,
// Light Pastel Gray
_ => new System.Windows.Media.BrushConverter().ConvertFromString("#EDEDED") as System.Windows.Media.Brush,
_ => new BrushConverter().ConvertFromString("#EDEDED") as Brush,
};
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,6 @@ private void ExclusionsView(object obj)
return;
}

if (GlobalVars.path is null)
{
throw new InvalidOperationException("GlobalVars.path cannot be null.");
}

// if Admin privileges are not available, return and do not proceed any further
// Will prevent the page from being loaded since the CurrentView won't be set/changed
if (!UserPrivCheck.IsAdmin())
Expand Down
9 changes: 2 additions & 7 deletions Harden-Windows-Security Module/Main files/C#/GUI/Log/View.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,6 @@ private void LogsView(object obj)
return;
}

if (GlobalVars.path is null)
{
throw new InvalidOperationException("GlobalVars.path cannot be null.");
}

// Construct the file path for the Logs view XAML
string xamlPath = Path.Combine(GlobalVars.path, "Resources", "XAML", "Logs.xaml");

Expand All @@ -56,7 +51,7 @@ private void LogsView(object obj)
// Add image to the ExportLogsIcon
BitmapImage ExportLogsIconBitmapImage = new();
ExportLogsIconBitmapImage.BeginInit();
ExportLogsIconBitmapImage.UriSource = new Uri(Path.Combine(GlobalVars.path!, "Resources", "Media", "ExportIconBlack.png"));
ExportLogsIconBitmapImage.UriSource = new Uri(Path.Combine(GlobalVars.path, "Resources", "Media", "ExportIconBlack.png"));
ExportLogsIconBitmapImage.CacheOption = BitmapCacheOption.OnLoad; // Load the image data into memory
ExportLogsIconBitmapImage.EndInit();
ExportLogsIcon.Source = ExportLogsIconBitmapImage;
Expand All @@ -65,7 +60,7 @@ private void LogsView(object obj)
// Add image to the ClearLogsIcon
BitmapImage ClearLogsIconBitmapImage = new();
ClearLogsIconBitmapImage.BeginInit();
ClearLogsIconBitmapImage.UriSource = new Uri(Path.Combine(GlobalVars.path!, "Resources", "Media", "ClearLogsIcon.png"));
ClearLogsIconBitmapImage.UriSource = new Uri(Path.Combine(GlobalVars.path, "Resources", "Media", "ClearLogsIcon.png"));
ClearLogsIconBitmapImage.CacheOption = BitmapCacheOption.OnLoad; // Load the image data into memory
ClearLogsIconBitmapImage.EndInit();
ClearLogsIcon.Source = ClearLogsIconBitmapImage;
Expand Down
Loading

0 comments on commit 3350479

Please sign in to comment.