Skip to content

Commit

Permalink
Harden Windows Security v.0.7.3 (#515)
Browse files Browse the repository at this point in the history
Added a new section to the Apps | Features page where you can remove the pre-installed built-in network drivers that you do not use. Windows by default has WIFI and Ethernet network adapter drivers of Intel, Broadcom, Ralink, Realtek, Qualcomm and Marvel. If you do not have any of those hardware or you install your own drivers then you can remove the unnecessary ones, freeing up disk space.

You can view the full list of pre-installed network drivers via this PowerShell command: Get-WindowsCapability -Online

As always, detailed logs of each step of the operation will be generated and made available.

Improved the dialog window design. It has a gradient dark background and will stay at top so user won't miss important message that is displayed.

Added a check to display a message to the user when installing AppControl Manager and an incompatible policy is detected.

Improved the module's compatibility with other modules that load the same Microsoft DLLs in the session through PowerShell profile. When Harden Windows Security detects such situations, it will automatically use the -NoProfile switch.

Updated the Microsoft DLLs to the latest versions from NuGet.

Improved the logging mechanism when using the Harden Windows Security in unattended/headless mode
  • Loading branch information
HotCakeX authored Jan 8, 2025
1 parent bad0e85 commit 8ad3e5c
Show file tree
Hide file tree
Showing 26 changed files with 255 additions and 83 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ internal static void Disable(string DriveLetter)

if (DecryptMethodInvocationResultCode is 0)
{
Logger.LogMessage($"Successfully Decrypted the drive {DriveLetter}", LogTypeIntel.InformationInteractionRequired);
Logger.LogMessage($"Successfully started decrypting the drive {DriveLetter}", LogTypeIntel.InformationInteractionRequired);
}
else
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,4 @@ public static class GUIAppControlManager
);

