Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Harden Windows Security v0.5.5 #319

Merged
merged 21 commits into from
Aug 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading