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

Adding support for custom file path rule creation #624

Merged
merged 8 commits into from
Feb 27, 2025
Merged
Show file tree
Hide file tree
Changes from 6 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
2 changes: 1 addition & 1 deletion AppControl Manager/App.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ protected override void OnLaunched(LaunchActivatedEventArgs args)
private Window? m_window;

// Adding this public property to expose the window
public static Window? MainWindow => ((App)Current).m_window;
internal static Window? MainWindow => ((App)Current).m_window;

/// <summary>
/// Event handler for unhandled exceptions.
Expand Down
4 changes: 2 additions & 2 deletions AppControl Manager/AppControl Manager.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
<WindowsAppSDKSelfContained>true</WindowsAppSDKSelfContained>

<!-- Publish Properties -->
<PublishReadyToRun>True</PublishReadyToRun>
<PublishReadyToRun Condition="'$(Configuration)' != 'Debug'">true</PublishReadyToRun>

<ImplicitUsings>disable</ImplicitUsings>
<Description>A modern secure application that simplifies management of Application Control in Windows.</Description>
Expand Down Expand Up @@ -79,7 +79,7 @@
<PublishAot>True</PublishAot>
<OptimizationPreference>Speed</OptimizationPreference>
<ErrorReport>send</ErrorReport>
<FileVersion>1.9.2.0</FileVersion>
<FileVersion>1.9.3.0</FileVersion>
<AssemblyVersion>$(FileVersion)</AssemblyVersion>
<NeutralLanguage>en-US</NeutralLanguage>
<PackageLicenseFile>LICENSE</PackageLicenseFile>
Expand Down
102 changes: 102 additions & 0 deletions AppControl Manager/CustomUIElements/CustomPatternBasedFilePath.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
<ContentDialog
x:Class="AppControlManager.CustomUIElements.CustomPatternBasedFilePath"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:AppControlManager.CustomUIElements"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ui="using:CommunityToolkit.WinUI"
xmlns:controls="using:CommunityToolkit.WinUI.Controls"
xmlns:win="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
xmlns:behaviors="using:CommunityToolkit.WinUI.Behaviors"
mc:Ignorable="d"
Title="Pattern Based File Path"
CloseButtonText="OK"
IsPrimaryButtonEnabled="False"
DefaultButton="Primary"
BorderThickness="1"
CornerRadius="8"
Style="{ThemeResource DefaultContentDialogStyle}"
BorderBrush="{ThemeResource AccentFillColorDefaultBrush}">

<ContentDialog.Resources>
<!-- https://github.com/microsoft/microsoft-ui-xaml/issues/424 -->
<x:Double x:Key="ContentDialogMaxWidth">900</x:Double>
</ContentDialog.Resources>

<Grid>

<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>

<controls:WrapPanel Orientation="Vertical" Margin="0,0,0,15" Grid.Row="0" HorizontalSpacing="10" VerticalSpacing="10">

<TextBlock IsTextSelectionEnabled="True" TextWrapping="Wrap" VerticalAlignment="Top" Text="Here are some examples of custom patterns for file path rules" />

<HyperlinkButton Content="More Info" NavigateUri="https://learn.microsoft.com/en-us/windows/security/application-security/application-control/app-control-for-business/design/select-types-of-rules-to-create#using-wildcards-in-app-control-filepath-rules" />

</controls:WrapPanel>

<ListView x:Name="CustomPatternBasedFilePathListView"
Grid.Row="1"
SelectionMode="None"
ScrollViewer.HorizontalScrollMode="Enabled"
ScrollViewer.IsHorizontalRailEnabled="True"
ScrollViewer.HorizontalScrollBarVisibility="Visible"
ShowsScrollingPlaceholders="True"
ScrollViewer.VerticalScrollBarVisibility="Visible"
Margin="0,0,0,15">

<ListView.Header>

<Border CornerRadius="5" Background="Black">
<interactivity:Interaction.Behaviors>
<behaviors:StickyHeaderBehavior />
</interactivity:Interaction.Behaviors>
<Grid>