internal static readonly Uri AppUpdateDownloadLinkURL = new("https://raw.githubusercontent.com/HotCakeX/Harden-Windows-Security/refs/heads/main/AppControl%20Manager/DownloadURL.txt");

}
Original file line number Diff line number Diff line change
Expand Up @@ -353,22 +353,21 @@ await Task.Run(() =>

Logger.LogMessage($"AppControl Manager installation has been successful.", LogTypeIntel.InformationInteractionRequired);


#region Check for incompatible policy
try
{
string registryPath = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System";
string registryName = "ValidateAdminCodeSignatures";

using (RegistryKey? key = Registry.LocalMachine.OpenSubKey(registryPath))
using (RegistryKey? key = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System"))
{
if (key is not null)
{
// Get the registry value
object? registryValue = key.GetValue(registryName);
object? registryValue = key.GetValue("ValidateAdminCodeSignatures");

if (registryValue is not null && string.Equals(registryValue.ToString(), "1", StringComparison.OrdinalIgnoreCase))
{

Logger.LogMessage("Warning: A policy named 'Only elevate executables that are signed and validated' " +
Logger.LogMessage("A policy named 'Only elevate executables that are signed and validated' " +
"is conflicting with the AppControl Manager app and won't let it start because it's self-signed " +
"with your on-device keys. Please disable the policy. It can be found in Group Policy Editor -> " +
"Computer Configuration -> Windows Settings -> Security Settings -> Local Policies -> Security Options -> " +
Expand All @@ -382,6 +381,8 @@ await Task.Run(() =>
{
Logger.LogMessage("Could not verify that 'Only Elevate signed' policy is not active.", LogTypeIntel.Warning);
}
#endregion


});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -388,7 +388,7 @@ private void UpdateTotalCount(bool ShowNotification)
NonCompliantItemsTextBlock.Text = $"{NonCompliantItemsCount} Non-Compliant Items";
}

// Display a notification if it's allowed to do so, and ShowNotification is set to true
// Display a notification if ShowNotification is set to true
if (ShowNotification)
{
ToastNotification.Show(ToastNotification.Type.EndOfConfirmation, CompliantItemsCount, NonCompliantItemsCount, null, null);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@ private void OptionalFeaturesView(object obj)
Button RetrieveRemovableApps = (Button)(GUIOptionalFeatures.ParentGrid).FindName("RetrieveRemovableApps");
Button RemoveApps = (Button)(GUIOptionalFeatures.ParentGrid).FindName("RemoveApps");

ComboBox NetworkAdaptersCompanyListComboBox = (ComboBox)(GUIOptionalFeatures.ParentGrid).FindName("NetworkAdaptersCompanyListComboBox");
Button RemoveNetworkAdapters = (Button)(GUIOptionalFeatures.ParentGrid).FindName("RemoveNetworkAdapters");

// A dictionary to store all checkboxes
Dictionary<string, CheckBox> featureCheckboxes = [];

Expand Down Expand Up @@ -103,6 +106,7 @@ private void OptionalFeaturesView(object obj)
ActivityTracker.RegisterUIElement(RetrieveOptionalFeaturesStatus);
ActivityTracker.RegisterUIElement(RemoveApps);
ActivityTracker.RegisterUIElement(RetrieveRemovableApps);
ActivityTracker.RegisterUIElement(RemoveNetworkAdapters);


// Event handler for the apply button
Expand Down Expand Up @@ -795,6 +799,75 @@ await Task.Run(() =>
// Retrieve the removable apps on the system once the view is loaded
_ = _RetrieveRemovableApps();




// Event handler for the network adapters remove button
RemoveNetworkAdapters.Click += async (sender, e) =>
{

// Only continue if there is no activity other places
if (ActivityTracker.IsActive)
{
return;
}

// mark as activity started
ActivityTracker.IsActive = true;

try
{
// When "*" is used in the middle of the name, it means both WIFI and Ethernet drivers will be targeted for removal
switch (NetworkAdaptersCompanyListComboBox.SelectedIndex)
{
case 0: // Intel
{
await Task.Run(() => WindowsFeatureChecker.BulkCapabilityRemoval("Microsoft.Windows.*.Client.Intel*"));
break;
}
case 1: // Broadcom
{
await Task.Run(() => WindowsFeatureChecker.BulkCapabilityRemoval("Microsoft.Windows.Wifi.Client.Broadcom*"));
break;
}
case 2: // Marvel
{
await Task.Run(() => WindowsFeatureChecker.BulkCapabilityRemoval("Microsoft.Windows.Wifi.Client.Marvel*"));
break;
}
case 3: // Qualcomm
{
await Task.Run(() => WindowsFeatureChecker.BulkCapabilityRemoval("Microsoft.Windows.Wifi.Client.Qualcomm*"));
break;
}
case 4: // Ralink
{
await Task.Run(() => WindowsFeatureChecker.BulkCapabilityRemoval("Microsoft.Windows.Wifi.Client.Ralink*"));
break;
}
case 5: // Realtek
{
await Task.Run(() => WindowsFeatureChecker.BulkCapabilityRemoval("Microsoft.Windows.*.Client.Realtek*"));
break;
}
default:
{
break;
}
}


}
finally
{
// mark as activity completed
ActivityTracker.IsActive = false;
}

};



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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Markup;
Expand Down Expand Up @@ -89,7 +90,7 @@ private void UnprotectView(object obj)
// Event handler for when the refresh button is pressed
RefreshDrivesButton.Click += async (sender, e) =>
{
await System.Threading.Tasks.Task.Run(() =>
await Task.Run(() =>
{
// Get the drives list
List<BitLocker.BitLockerVolume> allDrivesList = BitLocker.GetAllEncryptedVolumeInfo(false, false);
Expand Down Expand Up @@ -127,7 +128,7 @@ await System.Threading.Tasks.Task.Run(() =>


// Perform the main tasks on another thread to avoid freezing the GUI
await System.Threading.Tasks.Task.Run(() =>
await Task.Run(() =>
{
if (SelectedDriveFromComboBox is null)
{
Expand Down Expand Up @@ -190,7 +191,7 @@ await System.Threading.Tasks.Task.Run(() =>
});

// Run the Unprotect commands asynchronously in a different thread
await System.Threading.Tasks.Task.Run(() =>
await Task.Run(() =>
{
// if LGPO doesn't already exist in the working directory, then download it
if (!Path.Exists(GlobalVars.LGPOExe))
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using System.Threading;
using System.Windows;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;

namespace HardenWindowsSecurity;

Expand All @@ -14,20 +14,34 @@ internal static class DialogMsgHelper
/// <param name="Title"></param>
internal static void Show(string Message, string? Title = "An Error Occurred")
{
Thread thread = new(() =>
// Needs to be on the UI thread
Application.Current.Dispatcher.Invoke(() =>
{

// Create a custom error window
Window errorWindow = new()
// Create a custom dialog window
Window dialogWindow = new()
{
Title = Title,
Width = 450,
Height = 350,
WindowStartupLocation = WindowStartupLocation.CenterScreen,
ResizeMode = ResizeMode.NoResize
ResizeMode = ResizeMode.NoResize,
Owner = Application.Current.MainWindow, // Associate the dialog with the main Window

// Enable this when the time is right
// ThemeMode = ThemeMode.System

WindowStyle = WindowStyle.None, // Hides the title bar

Background = new LinearGradientBrush(
Color.FromRgb(15, 32, 39),
Color.FromRgb(32, 58, 67),
45),

BorderThickness = new Thickness(1),
BorderBrush = new LinearGradientBrush(
Color.FromRgb(255, 105, 180),
Color.FromRgb(255, 20, 147),
90)
};

StackPanel stackPanel = new() { Margin = new Thickness(20) };
Expand All @@ -37,7 +51,10 @@ internal static void Show(string Message, string? Title = "An Error Occurred")
Text = Message,
Margin = new Thickness(0, 0, 0, 20),
TextWrapping = TextWrapping.Wrap,
Foreground = Brushes.White,
FontSize = 14,
HorizontalAlignment = HorizontalAlignment.Center,
TextAlignment = TextAlignment.Center,
FontWeight = FontWeights.SemiBold
};

Expand All @@ -52,7 +69,7 @@ internal static void Show(string Message, string? Title = "An Error Occurred")

okButton.Click += (sender, args) =>
{
errorWindow.Close();
dialogWindow.Close();
};

StackPanel buttonPanel = new() { Orientation = Orientation.Horizontal, HorizontalAlignment = HorizontalAlignment.Center };
Expand All @@ -61,13 +78,8 @@ internal static void Show(string Message, string? Title = "An Error Occurred")
_ = stackPanel.Children.Add(errorMessage);
_ = stackPanel.Children.Add(buttonPanel);

errorWindow.Content = stackPanel;
_ = errorWindow.ShowDialog();

dialogWindow.Content = stackPanel;
_ = dialogWindow.ShowDialog();
});

// Required since we're displaying GUI elements
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,11 @@ public static class GlobalVars
// stored at the beginning of each cmdlet in the begin block through the Initialize() method
public static string? VerbosePreference;

// To track the load of the DLLs in the module that occurs at the beginning of each cmdlet
public static bool RequiredDLLsLoaded;

public const string ReRunText = "Re-running the module because of a possible dependency conflict with other modules such as CommandNotFound in PowerToys";

// Create an empty ConcurrentDictionary to store the final results of the cmdlets
public static readonly ConcurrentDictionary<ComplianceCategories, List<IndividualResult>> FinalMegaObject = [];

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ public static void Initialize(string VerbosePreference = "SilentlyContinue", boo

GlobalVars.LogHeaderHasBeenWritten = false;

// Clear the log path in the Logger class, it should be set by each cmdlet that uses the -Log parameter every time
Logger.LogFilePathCLI = null;

// This check is only necessary to be performed once.
// GlobalVars.path is set to non-nullable intentionally with pragma disable
if (string.IsNullOrWhiteSpace(GlobalVars.path))
Expand Down
Loading

0 comments on commit 8ad3e5c

Please sign in to comment.