Skip to content

Commit

Permalink
Harden Windows Security v0.6.9 (#391)
Browse files Browse the repository at this point in the history
New optional sub-category for the Device Guard category: Mandatory mode for VBS (Virtualization based security) and Memory Integrity.

New Optional sub-category for the Miscellaneous category: Enable support for long paths for programs in Windows.

New Optional sub-category for the Miscellaneous category: Force strong key protection for user keys stored on the computer

Updated wiki posts to reflect the recent changes in WDACConfig and Harden Windows Security module.

During unprotection process, the logon/logoff audits that turn on in the Miscellaneous category are now reverted.

Added process mitigations for the AppControl manager. They protect it against external threats.
  • Loading branch information
HotCakeX authored Nov 4, 2024
1 parent e208fea commit 3216011
Show file tree
Hide file tree
Showing 70 changed files with 415 additions and 208 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ AppControl Manager/.vs/
AppControl Manager/bin/
AppControl Manager/obj/
AppControl Manager/Generated Files/
AppControl Manager/AppControl Manager.csproj.user
AppControl Manager/AppControl Manager.csproj.user
Harden-Windows-Security Module/Harden Windows Security.csproj.user
44 changes: 25 additions & 19 deletions Harden-Windows-Security Module/Harden Windows Security.csproj
Original file line number Diff line number Diff line change
@@ -1,23 +1,21 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net9.0-windows10.0.26100.0</TargetFramework>
<RootNamespace>HardenWindowsSecurity</RootNamespace>

<!--
Setting it to disable so that code clean up will properly remove unused usings.
With this enabled, VS would take into account the global usings and would remove required usings from .cs files during Code Cleanup task,
which would lead to errors in VS Code when running the code via Add-Type in PowerShell.
-->
<ImplicitUsings>disable</ImplicitUsings>

<ImplicitUsings>disable</ImplicitUsings>
<!-- Reference to the manifest file -->
<ApplicationManifest>app.manifest</ApplicationManifest>

<!-- This would activate all analyzers -->
<!-- <AnalysisMode>All</AnalysisMode> -->

<OutputType>Exe</OutputType>
<TargetFramework>net9.0-windows10.0.26100.0</TargetFramework>
<RootNamespace>HardenWindowsSecurity</RootNamespace>
<Nullable>enable</Nullable>
<UseWpf>true</UseWpf>
<UseWindowsForms>false</UseWindowsForms>
Expand All @@ -26,28 +24,29 @@
<StartupObject>HardenWindowsSecurity.Program</StartupObject>
<PackageProjectUrl>https://github.com/HotCakeX/Harden-Windows-Security</PackageProjectUrl>
<RepositoryUrl>https://github.com/HotCakeX/Harden-Windows-Security</RepositoryUrl>
<PackageTags>Windows;Cyber;CyberSecurity</PackageTags>
<PackageTags>Windows;Cyber;CyberSecurity,Harden</PackageTags>
<Title>Harden Windows Security</Title>
<Authors>Violet Hansen</Authors>
<Company>SpyNetGirl</Company>
<PackageReleaseNotes>https://github.com/HotCakeX/Harden-Windows-Security/releases</PackageReleaseNotes>
<PackageId>HardenWindowsSecurity</PackageId>
<Description>Harden Windows Safely, Securely using Official Supported Microsoft methods and proper explanation</Description>
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<CheckForOverflowUnderflow>True</CheckForOverflowUnderflow>
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<CheckForOverflowUnderflow>True</CheckForOverflowUnderflow>
</PropertyGroup>
<FileVersion>1.0.0.0</FileVersion>
<AssemblyVersion>$(FileVersion)</AssemblyVersion>
<NeutralLanguage>en-US</NeutralLanguage>
<AllowUnsafeBlocks>False</AllowUnsafeBlocks>
<Version>$(FileVersion)</Version>
<RuntimeIdentifiers>win-x64</RuntimeIdentifiers>

<PropertyGroup>
<RuntimeIdentifiers>win-x64;win-arm64</RuntimeIdentifiers>
<!-- When compiling into executable can be set to true, otherwise unnecessarily increases debug/build process -->
<SelfContained>false</SelfContained>
<NeutralLanguage>en-US</NeutralLanguage>

<EnforceCodeStyleInBuild>True</EnforceCodeStyleInBuild>
<CheckForOverflowUnderflow>True</CheckForOverflowUnderflow>
<PackageLicenseFile>LICENSE</PackageLicenseFile>
<IncludeSymbols>False</IncludeSymbols>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
<DebugType>full</DebugType>
</PropertyGroup>

<ItemGroup>
Expand All @@ -59,6 +58,13 @@
</Content>
</ItemGroup>

<ItemGroup>
<None Include="..\LICENSE">
<Pack>True</Pack>
<PackagePath>\</PackagePath>
</None>
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.PowerShell.SDK" Version="7.4.6" />
<PackageReference Include="Microsoft.Toolkit.Uwp.Notifications" Version="7.1.3" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@
"notcontains",
"ntdll",
"NTFS",
"NTLM",
"OFAC",
"ONENOTE",
"operatingsystem",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -599,6 +599,10 @@ await Task.Run(() =>
case "DeviceGuard":
{
DeviceGuard.Invoke();
if (GUIProtectWinSecurity.SelectedSubCategories.Contains("DeviceGuard_MandatoryVBS"))
{
DeviceGuard.DeviceGuard_MandatoryVBS();
}
break;
}
case "TLSSecurity":
Expand Down Expand Up @@ -665,6 +669,16 @@ await Task.Run(() =>
MiscellaneousConfigurations.MiscellaneousConfigurations_WindowsProtectedPrint();
}
if (GUIProtectWinSecurity.SelectedSubCategories.Contains("MiscellaneousConfigurations_LongPathSupport"))
{
MiscellaneousConfigurations.MiscellaneousConfigurations_LongPathSupport();
}
if (GUIProtectWinSecurity.SelectedSubCategories.Contains("MiscellaneousConfigurations_StrongKeyProtection"))
{
MiscellaneousConfigurations.MiscellaneousConfigurations_StrongKeyProtection();
}
break;
}
case "WindowsUpdateConfigurations":
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ public static partial class GUIProtectWinSecurity
{ "LockScreen", new string[] { "LockScreen_CtrlAltDel", "LockScreen_NoLastSignedIn" } },
{ "UserAccountControl", new string[] { "UAC_NoFastSwitching", "UAC_OnlyElevateSigned" } },
{ "WindowsNetworking", new string[] { "WindowsNetworking_BlockNTLM" } },
{ "MiscellaneousConfigurations", new string[] { "Miscellaneous_WindowsProtectedPrint" } },
{ "MiscellaneousConfigurations", new string[] { "Miscellaneous_WindowsProtectedPrint", "MiscellaneousConfigurations_LongPathSupport", "MiscellaneousConfigurations_StrongKeyProtection" } },
{ "DeviceGuard", new string[] { "DeviceGuard_MandatoryVBS" } },
{ "CountryIPBlocking", new string[] { "CountryIPBlocking_OFAC" } },
{ "DownloadsDefenseMeasures", new string[] { "DangerousScriptHostsBlocking" } }
};
Expand Down Expand Up @@ -98,14 +99,14 @@ public static partial class GUIProtectWinSecurity
"preset: recommended", new Dictionary<string, List<string>>
{
{ "Categories", new List<string> { "MicrosoftSecurityBaselines", "Microsoft365AppsSecurityBaselines", "MicrosoftDefender", "AttackSurfaceReductionRules", "BitLockerSettings", "DeviceGuard", "TLSSecurity", "LockScreen", "UserAccountControl", "WindowsFirewall", "OptionalWindowsFeatures", "WindowsNetworking", "MiscellaneousConfigurations", "WindowsUpdateConfigurations", "EdgeBrowserConfigurations", "DownloadsDefenseMeasures", "NonAdminCommands" } },
{ "SubCategories", new List<string> { "WindowsNetworking_BlockNTLM", "DangerousScriptHostsBlocking" } }
{ "SubCategories", new List<string> { "WindowsNetworking_BlockNTLM", "DangerousScriptHostsBlocking","MiscellaneousConfigurations_LongPathSupport" } }
}
},
{
"preset: complete", new Dictionary<string, List<string>>
{
{ "Categories", new List<string> { "MicrosoftSecurityBaselines", "Microsoft365AppsSecurityBaselines", "MicrosoftDefender", "AttackSurfaceReductionRules", "BitLockerSettings", "DeviceGuard", "TLSSecurity", "LockScreen", "UserAccountControl", "WindowsFirewall", "OptionalWindowsFeatures", "WindowsNetworking", "MiscellaneousConfigurations", "WindowsUpdateConfigurations", "EdgeBrowserConfigurations", "CountryIPBlocking", "DownloadsDefenseMeasures", "NonAdminCommands" } },
{ "SubCategories", new List<string> { "MSFTDefender_SAC", "UAC_OnlyElevateSigned", "WindowsNetworking_BlockNTLM", "Miscellaneous_WindowsProtectedPrint", "CountryIPBlocking_OFAC", "DangerousScriptHostsBlocking" } }
{ "SubCategories", new List<string> { "MSFTDefender_SAC", "UAC_OnlyElevateSigned", "WindowsNetworking_BlockNTLM", "Miscellaneous_WindowsProtectedPrint", "CountryIPBlocking_OFAC", "DangerousScriptHostsBlocking","MiscellaneousConfigurations_StrongKeyProtection", "MiscellaneousConfigurations_LongPathSupport" } }
}
}
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@ public string[] GetValidValues()
"TLSSecurity", // 21
"LockScreen", // 14
"UserAccountControl", // 6
"DeviceGuard", // 9
"DeviceGuard", // 10
"WindowsFirewall", // 20
"OptionalWindowsFeatures", // 14
"WindowsNetworking", // 17
"MiscellaneousConfigurations", // 18
"MiscellaneousConfigurations", // 20
"WindowsUpdateConfigurations", // 15
"EdgeBrowserConfigurations", // 14
"NonAdminCommands" // 9
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -480,6 +480,12 @@ private static Task VerifyDeviceGuard()
ConditionalResultAdd.Add(nestedObjectArray, Result);
}
// Process items in Registry resources.csv file with "Registry Keys" origin and add them to the nestedObjectArray array
foreach (IndividualResult Result in (CategoryProcessing.ProcessCategory(CatName, "Registry Keys")))
{
ConditionalResultAdd.Add(nestedObjectArray, Result);
}
if (GlobalVars.FinalMegaObject is null)
{
throw new ArgumentNullException(nameof(GlobalVars.FinalMegaObject), "FinalMegaObject cannot be null.");
Expand Down Expand Up @@ -843,7 +849,7 @@ private static Task VerifyMiscellaneousConfigurations()
Compliant = individualItemResult,
Value = individualItemResult ? "Success and Failure" : inclusionSetting ?? string.Empty, // just to suppress the warning
Name = "Audit policy for Other Logon/Logoff Events",
Category = CatName ?? string.Empty, // just to suppress the warning
Category = CatName,
Method = "Cmdlet"
});
}
Expand All @@ -868,19 +874,25 @@ private static Task VerifyMiscellaneousConfigurations()
Compliant = MDM_Policy_Result01_System02_AllowLocation.IsMatch,
Value = MDM_Policy_Result01_System02_AllowLocation.Value,
Name = "Disable Location",
Category = CatName ?? string.Empty, // just to suppress the warning
Category = CatName,
Method = "CIM"
});
// Process items in Registry resources.csv file with "Group Policy" origin and add them to the $NestedObjectArray array
foreach (IndividualResult Result in (CategoryProcessing.ProcessCategory(CatName ?? string.Empty, "Group Policy")))
foreach (IndividualResult Result in (CategoryProcessing.ProcessCategory(CatName, "Group Policy")))
{
ConditionalResultAdd.Add(nestedObjectArray, Result);
}
// Process items in Registry resources.csv file with "Registry Keys" origin and add them to the nestedObjectArray array
foreach (IndividualResult Result in (CategoryProcessing.ProcessCategory(CatName ?? string.Empty, "Registry Keys")))
foreach (IndividualResult Result in (CategoryProcessing.ProcessCategory(CatName, "Registry Keys")))
{
ConditionalResultAdd.Add(nestedObjectArray, Result);
}
// Process the Security Policies for the current category that reside in the "SecurityPoliciesVerification.csv" file
foreach (IndividualResult Result in (SecurityPolicyChecker.CheckPolicyCompliance(CatName)))
{
ConditionalResultAdd.Add(nestedObjectArray, Result);
}
Expand All @@ -907,7 +919,7 @@ private static Task VerifyMiscellaneousConfigurations()
Compliant = testSecureMacsResult,
Value = testSecureMacsResult ? "True" : "False",
Name = "SSH Secure MACs",
Category = CatName ?? string.Empty, // just to suppress the warning
Category = CatName,
Method = "CIM"
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using Microsoft.Win32;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Globalization;
using System.IO;

