RegistryPlugins icon indicating copy to clipboard operation
RegistryPlugins copied to clipboard

ApplicationSettingsContainer Plugin

Open ogmini opened this issue 4 months ago • 36 comments

Adding ApplicationSettingsContainer Plugin for handling settings.dat files related to packaged applications in Windows. Below are some screenshots of using Registry Explorer to examine the settings.dat file for the Photos application on Windows 11. The First one is without the plugin and the second is with the plugin.

No Plugin Photos-NoPlugin

Plugin Photos-Plugin

More details and another example can be found at https://ogmini.github.io/2025/08/06/Registry-Plugin-Application-Settings-Container-(RECmd-and-Registry-Explorer).html

ogmini avatar Aug 07 '25 18:08 ogmini

@AndrewRathbun - I added some changes to support subkeys. Microsoft documentation didn't make mention of subkey support but it is there. I noticed it while perusing the settings.dat for Photos more closely.

Screenshot 2025-08-08 072757

ogmini avatar Aug 08 '25 11:08 ogmini

Awesome! Nice work! For code PRs, I always give @EricZimmerman the final authority for merging. He'll merge when he reviews it.

AndrewRathbun avatar Aug 08 '25 12:08 AndrewRathbun

This is great work! Can see useful bits even in that Photos screenshot. IsFirstRun and FirstUseTime if they work the way I think they do would be good for tracking recon/lateral movement activity on freshly used compromised accounts for example. Recent Files in Notepad too is a great one too. This will unlock a lot of new discoveries thanks again for putting the effort in to getting this across the line!

reece394 avatar Aug 08 '25 21:08 reece394

@ogmini I have compiled this to test it out and found some more useful bits like in the Camera app it stores AppLaunchesWithSuccessfulCaptures as well as Camera devices inside the SensorService SubKey and in the WindowsStore app in the SearchContainer subkey it stores search history in MRU style with SearchHistory* and SearchHistoryCount fields. However in the WindowsCommunicationApps settings.dat in the ConfigSettings subkey the RegUwpDateTimeOffset Value type seems slightly off with it having the year being 3623 instead of 2023. This could be Microsoft being Microsoft but I wanted to raise it to you anyway just FYI image