<Grid.ColumnDefinitions>
<ColumnDefinition Width="400" />
<ColumnDefinition Width="400" />
</Grid.ColumnDefinitions>
<TextBlock Text="Example" Foreground="LightGray" HorizontalAlignment="Stretch" Grid.Column="0" FontWeight="Bold" Margin="10,0,2,0" Padding="5"/>
<TextBlock Text="Description" Foreground="LightGray" HorizontalAlignment="Stretch" Grid.Column="1" FontWeight="Bold" Margin="10,0,2,0" Padding="5"/>
</Grid>
</Border>
</ListView.Header>

<!-- DataTemplate for ListView items -->
<ListView.ItemTemplate>
<DataTemplate x:DataType="local:FilePathPatternExample">
<!-- Setting Background="Transparent" on the Grid makes it hit-test visible, meaning that even areas without any child elements (like empty spaces in the column) will respond to pointer events. -->
<Grid Background="Transparent">

<Grid.ColumnDefinitions>
<ColumnDefinition Width="400" />
<ColumnDefinition Width="400" />
</Grid.ColumnDefinitions>
<TextBlock Text="{x:Bind Example}" HorizontalAlignment="Left" Grid.Column="0" Margin="0,10,2,10" TextWrapping="WrapWholeWords" IsTextSelectionEnabled="True"/>
<TextBlock Text="{x:Bind Description}" HorizontalAlignment="Left" Grid.Column="1" TextWrapping="WrapWholeWords" Margin="0,10,2,10" IsTextSelectionEnabled="True"/>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>

<TextBlock IsTextSelectionEnabled="True" Margin="0,0,0,15" Grid.Row="2" TextWrapping="Wrap" VerticalAlignment="Top">
<Bold><Run Foreground="DeepPink" FontSize="18">*</Run></Bold>
<Span>Matches zero or more characters.</Span>
</TextBlock>

<TextBlock IsTextSelectionEnabled="True" Margin="0,0,0,15" Grid.Row="3" TextWrapping="Wrap" VerticalAlignment="Top">
<Bold><Run Foreground="DeepPink" FontSize="18">?</Run></Bold>
<Span>Matches a single character.</Span>
</TextBlock>

</Grid>

</ContentDialog>
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
using System.Collections.ObjectModel;
using Microsoft.UI.Xaml.Controls;

namespace AppControlManager.CustomUIElements;

// https://learn.microsoft.com/en-us/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.controls.contentdialog
internal sealed partial class CustomPatternBasedFilePath : ContentDialog
{

internal static readonly ObservableCollection<FilePathPatternExample> FilePathPatternExamplesCollection = [

new()
{
Example = "C:\\Windows\\*",
Description = "Matches all files in the 'C:\\Windows' directory and its sub-directories."
},
new()
{
Example = "D:\\EnterpriseApps\\MyApp\\*",
Description = "Matches all files in the 'D:\\EnterpriseApps\\MyApp\\' directory and its sub-directories."
},
new()
{
Example = "*\\Bing.exe",
Description = "Matches any file(s) named 'Bing.exe' in any location."
},
new()
{
Example = "C:\\*\\CCMCACHE\\*\\7z????-x64.exe",
Description = "Wildcards used in the middle of a path allow all files that match that pattern. In this example, both of these hypothetical paths would match: 'C:\\WINDOWS\\CCMCACHE\\12345\\7zabcd-x64.exe' and 'C:\\USERS\\AppControlUSER\\Downloads\\Malware\\CCMCACHE\\Pwned\\7zhaha-x64.exe'"
},
new()
{
Example = "C:\\Users\\UserName\\AppData\\Local\\Temp\\????????-????-????-????-????????????.tmp.node\"",
Description = "This example allows any '.node' temporary file inside of the TEMP folder that has a GUID as file name."
}
];

internal CustomPatternBasedFilePath()
{
this.InitializeComponent();

XamlRoot = App.MainWindow?.Content.XamlRoot;

CustomPatternBasedFilePathListView.ItemsSource = FilePathPatternExamplesCollection;
}
}