Expand Down Expand Up @@ -95,13 +97,13 @@ public static void Initialize(string VerbosePreference = "SilentlyContinue", boo
GlobalVars.MDAVConfigCurrent = ConfigDefenderHelper.GetMpComputerStatus();

// Total number of Compliant values
GlobalVars.TotalNumberOfTrueCompliantValues = 253;
GlobalVars.TotalNumberOfTrueCompliantValues = 256;

// Getting the $VerbosePreference from the calling cmdlet and saving it in the global variable
GlobalVars.VerbosePreference = VerbosePreference;

// Create an empty ConcurrentDictionary to store the final results of the cmdlets
GlobalVars.FinalMegaObject = new System.Collections.Concurrent.ConcurrentDictionary<System.String, System.Collections.Generic.List<IndividualResult>>();
GlobalVars.FinalMegaObject = new ConcurrentDictionary<String, List<IndividualResult>>();

// Create an empty dictionary to store the System Security Policies from the security_policy.inf file
GlobalVars.SystemSecurityPoliciesIniObject = [];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ private static Hashtable ConvertJsonElementToHashtable(JsonElement jsonElement)
// Check the type of the JSON value
if (property.Value.ValueKind == JsonValueKind.Object)
{
// If the value is a nested object, recursively convert it to a Hashtable
// If the value is a nested object, recursively convert it to a HashTable
hashtable[property.Name] = ConvertJsonElementToHashtable(property.Value);
}
else if (property.Value.ValueKind == JsonValueKind.Array)
Expand All @@ -51,7 +51,7 @@ private static Hashtable ConvertJsonElementToHashtable(JsonElement jsonElement)
}
else
{
// For primitive values, add them directly to the Hashtable
// For primitive values, add them directly to the HashTable
hashtable[property.Name] = property.Value.ToString();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ namespace HardenWindowsSecurity
{
public static class AttackSurfaceReductionRules
{
/// <summary>
/// Applies Attack Surface Reduction rules
/// </summary>
/// <exception cref="ArgumentNullException"></exception>
public static void Invoke()
{
if (GlobalVars.path is null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ namespace HardenWindowsSecurity
{
public static class BitLockerSettings
{
// Applies all Bitlocker settings hardening category
/// <summary>
/// Applies all Bitlocker settings hardening category
/// </summary>
/// <exception cref="ArgumentNullException"></exception>
public static void Invoke()
{
if (GlobalVars.path is null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ namespace HardenWindowsSecurity
{
public static class CertificateCheckingCommands
{
/// <summary>
/// Checks the certificates of the system and displays ones that don't come by default in Windows
/// </summary>
/// <exception cref="ArgumentNullException"></exception>
public static void Invoke()
{
if (GlobalVars.WorkingDir is null || !Directory.Exists(GlobalVars.WorkingDir))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ namespace HardenWindowsSecurity
{
public static partial class CountryIPBlocking
{
/// <summary>
/// Performs country IP blocking operations
/// </summary>
public static void Invoke()
{

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ namespace HardenWindowsSecurity
{
public static partial class CountryIPBlocking
{
/// <summary>
/// Blocks IP address of the countries in the OFAC list
/// </summary>
public static void CountryIPBlocking_OFAC()
{
Logger.LogMessage("Blocking IP ranges of countries in OFAC sanction list", LogTypeIntel.Information);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ namespace HardenWindowsSecurity
{
public static partial class DownloadsDefenseMeasures
{
/// <summary>
/// Blocks certain dangerous script hosts using AppControl policy
/// </summary>
/// <exception cref="ArgumentNullException"></exception>
public static void DangerousScriptHostsBlocking()
{
if (GlobalVars.path is null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

namespace HardenWindowsSecurity
{
public static class DeviceGuard
public partial class DeviceGuard
{

/// <summary>
Expand All @@ -26,6 +26,16 @@ public static void Invoke()

LGPORunner.RunLGPOCommand(Path.Combine(GlobalVars.path, "Resources", "Security-Baselines-X", "Device Guard Policies", "registry.pol"), LGPORunner.FileType.POL);

Logger.LogMessage("Applying the Device Guard registry settings", LogTypeIntel.Information);

foreach (HardeningRegistryKeys.CsvRecord Item in GlobalVars.RegistryCSVItems!)
{
if (string.Equals(Item.Category, "DeviceGuard", StringComparison.OrdinalIgnoreCase))
{
RegistryEditor.EditRegistry(Item.Path, Item.Key, Item.Value, Item.Type, Item.Action);
}
}

}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using System;

#nullable enable

namespace HardenWindowsSecurity
{
public partial class DeviceGuard
{

/// <summary>
/// Enables mandatory mode of VBS and Memory Integrity
/// </summary>
/// <exception cref="ArgumentNullException"></exception>
public static void DeviceGuard_MandatoryVBS()
{

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

ChangePSConsoleTitle.Set("🖥️ Device Guard");

Logger.LogMessage("Setting VBS and Memory Integrity in Mandatory Mode", LogTypeIntel.Information);

foreach (HardeningRegistryKeys.CsvRecord Item in GlobalVars.RegistryCSVItems!)
{
if (string.Equals(Item.Category, "DeviceGuard_MandatoryVBS", StringComparison.OrdinalIgnoreCase))
{
RegistryEditor.EditRegistry(Item.Path, Item.Key, Item.Value, Item.Type, Item.Action);
}
}

}
}
}
Loading

0 comments on commit 3216011

Please sign in to comment.