Skip to content

Commit

Permalink
Merge pull request #319 from HotCakeX/Harden-Windows-Security-v0.5.5
Browse files Browse the repository at this point in the history
Harden Windows Security v0.5.5
  • Loading branch information
HotCakeX authored Aug 25, 2024
2 parents cc70a5c + 9fd2523 commit cf18768
Show file tree
Hide file tree
Showing 118 changed files with 7,442 additions and 2,774 deletions.
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Harden-Windows-Security Module/obj/
Harden-Windows-Security Module/.vs/
Harden-Windows-Security Module/bin/
WDACConfig/obj/
WDACConfig/.vs/
WDACConfig/bin/
9 changes: 9 additions & 0 deletions Harden-Windows-Security Module/.editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,12 @@ dotnet_diagnostic.CA1401.severity = error

# CA1303: Do not pass literals as localized parameters
dotnet_diagnostic.CA1303.severity = silent

# CA1309: Use ordinal string comparison
dotnet_diagnostic.CA1309.severity = error

# CA1311: Specify a culture or use an invariant version
dotnet_diagnostic.CA1311.severity = error

# CA1416: Validate platform compatibility
dotnet_diagnostic.CA1416.severity = error
15 changes: 11 additions & 4 deletions Harden-Windows-Security Module/Harden Windows Security.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,22 @@

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net9.0-windows10.0.22621.0</TargetFramework>
<TargetFramework>net9.0-windows10.0.26100.0</TargetFramework>
<RootNamespace>HardenWindowsSecurity</RootNamespace>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<UseWpf>true</UseWpf>
<UseWindowsForms>true</UseWindowsForms>
<HighEntropyVA>true</HighEntropyVA>
<XamlDebuggingInformation>True</XamlDebuggingInformation>
<StartupObject>HardenWindowsSecurity.Program</StartupObject>
<PackageProjectUrl>https://github.com/HotCakeX/Harden-Windows-Security</PackageProjectUrl>
<RepositoryUrl>https://github.com/HotCakeX/Harden-Windows-Security</RepositoryUrl>
<PackageTags>Windows</PackageTags>
<PackageTags>Windows;Cyber;CyberSecurity</PackageTags>
<Title>Harden Windows Security</Title>
<Authors>Violet Hansen</Authors>
<Company>SpyNetGirl</Company>
<PackageReleaseNotes>https://github.com/HotCakeX/Harden-Windows-Security/releases</PackageReleaseNotes>
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
Expand All @@ -29,12 +31,17 @@
<ItemGroup>
<Content Include="Main files\Resources\**">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Main files\Shared\**">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>