internal sealed class FilePathPatternExample
{
public string? Example;
public string? Description;
}
3 changes: 2 additions & 1 deletion AppControl Manager/IntelGathering/ScanLevels.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@ public enum ScanLevels
Hash,
FilePath,
WildCardFolderPath,
PFN
PFN,
CustomFileRulePattern
}
12 changes: 6 additions & 6 deletions AppControl Manager/Main/BasePolicyCreator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -390,7 +390,7 @@ internal static void GetDriversBlockRules(string StagingArea)
/// <param name="RequireEVSigners"></param>
/// <param name="EnableScriptEnforcement"></param>
/// <param name="TestMode"></param>
internal static void BuildAllowMSFT(string StagingArea, bool IsAudit, ulong? LogSize, bool deploy, bool RequireEVSigners, bool EnableScriptEnforcement, bool TestMode, bool? deployAppControlSupplementalPolicy, string? PolicyIDToUse = null)
internal static void BuildAllowMSFT(string StagingArea, bool IsAudit, ulong? LogSize, bool deploy, bool RequireEVSigners, bool EnableScriptEnforcement, bool TestMode, bool? deployAppControlSupplementalPolicy, string? PolicyIDToUse = null, bool DeployMicrosoftRecommendedBlockRules = true)
{

string policyName;
Expand All @@ -414,7 +414,7 @@ internal static void BuildAllowMSFT(string StagingArea, bool IsAudit, ulong? Log
string finalPolicyPath = Path.Combine(GlobalVars.UserConfigDir, $"{policyName}.xml");

// Get/Deploy the block rules if this base policy is not being swapped
if (PolicyIDToUse is null)
if (PolicyIDToUse is null && DeployMicrosoftRecommendedBlockRules)
GetBlockRules(StagingArea, deploy);

Logger.Write("Copying the AllowMicrosoft.xml from Windows directory to the Staging Area");
Expand Down Expand Up @@ -476,7 +476,7 @@ internal static void BuildAllowMSFT(string StagingArea, bool IsAudit, ulong? Log
/// <param name="RequireEVSigners"></param>
/// <param name="EnableScriptEnforcement"></param>
/// <param name="TestMode"></param>
internal static void BuildDefaultWindows(string StagingArea, bool IsAudit, ulong? LogSize, bool deploy, bool RequireEVSigners, bool EnableScriptEnforcement, bool TestMode, bool? deployAppControlSupplementalPolicy, string? PolicyIDToUse = null)
internal static void BuildDefaultWindows(string StagingArea, bool IsAudit, ulong? LogSize, bool deploy, bool RequireEVSigners, bool EnableScriptEnforcement, bool TestMode, bool? deployAppControlSupplementalPolicy, string? PolicyIDToUse = null, bool DeployMicrosoftRecommendedBlockRules = true)
{

string policyName;
Expand All @@ -500,7 +500,7 @@ internal static void BuildDefaultWindows(string StagingArea, bool IsAudit, ulong
string finalPolicyPath = Path.Combine(GlobalVars.UserConfigDir, $"{policyName}.xml");

// Get/Deploy the block rules if this base policy is not being swapped
if (PolicyIDToUse is null)
if (PolicyIDToUse is null && DeployMicrosoftRecommendedBlockRules)
GetBlockRules(StagingArea, deploy);

Logger.Write("Copying the DefaultWindows.xml from Windows directory to the Staging Area");
Expand Down Expand Up @@ -658,7 +658,7 @@ internal static void GetBlockRules(string StagingArea, bool deploy)
/// <param name="RequireEVSigners"></param>
/// <param name="EnableScriptEnforcement"></param>
/// <param name="TestMode"></param>
internal static void BuildSignedAndReputable(string StagingArea, bool IsAudit, ulong? LogSize, bool deploy, bool RequireEVSigners, bool EnableScriptEnforcement, bool TestMode, bool? deployAppControlSupplementalPolicy, string? PolicyIDToUse = null)
internal static void BuildSignedAndReputable(string StagingArea, bool IsAudit, ulong? LogSize, bool deploy, bool RequireEVSigners, bool EnableScriptEnforcement, bool TestMode, bool? deployAppControlSupplementalPolicy, string? PolicyIDToUse = null, bool DeployMicrosoftRecommendedBlockRules = true)
{

string policyName;
Expand All @@ -682,7 +682,7 @@ internal static void BuildSignedAndReputable(string StagingArea, bool IsAudit, u
string finalPolicyPath = Path.Combine(GlobalVars.UserConfigDir, $"{policyName}.xml");

// Get/Deploy the block rules if this base policy is not being swapped
if (PolicyIDToUse is null)
if (PolicyIDToUse is null && DeployMicrosoftRecommendedBlockRules)
GetBlockRules(StagingArea, deploy);

Logger.Write("Copying the AllowMicrosoft.xml from Windows directory to the Staging Area");
Expand Down
99 changes: 99 additions & 0 deletions AppControl Manager/Others/GetAppsList.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Threading.Tasks;
using Windows.ApplicationModel;
using Windows.Management.Deployment;

namespace AppControlManager.Others;

internal static class GetAppsList
{

// Package Manager object used by the PFN section
private static readonly PackageManager packageManager = new();

/// <summary>
/// Gets the list of all installed Packaged Apps
/// </summary>
/// <returns></returns>
private static async Task<List<PackagedAppView>> Get()
{
return await Task.Run(() =>
{
// The list to return as output
List<PackagedAppView> apps = [];

// Get all of the packages on the system
IEnumerable<Package> allApps = packageManager.FindPackages();

// Loop over each package
foreach (Package item in allApps)
{
try
{
// Try get the logo string
string? logoStr = item.Logo?.ToString();

// Validate that the logo string is a valid absolute URI
if (!Uri.TryCreate(logoStr, UriKind.Absolute, out _))
{
// If invalid, assign a fallback logo
logoStr = GlobalVars.FallBackAppLogoURI;
}

// Create a new instance of the class that displays each app in the ListView
apps.Add(new PackagedAppView(
displayName: item.DisplayName,
version: $"Version: {item.Id.Version.Major}.{item.Id.Version.Minor}.{item.Id.Version.Build}.{item.Id.Version.Revision}",
packageFamilyName: $"PFN: {item.Id.FamilyName}",
logo: logoStr,
packageFamilyNameActual: item.Id.FamilyName
));
}
catch (Exception ex)
{
try
{
Logger.Write($"There was an error getting the details for the app: {item.Id.FamilyName}");
}
catch
{
Logger.Write("There was an error getting the details of an app");
}
Logger.Write(ErrorWriter.FormatException(ex));
}
}

return apps;
});

}


// To create a collection of grouped items, create a query that groups
// an existing list, or returns a grouped collection from a database.
// The following method is used to create the ItemsSource for our CollectionViewSource that is defined in XAML
internal static async Task<ObservableCollection<GroupInfoListForPackagedAppView>> GetContactsGroupedAsync()
{
// Grab Apps objects from pre-existing list
IEnumerable<GroupInfoListForPackagedAppView> query = from item in await Get()

// Ensure DisplayName is not null before grouping
// This also prevents apps without a DisplayName to exist in the returned apps list
where !string.IsNullOrWhiteSpace(item.DisplayName)

// Group the items returned from the query, sort and select the ones you want to keep
group item by item.DisplayName[..1].ToUpper() into g
orderby g.Key

// GroupInfoListForPackagedAppView is a simple custom class that has an IEnumerable type attribute, and
// a key attribute. The IGrouping-typed variable g now holds the App objects,
// and these objects will be used to create a new GroupInfoListForPackagedAppView object.
select new GroupInfoListForPackagedAppView(g) { Key = g.Key };

return [.. query];
}

}
2 changes: 1 addition & 1 deletion AppControl Manager/Package.appxmanifest
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
<Identity
Name="AppControlManager"
Publisher="CN=SelfSignedCertForAppControlManager"
Version="1.9.2.0" />
Version="1.9.3.0" />

<mp:PhoneIdentity PhoneProductId="199a23ec-7cb6-4ab5-ab50-8baca348bc79" PhonePublisherId="00000000-0000-0000-0000-000000000000"/>

Expand Down
Loading