Skip to content

Commit

Permalink
Merge branch 'main' into WDACConfig-v0.4.6
Browse files Browse the repository at this point in the history
  • Loading branch information
HotCakeX authored Oct 4, 2024
2 parents 611e536 + c59f9ce commit 81b61ec
Show file tree
Hide file tree
Showing 29 changed files with 709 additions and 184 deletions.
4 changes: 2 additions & 2 deletions Harden-Windows-Security Module/Harden Windows Security.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,11 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.PowerShell.SDK" Version="7.5.0-preview.4" />
<PackageReference Include="Microsoft.PowerShell.SDK" Version="7.5.0-preview.5" />
<PackageReference Include="Microsoft.Toolkit.Uwp.Notifications" Version="7.1.3" />
<PackageReference Include="System.DirectoryServices.AccountManagement" Version="9.0.0-rc.1.24431.7" />
<PackageReference Include="System.Management" Version="9.0.0-rc.1.24431.7" />
<PackageReference Include="System.Management.Automation" Version="7.5.0-preview.4" />
<PackageReference Include="System.Management.Automation" Version="7.5.0-preview.5" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -348,8 +348,8 @@ internal static void Enable(string DriveLetter, bool FreePlusUsedSpace)


// Make sure the OS Drive is encrypted first, or else we would add recovery password key protector and then get error about the same problem during auto-unlock key protector enablement
var volumeInfo = HardenWindowsSecurity.BitLocker.GetEncryptedVolumeInfo(Environment.GetEnvironmentVariable("SystemDrive") ?? "C:\\");
if (volumeInfo.ProtectionStatus is not BitLocker.ProtectionStatus.Protected)
BitLockerVolume OSDriveVolumeInfo = HardenWindowsSecurity.BitLocker.GetEncryptedVolumeInfo(Environment.GetEnvironmentVariable("SystemDrive") ?? "C:\\");
if (OSDriveVolumeInfo.ProtectionStatus is not BitLocker.ProtectionStatus.Protected)
{
Logger.LogMessage($"Operation System drive must be encrypted first before encrypting Non-OS drives.", LogTypeIntel.ErrorInteractionRequired);
BitLocker.HasErrorsOccurred = true;
Expand Down Expand Up @@ -385,27 +385,52 @@ internal static void Enable(string DriveLetter, bool FreePlusUsedSpace)

#region
// Delete any possible old leftover ExternalKey key protectors
List<BitLocker.KeyProtector> ExternalKeys = volumeInfo.KeyProtector!.Where(kp => kp.KeyProtectorType is KeyProtectorType.ExternalKey).ToList();
List<BitLocker.KeyProtector> ExternalKeys = VolumeInfoExtended.KeyProtector!.Where(kp => kp.KeyProtectorType is KeyProtectorType.ExternalKey).ToList();

if (ExternalKeys.Count > 1)
// This step ensures any leftover or unbound external key key protectors will be removed and a working one will be added
// If the current one is working and bound, it won't be removed and will be gracefully skipped over.
foreach (KeyProtector ExKp in ExternalKeys)
{
Logger.LogMessage($"The drive {DriveLetter} has more than 1 ExternalKey (Auto-unlock) key protectors, possibly from previous OS installations. Removing all but the one that is currently being used to unlock the drive.", LogTypeIntel.Information);

foreach (KeyProtector ExKp in ExternalKeys)
if (ExKp.KeyProtectorID is not null)
{
if (ExKp.KeyProtectorID is not null)
{
RemoveKeyProtector(DriveLetter, ExKp.KeyProtectorID, true);
}
Logger.LogMessage($"Removing ExternalKey key protector with the ID {ExKp.KeyProtectorID} for the drive {DriveLetter}. Will set a new one bound to the OS drive in the next step.", LogTypeIntel.Information);

RemoveKeyProtector(DriveLetter, ExKp.KeyProtectorID, true);
}
}


// Get the extended volume info based on the drive letter again
// Because if the ExternalKey key protectors were deleted in the previous steps,
// The extended drive info must be updated to reflect that change
VolumeInfoExtended = GetEncryptedVolumeInfo(DriveLetter);

if (HasErrorsOccurred) { return; }

// Get the key protectors of the Drive again for the reason mentioned above
KeyProtectors = VolumeInfoExtended.KeyProtector!
.Select(kp => kp.KeyProtectorType).ToList();


// If the Auto-unlock (aka ExternalKey) key protector is not present, add it
// This only runs if all the ExternalKey key protectors were deleted in the previous step
// Indicating that none of them were bound to the OS Drive and were leftovers of previous OS Installations
if (!KeyProtectors.Contains(BitLocker.KeyProtectorType.ExternalKey))
{
Logger.LogMessage($"Adding a new {BitLocker.KeyProtectorType.ExternalKey} key protector for Auto-unlock to the drive {DriveLetter}.", LogTypeIntel.Information);

EnableBitLockerAutoUnlock(DriveLetter);

if (HasErrorsOccurred) { return; }
}

#endregion


#region
// Check for presence of multiple recovery password key protectors

List<BitLocker.KeyProtector> PasswordProtectors = volumeInfo.KeyProtector!.Where(kp => kp.KeyProtectorType is KeyProtectorType.RecoveryPassword).ToList();
List<BitLocker.KeyProtector> PasswordProtectors = VolumeInfoExtended.KeyProtector!.Where(kp => kp.KeyProtectorType is KeyProtectorType.RecoveryPassword).ToList();

if (PasswordProtectors.Count > 1)
{
Expand All @@ -414,6 +439,9 @@ internal static void Enable(string DriveLetter, bool FreePlusUsedSpace)
#endregion

Logger.LogMessage($"The drive {DriveLetter} is fully encrypted with all the required key protectors.", LogTypeIntel.InformationInteractionRequired);

// Exit the method and do not proceed further if the drive was already encrypted
// And key protector checks have been performed
HasErrorsOccurred = true;
return;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -700,10 +700,6 @@ await Task.Run(() =>
case "NonAdminCommands":
{
HardenWindowsSecurity.NonAdminCommands.Invoke();
if (HardenWindowsSecurity.GUIProtectWinSecurity.SelectedSubCategories.Contains("ClipboardSync"))
{
HardenWindowsSecurity.NonAdminCommands.ClipboardSync();
}
break;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,7 @@ public partial class GUIProtectWinSecurity
{ "LockScreen", new string[] { "LockScreen_CtrlAltDel", "LockScreen_NoLastSignedIn" } },
{ "UserAccountControl", new string[] { "UAC_NoFastSwitching", "UAC_OnlyElevateSigned" } },
{ "CountryIPBlocking", new string[] { "CountryIPBlocking_OFAC" } },
{ "DownloadsDefenseMeasures", new string[] { "DangerousScriptHostsBlocking" } },
{ "NonAdminCommands", new string[] { "ClipboardSync" } }
{ "DownloadsDefenseMeasures", new string[] { "DangerousScriptHostsBlocking" } }
};

internal static System.Windows.Controls.ListView? categories;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public class AsyncDownloader
private static readonly Dictionary<string, string> fileDictionary = new()
{
{
"https://download.microsoft.com/download/8/5/C/85C25433-A1B0-4FFA-9429-7E023E7DA8D8/Windows%2011%20v23H2%20Security%20Baseline.zip",
"https://download.microsoft.com/download/8/5/C/85C25433-A1B0-4FFA-9429-7E023E7DA8D8/Windows%2011%20v24H2%20Security%20Baseline.zip",
"MicrosoftSecurityBaseline.zip"
},
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,15 @@ public string[] GetValidValues()
"BitLockerSettings", // 21 + conditional item for Hibernation check (only available on non-VMs) + Number of Non-OS drives which are dynamically increased
"TLSSecurity", // 21
"LockScreen", // 14
"UserAccountControl", // 4
"UserAccountControl", // 6
"DeviceGuard", // 8
"WindowsFirewall", // 19
"OptionalWindowsFeatures", // 14
"WindowsNetworking", // 9
"MiscellaneousConfigurations", // 17
"WindowsUpdateConfigurations", // 14
"WindowsUpdateConfigurations", // 15
"EdgeBrowserConfigurations", // 14
"NonAdminCommands" // 11
"NonAdminCommands" // 9
];
return categoriex;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -654,6 +654,8 @@ public static Task VerifyBitLockerSettings()
}
else
{
HardenWindowsSecurity.Logger.LogMessage("BitLocker is enabled for the OS Drive but it does not conform to the Normal or Enhanced Security levels requirements.", LogTypeIntel.Information);
nestedObjectArray.Add(new HardenWindowsSecurity.IndividualResult
{
FriendlyName = "Secure OS Drive encryption",
Expand All @@ -667,6 +669,8 @@ public static Task VerifyBitLockerSettings()
}
else
{
HardenWindowsSecurity.Logger.LogMessage("BitLocker is not enabled for the OS Drive.", LogTypeIntel.Information);
nestedObjectArray.Add(new HardenWindowsSecurity.IndividualResult
{
FriendlyName = "Secure OS Drive encryption",
Expand Down Expand Up @@ -1856,6 +1860,10 @@ public static Task VerifyMicrosoftDefender()
// Compare the values of the two HashTables if the keys match
foreach (var targetMitigationItem in TargetMitigations)
{
// Increment the total number of the verifiable compliant values for each process that has a mitigation applied to it in the CSV file
HardenWindowsSecurity.GlobalVars.TotalNumberOfTrueCompliantValues++;
// Get the current key and value from dictionary containing the CSV data
string ProcessName_Target = targetMitigationItem.Key;
string[] ProcessMitigations_Target = targetMitigationItem.Value;
Expand All @@ -1872,31 +1880,52 @@ public static Task VerifyMicrosoftDefender()
// Compare the values of the two dictionaries to see if they are the same without considering the order of the elements (process mitigations)
if (!targetSet.SetEquals(ProcessMitigations_Applied))
{
// If the values are different, it means the process has different mitigations applied to it than the ones in the CSV file
HardenWindowsSecurity.Logger.LogMessage($"Mitigations for {ProcessName_Target} were found but are not compliant", LogTypeIntel.Information);
HardenWindowsSecurity.Logger.LogMessage($"Applied Mitigations: {string.Join(",", ProcessMitigations_Applied)}", LogTypeIntel.Information);
HardenWindowsSecurity.Logger.LogMessage($"Target Mitigations: {string.Join(",", ProcessMitigations_Target)}", LogTypeIntel.Information);
// Increment the total number of the verifiable compliant values for each process that has a mitigation applied to it in the CSV file
HardenWindowsSecurity.GlobalVars.TotalNumberOfTrueCompliantValues++;
Logger.LogMessage($"Mitigations for {ProcessName_Target} were found but they do not exactly match, performing further checks", LogTypeIntel.Information);
nestedObjectArray.Add(new HardenWindowsSecurity.IndividualResult
// Check if the mitigations applied to the current process at least include all of the mitigations required by the CSV file for that process
if (ProcessMitigations_Applied.IsSupersetOf(targetSet))
{
FriendlyName = $"Process Mitigations for: {ProcessName_Target}",
Compliant = false,
Value = string.Join(",", ProcessMitigations_Applied),
Name = $"Process Mitigations for: {ProcessName_Target}",
Category = CatName,
Method = "Cmdlet"
});
HardenWindowsSecurity.Logger.LogMessage($"Mitigations for {ProcessName_Target} contain all the required mitigations plus more", LogTypeIntel.Information);
HardenWindowsSecurity.Logger.LogMessage($"Applied Mitigations: {string.Join(",", ProcessMitigations_Applied)}", LogTypeIntel.Information);
HardenWindowsSecurity.Logger.LogMessage($"Target Mitigations: {string.Join(",", ProcessMitigations_Target)}", LogTypeIntel.Information);
nestedObjectArray.Add(new HardenWindowsSecurity.IndividualResult
{
FriendlyName = $"Process Mitigations for: {ProcessName_Target}",
Compliant = true,
Value = string.Join(",", ProcessMitigations_Target), // Join the array elements into a string to display them properly in the output CSV file
Name = $"Process Mitigations for: {ProcessName_Target}",
Category = CatName,
Method = "Cmdlet"
});
}
else
{
HardenWindowsSecurity.Logger.LogMessage($"Mitigations for {ProcessName_Target} do not contain all of the required mitigations", LogTypeIntel.Information);
HardenWindowsSecurity.Logger.LogMessage($"Applied Mitigations: {string.Join(",", ProcessMitigations_Applied)}", LogTypeIntel.Information);
HardenWindowsSecurity.Logger.LogMessage($"Target Mitigations: {string.Join(",", ProcessMitigations_Target)}", LogTypeIntel.Information);
nestedObjectArray.Add(new HardenWindowsSecurity.IndividualResult
{
FriendlyName = $"Process Mitigations for: {ProcessName_Target}",
Compliant = false,
Value = string.Join(",", ProcessMitigations_Applied),
Name = $"Process Mitigations for: {ProcessName_Target}",
Category = CatName,
Method = "Cmdlet"
});
}
}
else
{
// If the values are the same, it means the process has the same mitigations applied to it as the ones in the CSV file
HardenWindowsSecurity.Logger.LogMessage($"Mitigations for {ProcessName_Target} are compliant", LogTypeIntel.Information);
// Increment the total number of the verifiable compliant values for each process that has a mitigation applied to it in the CSV file
HardenWindowsSecurity.GlobalVars.TotalNumberOfTrueCompliantValues++;
HardenWindowsSecurity.Logger.LogMessage($"Mitigations for {ProcessName_Target} are precisely compliant and match.", LogTypeIntel.Information);
nestedObjectArray.Add(new HardenWindowsSecurity.IndividualResult
{
Expand All @@ -1914,9 +1943,6 @@ public static Task VerifyMicrosoftDefender()
//If the process name is not found in the HashTable containing the currently applied mitigations, it means the process doesn't have any mitigations applied to it
HardenWindowsSecurity.Logger.LogMessage($"Mitigations for {ProcessName_Target} were not found", LogTypeIntel.Information);
// Increment the total number of the verifiable compliant values for each process that has a mitigation applied to it in the CSV file
HardenWindowsSecurity.GlobalVars.TotalNumberOfTrueCompliantValues++;
nestedObjectArray.Add(new HardenWindowsSecurity.IndividualResult
{
FriendlyName = $"Process Mitigations for: {ProcessName_Target}",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ public static void Initialize(string VerbosePreference = "SilentlyContinue", boo
HardenWindowsSecurity.GlobalVars.MDAVConfigCurrent = HardenWindowsSecurity.ConfigDefenderHelper.GetMpComputerStatus();

// Total number of Compliant values
HardenWindowsSecurity.GlobalVars.TotalNumberOfTrueCompliantValues = 241;
HardenWindowsSecurity.GlobalVars.TotalNumberOfTrueCompliantValues = 242;

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

This file was deleted.

Loading

0 comments on commit 81b61ec

Please sign in to comment.