<ItemGroup>
<PackageReference Include="System.DirectoryServices.AccountManagement" Version="9.0.0-preview.6.24327.7" />
<PackageReference Include="System.Management" Version="9.0.0-preview.6.24327.7" />
<PackageReference Include="Microsoft.PowerShell.SDK" Version="7.5.0-preview.3" />
<PackageReference Include="Microsoft.Toolkit.Uwp.Notifications" Version="7.1.3" />
<PackageReference Include="System.DirectoryServices.AccountManagement" Version="9.0.0-preview.7.24405.7" />
<PackageReference Include="System.Management" Version="9.0.0-preview.7.24405.7" />
<PackageReference Include="System.Management.Automation" Version="7.5.0-preview.3" />
</ItemGroup>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ System
System.IO
System.Xml
System.Net
System.Data
WindowsBase
System.Xaml
System.Linq
Expand All @@ -11,6 +12,7 @@ System.Windows
System.CodeDom
System.Runtime
System.Net.Http
System.Xml.Linq
System.Security
PresentationCore
System.Text.Json
Expand All @@ -21,6 +23,7 @@ System.ObjectModel
System.Collections
System.Windows.Forms
System.Net.Primitives
System.ComponentModel
PresentationFramework
System.IO.Compression
System.Security.Claims
Expand All @@ -32,6 +35,7 @@ WindowsFormsIntegration
System.DirectoryServices
Microsoft.Win32.Registry
System.Security.Principal
System.Reflection.Metadata
System.Diagnostics.Process
Microsoft.Win32.Primitives
System.Management.Automation
Expand All @@ -42,4 +46,5 @@ System.Windows.Controls.Ribbon
System.Text.RegularExpressions
System.ComponentModel.Primitives
System.Security.Principal.Windows
System.ComponentModel.TypeConverter
System.DirectoryServices.AccountManagement
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ private static string GetSubDirectoryName(string basePath)
// Finally, it extracts the downloaded zip files to the working directory
// It also copies the LGPO.exe to the Microsoft Security Baseline and Microsoft 365 Security Baseline folders
// so that it can be used by the PowerShell script
public static void PrepDownloadedFiles(string? LGPOPath, string? MSFTSecurityBaselinesPath, string? MSFT365AppsSecurityBaselinesPath, bool GUI)
public static void PrepDownloadedFiles(string? LGPOPath, string? MSFTSecurityBaselinesPath, string? MSFT365AppsSecurityBaselinesPath)
{
// Only download if offline is not used
if (!HardenWindowsSecurity.GlobalVars.Offline)
Expand All @@ -175,7 +175,7 @@ public static void PrepDownloadedFiles(string? LGPOPath, string? MSFTSecurityBas
}
else if (DownloadsTask.IsCompletedSuccessfully)
{
// Console.WriteLine("Download completed successfully");
// HardenWindowsSecurity.Logger.LogMessage("Download completed successfully");
}

}
Expand Down
6 changes: 3 additions & 3 deletions Harden-Windows-Security Module/Main files/C#/Categoriex.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public string[] GetValidValues()
{
string[] categoriex = new string[]
{
"MicrosoftDefender", // 54 - 3x(N/A) + Number of Process Mitigations which are dynamically increased
"MicrosoftDefender", // 56 - 1x(N/A) + Number of Process Mitigations which are dynamically increased
"AttackSurfaceReductionRules", // 19 rules
"BitLockerSettings", // 21 + conditional item for Hibernation check (only available on non-VMs) + Number of Non-OS drives which are dynamically increased
"TLSSecurity", // 21
Expand Down Expand Up @@ -77,8 +77,8 @@ public static bool IsTpmPresentAndEnabled()
return true;
// foreach (ManagementObject tpm in queryCollection)
// {
// Console.WriteLine("TPM is present on this system.");
// Console.WriteLine("TPM Version: " + tpm["SpecVersion"]);
// HardenWindowsSecurity.Logger.LogMessage("TPM is present on this system.");
// HardenWindowsSecurity.Logger.LogMessage("TPM Version: " + tpm["SpecVersion"]);
// }
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -347,7 +347,7 @@ private static bool CompareRegistryValues(string type, object regValue, object e
}
catch (Exception)
{
// Console.WriteLine($"Error comparing registry values: {ex.Message}");
// HardenWindowsSecurity.Logger.LogMessage($"Error comparing registry values: {ex.Message}");
return false;
}
return false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -170,5 +170,45 @@ public enum NetSecurityEncryption : ushort
Required = 1,
Dynamic = 2
}


public enum FirewallRuleAction
{
Enable,
Disable
}

/// <summary>
/// Enable or disable a firewall rule by DisplayName
/// Can be expanded in the future to provide the full functionality of the built-in cmdlets but for now these are the features that are needed
/// </summary>
/// <param name="action">Enable/Disable</param>
/// <param name="displayName">The DisplayName of the Firewall rule to Enable/Disable</param>
public static void ManageFirewallRule(FirewallRuleAction action, string displayName)
{
// Convert the enum to the corresponding method name
string methodName = action.ToString();

// Define the WMI query to get the firewall rule by DisplayName
// The 'LIKE' operator in WMI queries can be used for case-insensitive matching
string query = $"SELECT * FROM MSFT_NetFirewallRule WHERE UPPER(DisplayName) = '{displayName.ToUpperInvariant()}'";

// Initialize the ManagementScope
ManagementScope scope = new ManagementScope(@"\\.\ROOT\StandardCimv2");
scope.Connect();

// Execute the WMI query
using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, new ObjectQuery(query)))
{
using (ManagementObjectCollection results = searcher.Get())
{
// Iterate through the results and invoke the specified method
foreach (ManagementObject rule in results)
{
rule.InvokeMethod(methodName, null);
}
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -86,5 +86,80 @@ private static DateTime ConvertDmtfToDateTime(string dmtfTime)

throw new FormatException($"Invalid DMTF datetime format: {dmtfTime}");
}


/// <summary>
/// The Set-MpPreference command but implemented from scratch for the Harden Windows Security application
/// </summary>
/// <typeparam name="T">The type of the value to set the Microsoft Defender feature to</typeparam>
/// <param name="preferenceName">The name of the Microsoft Defender feature to configure</param>
/// <param name="preferenceValue">The value to set the Microsoft Defender feature to</param>
public static void SetMpComputerStatus<T>(string preferenceName, T preferenceValue)
{
try
{
// Connect to the WMI namespace
var scope = new ManagementScope(@"\\.\ROOT\Microsoft\Windows\Defender");
scope.Connect();

// Create an instance of the MSFT_MpPreference class
var mpPreferenceClass = new ManagementClass(scope, new ManagementPath("MSFT_MpPreference"), null);

// Get the available methods for the class
var methodParams = mpPreferenceClass.GetMethodParameters("Set");

if (preferenceValue == null)
{
throw new ArgumentNullException(nameof(preferenceValue));
}

// Set the preference based on the type T
if (typeof(T) == typeof(string))
{
methodParams[preferenceName] = (string)(object)preferenceValue;
}
else if (typeof(T) == typeof(bool))
{
methodParams[preferenceName] = (bool)(object)preferenceValue;
}
else if (typeof(T) == typeof(int))
{
methodParams[preferenceName] = (int)(object)preferenceValue;
}
else if (typeof(T) == typeof(double))
{
methodParams[preferenceName] = (double)(object)preferenceValue;
}
else if (typeof(T) == typeof(float))
{
methodParams[preferenceName] = (float)(object)preferenceValue;
}
else if (typeof(T) == typeof(string[]))
{
methodParams[preferenceName] = (string[])(object)preferenceValue;
}
else if (typeof(T) == typeof(byte))
{
methodParams[preferenceName] = (byte)(object)preferenceValue;
}
else if (typeof(ushort) == typeof(ushort))
{
methodParams[preferenceName] = (ushort)(object)preferenceValue;
}
else
{
throw new ArgumentException($"Unsupported type {typeof(T)} for preference value");
}

// Invoke the method to apply the settings
mpPreferenceClass.InvokeMethod("Set", methodParams, null);

HardenWindowsSecurity.Logger.LogMessage($"{preferenceName} set to {preferenceValue} (Type: {typeof(T).Name}) successfully.");
}
catch (Exception ex)
{
HardenWindowsSecurity.Logger.LogMessage($"Error setting {preferenceName}: {ex.Message}- You might need you Update your OS first.");
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public static List<ManagementObject> Get()
/// PS Example: [HardenWindowsSecurity.NetConnectionProfiles]::Set((3, 22), $null, [HardenWindowsSecurity.NetConnectionProfiles+NetworkCategory]::public)
/// PS Example: [HardenWindowsSecurity.NetConnectionProfiles]::Set($null, ('Ethernet', 'Wi-Fi'), [HardenWindowsSecurity.NetConnectionProfiles+NetworkCategory]::private)
/// <returns>True if successful, otherwise false.</returns>
public static bool Set(int[] interfaceIndices, string[] interfaceAliases, NetworkCategory networkCategory)
public static bool Set(NetworkCategory networkCategory, int[]? interfaceIndices = null, string[]? interfaceAliases = null)
{
try
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
using System;
using System.IO;
using System.Globalization;
using System.Management.Automation;
using System.Security.Principal;
using System.Threading;
using System.Diagnostics;

#nullable enable

namespace HardenWindowsSecurity
{
public class InvokeConfirmation
{
/// <summary>
/// This method will perform the system compliance checking and verification
/// </summary>
/// <param name="Categories"></param>
public static void Invoke(string[] Categories)
{
HardenWindowsSecurity.Logger.LogMessage("Collecting Intune applied policy details from the System");

HardenWindowsSecurity.Logger.LogMessage("Controlled Folder Access Handling");
HardenWindowsSecurity.ControlledFolderAccessHandler.Start();

// Give the Defender internals time to process the updated exclusions list
Thread.Sleep(5000);

HardenWindowsSecurity.Logger.LogMessage("Collecting any possible Intune/MDM policies");
HardenWindowsSecurity.SYSTEMScheduledTasks.Invoke();

// Collect the JSON File Paths
string MDM_Firewall_DomainProfile02_Path = System.IO.Path.Combine(HardenWindowsSecurity.GlobalVars.WorkingDir, "MDM_Firewall_DomainProfile02.json");
string MDM_Firewall_PrivateProfile02_Path = System.IO.Path.Combine(HardenWindowsSecurity.GlobalVars.WorkingDir, "MDM_Firewall_PrivateProfile02.json");
string MDM_Firewall_PublicProfile02_Path = System.IO.Path.Combine(HardenWindowsSecurity.GlobalVars.WorkingDir, "MDM_Firewall_PublicProfile02.json");
string MDM_Policy_Result01_Update02_Path = System.IO.Path.Combine(HardenWindowsSecurity.GlobalVars.WorkingDir, "MDM_Policy_Result01_Update02.json");
string MDM_Policy_Result01_System02_Path = System.IO.Path.Combine(HardenWindowsSecurity.GlobalVars.WorkingDir, "MDM_Policy_Result01_System02.json");


// Wait until all files are created, this is necessary because sometimes it takes a second or two for the scheduled task to create the files
// Initialize a stopwatch to track the elapsed time so we don't wait indefinitely
Stopwatch stopwatch = Stopwatch.StartNew();

while (true)
{
try
{
// Check if all files exist
if (File.Exists(MDM_Firewall_DomainProfile02_Path) &&
File.Exists(MDM_Firewall_PrivateProfile02_Path) &&
File.Exists(MDM_Firewall_PublicProfile02_Path) &&
File.Exists(MDM_Policy_Result01_Update02_Path) &&
File.Exists(MDM_Policy_Result01_System02_Path))
{
break; // Exit the loop if all files exist
}
}
catch (IOException)
{
// Ignore IOException and continue waiting
// Because the scheduled task will probably be accessing the file at the same time as well
}

// Check if the timeout has been exceeded
if (stopwatch.ElapsedMilliseconds > 10000) // 10 seconds in milliseconds
{
throw new TimeoutException("Timeout exceeded while waiting for the MDM policy files to be created.");
}

// Sleep for a short period before checking again
Thread.Sleep(500);
}

// Parse the JSON Files and store the results in global variables
HardenWindowsSecurity.GlobalVars.MDM_Firewall_DomainProfile02 = HardenWindowsSecurity.JsonToHashtable.ProcessJsonFile(MDM_Firewall_DomainProfile02_Path);
HardenWindowsSecurity.GlobalVars.MDM_Firewall_PrivateProfile02 = HardenWindowsSecurity.JsonToHashtable.ProcessJsonFile(MDM_Firewall_PrivateProfile02_Path);
HardenWindowsSecurity.GlobalVars.MDM_Firewall_PublicProfile02 = HardenWindowsSecurity.JsonToHashtable.ProcessJsonFile(MDM_Firewall_PublicProfile02_Path);
HardenWindowsSecurity.GlobalVars.MDM_Policy_Result01_Update02 = HardenWindowsSecurity.JsonToHashtable.ProcessJsonFile(MDM_Policy_Result01_Update02_Path);
HardenWindowsSecurity.GlobalVars.MDM_Policy_Result01_System02 = HardenWindowsSecurity.JsonToHashtable.ProcessJsonFile(MDM_Policy_Result01_System02_Path);

HardenWindowsSecurity.Logger.LogMessage("Verifying the security settings");
HardenWindowsSecurity.ConfirmSystemComplianceMethods.OrchestrateComplianceChecks(Categories);

}
}
}
Loading

0 comments on commit cf18768

Please sign in to comment.