-
Notifications
You must be signed in to change notification settings - Fork 180
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adding support for custom file path rule creation (#624)
File path rules now work for non-admin protected folders such as Desktop folder. In the Create Supplemental Policy page, if the scan level is set to File Path or Wildcard File Path, a new rule option called Disabled:Runtime FilePath Rule Protection will be added so that you can use file path rules to allow files in non-admin protected paths to run. Added a deploy toggle button to the Configure policy rule options page. Related discussion File Publisher and Hash rule types created in the XML file will no longer have the file path in the FriendlyName field. This is to make the generated policy more generic for mass deployments. Related discussion Added the ability to create custom pattern-based file-rule-based Supplemental and Deny policies. Related feature request. You can use this feature to create sophisticated allow/deny rules for very dynamic situations. Bumped version to 1.9.3.0 Added toggle buttons to the Create AppControl Policy that allows you to create/deploy the base policies without creation/deploying the Microsoft recommended (user-mode) block rules. Improved the resiliency of installed packaged apps list retrieval. In the Configure Policy Rule Options page, when you assign an XML file path to the page using the Sidebar button, its rule options will be automatically retrieved and displayed to you. Previously this would only work when you used the Browse button in the page itself. Some of the info bars in the Create Supplemental Policy page weren't closable at the end of the operation, that's fixed now. All CIP files generated for supplemental and deny policies have the same file name that you select as policy name, making it easier to identify them in the user configurations directory. Previously the CIP files would have the ID (GUID format) which made it hard to recognize which XML or policy they belonged to. Made the same change to the Allow New Apps page at the final step (Step 3) when you create to deploy the supplemental policy. When creating Supplemental or Deny policies, if you choose to deploy them, only the XML policy file will exist in the AppControl Manager directory in Program Files, but if you do not toggle the Deploy button, then the CIP file will also exist in the AppControl Manager directory. This makes it easier for you to use the CIP file on another system. Both the XML and CIP files will have the same name, easy to recognize, and it's the same name you select for the policy. Made the same change to the Allow New Apps page at the final step (Step 3) when you create to deploy the supplemental policy. When user is already inside of the scan results pages for supplemental and deny policies, the total logs/files count is now updated in real time.
- Loading branch information
Showing
27 changed files
with
1,155 additions
and
333 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
102 changes: 102 additions & 0 deletions
102
AppControl Manager/CustomUIElements/CustomPatternBasedFilePath.xaml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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> |
53 changes: 53 additions & 0 deletions
53
AppControl Manager/CustomUIElements/CustomPatternBasedFilePath.xaml.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,5 +8,6 @@ public enum ScanLevels | |
Hash, | ||
FilePath, | ||
WildCardFolderPath, | ||
PFN | ||
PFN, | ||
CustomFileRulePattern | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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]; | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.