PS when you figure out the RegUwpCompositeValue it seems in MicrosoftWindows.Client.CBS in Search/PersistentStorage that it stores the programs searched for and launched via the start menu at least in Windows 11 with MRU_* keys. In the example below I searched for local s and launched Local Security Policy (Microsoft.AutoGenerated.{BD3F924E-55FB-A1BA-9DE6-B50F9F2460AC}) (Screenshot is from another device that doesn't have the plugin installed) Screenshot 2025-08-09 at 17 40 08

reece394 avatar Aug 09 '25 16:08 reece394

@ogmini I have compiled this to test it out and found some more useful bits like in the Camera app it stores AppLaunchesWithSuccessfulCaptures as well as Camera devices inside the SensorService SubKey and in the WindowsStore app in the SearchContainer subkey it stores search history in MRU style with SearchHistory* and SearchHistoryCount fields. However in the WindowsCommunicationApps settings.dat in the ConfigSettings subkey the RegUwpDateTimeOffset Value type seems slightly off with it having the year being 3623 instead of 2023. This could be Microsoft being Microsoft but I wanted to raise it to you anyway just FYI image

PS when you figure out the RegUwpCompositeValue it seems in MicrosoftWindows.Client.CBS in Search/PersistentStorage that it stores the programs searched for and launched via the start menu at least in Windows 11 with MRU_* keys. In the example below I searched for local s and launched Local Security Policy (Microsoft.AutoGenerated.{BD3F924E-55FB-A1BA-9DE6-B50F9F2460AC}) (Screenshot is from another device that doesn't have the plugin installed) Screenshot 2025-08-09 at 17 40 08

Interesting about the RegUwpDateTimeOffset. I wonder if they had just stored it as a DateTime. In the documentation they state that for C#/.NET you should use DateTimeOffset. I’ll take a poke at this tomorrow. Might be worth displaying both DateTimeOffset and DateTime in the value column.

The composite value has me really stumped. Just need to poke some more.

Oh also, if you’re looking at the settings.dat file. Don’t forget about the application specific registry hives. I’ve found out that they can reference each other for more information. https://ogmini.github.io/2025/08/09/Windows-Snipping-Tool-Part-1.html

ogmini avatar Aug 10 '25 00:08 ogmini

@ogmini Did you get it sorted okay? WindowsCommunicationApps appears to be linked to the Mail app/ Outlook UWP app built into Windows 11. Attached below is the Values section for that field if you still need it image

reece394 avatar Aug 10 '25 13:08 reece394

@ogmini Did you get it sorted okay? WindowsCommunicationApps appears to be linked to the Mail app/ Outlook UWP app built into Windows 11. Attached below is the Values section for that field if you still need it image

Yup, I did find it. Should have left previous post instead of deleting it.

I see the 8 bytes we'd expect for a FILETIME. Which would typically give us the number of ticks. In your example and mine:

Hex Int64 / Ticks FILETIME Expected
A0-8B-6C-E9-41-B1-DB-08 638298668850252704 09/09/3623 14:34:45 09/09/2023 14:34:45
60-AC-7A-BF-59-2E-D8-08 637310310272380000 07/22/3620 16:10:27 07/22/2020 16:10:27

The next 4 are the timestamp and that works as expected.

My earlier datetime theory doesn't make sense now that I'm looking at it. Unless they're applying some really wacky offset? Or this is being stored as a Win32 FILETIME.

ogmini avatar Aug 10 '25 13:08 ogmini

~~Ok, it is being stored as a Win32 Filetime and not the Unix Filetime. That is really weird...~~

EDIT They are being stored as Windows FILETIME or DateTime.Ticks.

image

I'm on the fence about how to represent this value in the plugin. Options that I can think of:

  1. ~~Show Unix Filetime, Win32 Filetime, and the int64~~
  2. Have the plugin do some sanity checks on the Datetime and pick the most likely value

EDIT They are being stored as Windows FILETIME or DateTime.Ticks.

ogmini avatar Aug 10 '25 14:08 ogmini

My earlier datetime theory doesn't make sense now that I'm looking at it. Unless they're applying some really wacky offset? Or this is being stored as a Win32 FILETIME.

@ogmini I am wondering if it is something to do with this https://learn.microsoft.com/en-us/uwp/api/windows.foundation.datetime?view=winrt-26100 where WinRT seems to deviate slightly from FILETIME. Haven't looked too much into it but thankfully as you mention earlier we do still have the other timestamp to fall back on as unlike other registry hives each value has its own unique timestamp

reece394 avatar Aug 10 '25 14:08 reece394

My earlier datetime theory doesn't make sense now that I'm looking at it. Unless they're applying some really wacky offset? Or this is being stored as a Win32 FILETIME.

@ogmini I am wondering if it is something to do with this https://learn.microsoft.com/en-us/uwp/api/windows.foundation.datetime?view=winrt-26100 where WinRT seems to deviate slightly from FILETIME. Haven't looked too much into it but thankfully as you mention earlier we do still have the other timestamp to fall back on as unlike other registry hives each value has its own unique timestamp

Ah-ha! It is less weird to me now after reading that documentation you linked. My testing application is written in C#/.NET. The difficulty still remains that there is no way for the plugin to tell which one is being used purely by looking at the settings.dat file. This wouldn't be a problem for the native application as it would be the only one reading this file and would already know how to handle it.

@AndrewRathbun - any recommendations on a best practice for this situation?

  • ~~Show Unix Filetime, Win32 Filetime, and the int64~~
  • Have the plugin do some sanity checks on the Datetime and pick the most likely value
  • Show the int64 and let the analyst do the work

EDIT They are being stored as Windows FILETIME or DateTime.Ticks.

One quick sidenote, I have seen datetimes stored as:

  • RegUwpInt64
  • RegUwpString

For example, Windows Photos has these values:

image

ogmini avatar Aug 10 '25 14:08 ogmini

@ogmini I would be leaning more towards giving the value and then having the analyst parse it for accuracy. I know that is less convenient but seems like the most reliable solution in this case due to the different ways that field is used. Looks like they threw standards out the window when they used these 😂 no consistency in values and how they are used whatsoever between the applications. I know in RECmd Batch there is the BinaryConvert option in the rules which may lead to a potential way out for that but I am not sure how that interacts with RegistryPlugins. (Might expect the functionality to be integrated to use that rather than a plugin). You have the DataInterpreter in RegistryExplorer but it seems to be missing the correct interpreted time for that one.

reece394 avatar Aug 10 '25 14:08 reece394

@reece394 that makes sense. One argues an analyst should be comfortable recognizing the integers and knowing how to convert them appropriately. I added a "Notes" column to the plugin to give some guidance.

DateTime.Ticks image

FILETIME image

Array image

RegUwpDateTimeOffset value is still an Int64 that could either represent:

  1. A Windows Filetime that counts the number of 100-nanosecond intervals since January 1, 1601 (UTC)
  2. A DateTime.Ticks that counts the number of 100-nanosecond intervals since January 1, 0001

Just for future notes. Some handy online calculators:

  • https://www.datetimetoticks-converter.com/ DateTime.Ticks
  • https://ogmini.github.io/FILETIME_Converter_Page/ - FILETIME

ogmini avatar Aug 10 '25 18:08 ogmini

FYSA, most, if not all of the plugins in the repo are <TargetFramework>netstandard2.0</TargetFramework>, but this one is <TargetFramework>net9.0</TargetFramework>. I'm confirming with @EricZimmerman but I'm 99% sure we're going to want to change this to netstandard2.0 so the plugin can work on all versions of Registry Explorer (.NET 4, 6, and 9).

If I'm talking out of school here, please correct me, but just something I noticed!

AndrewRathbun avatar Aug 18 '25 16:08 AndrewRathbun

Yes net standard 2

EricZimmerman avatar Aug 18 '25 16:08 EricZimmerman

Easy enough change.

ogmini avatar Aug 18 '25 17:08 ogmini

Downgraded to .Net Standard 2.0 and tested on my side. No changes to code except me thinking I couldn't use the Linq and realizing I didn't have it in the namespace.

ogmini avatar Aug 18 '25 23:08 ogmini

@EricZimmerman tested and validated that this works

AndrewRathbun avatar Aug 19 '25 02:08 AndrewRathbun

I finally got a chance to test this out with RECmd. I noticed a few issues with the plugin when using it on a batch file. I implemented DateTime.Ticks support in RECmd to see how it interacted with the plugin and things did not go well.

Adding the following in the DFIRBatch File

    -
        Description: WindowsCommunicationApps
        HiveType: settings
        Category: User Activity
        KeyPath: Test\LocalState\ConfigSettings
        ValueName: LastCompletedFirstRunTime
        IncludeBinary: true
        BinaryConvert: DATETIMETICKS
        Recursive: false
        Comment: "DATETIMETICKS TEST"

Without the plugin the Date Decodes correctly and produces only 1 Value as expected: image

With the plugin it completely ignores the ValueName I have specified and outputs all values in the ConfigSettings Key image

Even when you take out the ValueName, IncludeBinary and BinaryConvert options ValueData1 only shows the ValueType and ValueData2 and ValueData3 are blank.

ValuesOut.cs Will need adjusted with ValueData1 just having the raw value with no comments? and then ValueData2 and 3 maybe having ValueType and the Timestamp for each value attached to each maybe as RECmd only currenlty shows last write timestamp of the key and not the individual values

        public string BatchValueData1 => $"ValueType: {ValueType}";
        public string BatchValueData2 => "";
        public string BatchValueData3 => "";

@ogmini can adjust the output and that should fix part of the problem but any ideas @EricZimmerman and @AndrewRathbun why my specifying of a value gets ignored when a plugin is used?

reece394 avatar Aug 30 '25 15:08 reece394

I finally got a chance to test this out with RECmd. I noticed a few issues with the plugin when using it on a batch file. I implemented DateTime.Ticks support in RECmd to see how it interacted with the plugin and things did not go well.

Adding the following in the DFIRBatch File

    -
        Description: WindowsCommunicationApps
        HiveType: settings
        Category: User Activity
        KeyPath: Test\LocalState\ConfigSettings
        ValueName: LastCompletedFirstRunTime
        IncludeBinary: true
        BinaryConvert: DATETIMETICKS
        Recursive: false
        Comment: "DATETIMETICKS TEST"

Without the plugin the Date Decodes correctly and produces only 1 Value as expected: image

With the plugin it completely ignores the ValueName I have specified and outputs all values in the ConfigSettings Key image

Even when you take out the ValueName, IncludeBinary and BinaryConvert options ValueData1 only shows the ValueType and ValueData2 and ValueData3 are blank.

ValuesOut.cs Will need adjusted with ValueData1 just having the raw value with no comments? and then ValueData2 and 3 maybe having ValueType and the Timestamp for each value attached to each maybe as RECmd only currenlty shows last write timestamp of the key and not the individual values

        public string BatchValueData1 => $"ValueType: {ValueType}";
        public string BatchValueData2 => "";
        public string BatchValueData3 => "";

@ogmini can adjust the output and that should fix part of the problem but any ideas @EricZimmerman and @AndrewRathbun why my specifying of a value gets ignored when a plugin is used?

Hmm any chance you stepped through it to see where it falls apart? I probably can't get to this until after the kids go to bed, if I'm lucky.

AndrewRathbun avatar Aug 30 '25 15:08 AndrewRathbun

@AndrewRathbun I think I traced this to BatchDumpKey

if (key.DisablePlugin == false && pluginsToActivate.Count > 0)

Reading the code it seems to process anything that the plugin specifies and because this plugin retrieves all values that is probably why it is ignoring the ValueName field. If we told it to only look at the ValueName field here I think this may break other plugin outputs in RECmd so we would have to be careful but we may be able to do something like adding an if statement to check if the ValueName exists?

(Code didn't work sadly :( But I think I am on the right sort of lines)

It seems like the plugins are ran first before BuildBatchCsvOut which does the BinaryConvert stuff hence it never hitting that code

Using DisablePlugin true fixes the problem but means I can't take advantage of the ValueData2 and 3 fields when ogmini fixes the BatchValue bits.

    -
        Description: WindowsCommunicationApps
        HiveType: settings
        Category: User Activity
        KeyPath: Test\LocalState\ConfigSettings
        ValueName: LastCompletedFirstRunTime
        DisablePlugin: true
        IncludeBinary: true
        BinaryConvert: DATETIMETICKS
        Recursive: false
        Comment: "DATETIMETICKS TEST"
    -
image

reece394 avatar Aug 30 '25 16:08 reece394

I'll take a look when I get a chance. Thanks for testing!

ogmini avatar Sep 01 '25 14:09 ogmini

Pushed up an alternative pull request there that puts the code into the Registry library directly. Offers better compatibility with RECmd than a plugin but haven't implemented the date parsing as I am not sure the best way to surface it yet. This seems the best path for RECmd at least but open to opinions on it

reece394 avatar Sep 08 '25 21:09 reece394

I don't have a problem with common functionality being added to recmd but consider additional common code to the base plugin as well, especially if it's static methods etc.

EricZimmerman avatar Sep 09 '25 12:09 EricZimmerman

Just getting back to this, I might poke you @reece394 for some more details/help.

ogmini avatar Oct 21 '25 15:10 ogmini

Sounds good to me. I feel like we have a good compromise. This plugin should be used in Registry Explorer as it additionally parses the per value timestamps and we can keep the plugin disabled in RECmd as the key bit for those is the keys and values which were already integrated into the Registry Library that RECmd uses

reece394 avatar Oct 21 '25 16:10 reece394

Is there a way to mark a plugin as not usable for RECmd?

ogmini avatar Oct 21 '25 18:10 ogmini

Just delete it from recmd

EricZimmerman avatar Oct 21 '25 18:10 EricZimmerman

The examiner could manually delete it, or we could simply ensure that the plugin is never summoned in the production DFIRBatch file, which is straightforward and has past precedent with a select few other plugins.

AndrewRathbun avatar Oct 21 '25 18:10 AndrewRathbun

Funny enough there is the DisablePlugin: true line if you look above that works well too

reece394 avatar Oct 21 '25 18:10 reece394

Hey now! Forward thinking

EricZimmerman avatar Oct 21 '25 18:10 EricZimmerman