
User Access Logging and KStrike
Harnessing UAL and KStrike during your incident response investigations.
Quick Links
· UAL Logs
· KStrike
· Analysis
· Other bits of info
∘ Presentations
∘ Alternative parsing options
∘ ESE database recovery and repair
∘ Roles and GUIDs
Background
I came across this forensically useful Windows feature called User Access Logging (UAL), while performing an investigation related to the SolarWinds breach at that time.
Back then, UAL proved to be an indispensable source of information, offering insights and details that were instrumental in our investigation efforts. To this day, UAL continues to be an invaluable resource in my work. It consistently plays a pivotal role in identifying systems accessed by threat actors and aiding in the tracking of lateral movement activities.
In this article, I aim to revisit and delve deeper into the significance of User Access Logging in DFIR. I will share my experiences, insights, and practical tips on how to effectively harness this feature for your own investigations.
Brief overview of Windows UAL
User Access Logging (UAL) is an integral feature in Windows Server 2012 and later versions (currently in Server 2022), designed to help server administrators track unique client requests for various services and roles. UAL is enabled by default, active on first server start-up, and operates with minimal configuration options.
UAL archives records up to two years, backing it up daily. This is aside from keeping the current year data, thus potentially having up to 3 years of data. It’s worth noting, UAL logs can be found in volume shadows if enable on a server (that’s going to be rare, though), potentially adding more historical value.
In high-volume environments, UAL has certain limitations, like a maximum of 65,535 accesses recorded per day. It can also be turned off for privacy or operational reasons using the Services console, command line, or PowerShell cmdlets.
For addition details, see Microsoft’s Learn pages here and here!
Benefits to investigations
UAL logs can be a valuable asset in incident response investigations due to the data it provides about users, devices, and activities on Windows Servers. Here are a few of the benefits:
- Tracking User Activity: UAL logs every instance of user access to roles and services on the server. This can help identify unauthorized access or unusual patterns of user behavior. Particularly, it can be helpful to assist in TA lateral movement analysis and potentially be available even when the Windows event logs are not.
- Temporal Analysis: UAL provides certain timestamped data, enabling investigators to construct a timeline of events. This is crucial in understanding the sequence of actions during an incident and correlating them with other events in the network.
- IP addresses: UAL logs include network address information, which can be used to trace the source of access requests. This can be crucial for identifying the location of attackers or compromised systems within the network.
- Hostname to IP mapping: If the UAL logs are from server with the DNS feature installed, there is additional and specific hostname to IP address mapping information over time.
UAL Logs
Location
UAL logs can be found only on Windows Servers, from 2012 and up (currently in Server 2022). For each of these systems, the UAL logs can be found in the SUM here:
%SystemRoot%\System32\Logfiles\SUM\

These files are each part of an Extensible Storage Engine (ESE) database system utilized here for UAL. We’ll talk about some of these files, though I’ll leave it to Microsoft to go over the database details here.
- mdb — The are the main ESE database files for User Access Logging. (Other ESE databases may have the .edb extension.)
Current.mdb : The database for the current year
{GUID}.mdb : Archived data from the Current.mdb, and previous years
SystemIdentity.mdb : Contains role information and system details
- svc*.log— These are ESE transaction logs.
Format : <base><generation-number>.log
Svc.log
Svc00000.log
Svc#####.log
- jfm — Flush Map files ESE uses for protection against lost writes to the mdb files. These will have the same name as the mdb files, but are not necessary for our purposes. Just make sure to grab the correct files.
- chk — These checkpoint files essentially help ESE know where it left off when committing information to the mdb files.
- For more details on ESE file types, take a look at this Microsoft documentation.
Oh and btw, SUM stands for Software Usage Metrics.
Tables
The follow chart shows the UAL databases and the tables of interest that each contain.

Columns
The following chart lists out the columns available in each of the UAL database files.

KStrike
Brian Moran is the mastermind behind KStrike. The need for writing this tool sprouted from an investigation we both worked on. The discovery of the User Access Logs, their tracking of user access to systems, maintaining historical records of IP address assignments, and how far back these logs go, made this tool extremely valuable for our investigation.
Getting things ready
For this demonstration, I will be using WSL2 on Windows 11 and installing SIFT-Workstation within the WSL2 instance.
- This is not required, I’m just not good at compiling libesedb, though SIFT comes with it! I found this simple walk-through, by Ivan Melnik, for how to set up WSL with SIFT.
You can download the KStrike tool along with some sample data, at Brian’s GitHub page:
I’ve added KStrike to my tools folder and added the contents of the SUM folder, from my lab server, to exports.

I’ll be using Python 3 for examples here. When first running KStrike, you can see Brian’s amazing artistic skills at work.

KStrike does not require the ESE databases to be in a clean state. However, I’ve provided the recovery and repairs steps later in this article. Use database recovery as it suits your needs.
KStrike will only parse the Current.mdb and the {GUID}.mdb files. This tool is not meant for the SystemIdentity.mdb file, as it has minimal value compared to the aforementioned files.
Usage: KStrike.py Current.mdb > SYSNAME_Current.txt
KStrike.py "{GUID}.mdb" > SYSNAME_GUID.txt
Parsing
Now that we have KStrike, an environment to run it in, some UAL data, and confirmed KStrike is working here. Let’s parse some data.
I’m running the following command first, to parse the Current.mdb file:
python3 KStrike.py ~/exports/Sum/Current.mdb > ~/exports/dc-current.txt

Here is a snippet of the dc-current.txt output file:

I’ll let Brian tell you at (this link), about how best to load this data into Excel. Though essentially, use UTF-8, double pipe delimiters, and format fields as desired.
Here is a snippet of how I loaded my file into Excel.

Output explained
There are several columns from the UAL databases that Brian is pulling data from. Here are the columns:
- TenantId — TenantID or InvocationID attribute
- TotalAccesses — Incremental count of device accesses for a particular client device
- InsertDate — First date and time (UTC) seen for the client record
- LastAccess — Last date and time (UTC) seen for the client record
- RawAddress — Address format from the database
- ConvertedAddress (Correlated_HostName(s)) — Converted address and matching host from the UAL DNS table (if present)
- AuthenticatedUserName — User name of the client that accompanies the UAL entry
- DatesAndAccesses — Count of accesses for the day of the year (UTC)
Analysis
Now that we have this data, what do we do with it?
Host to IP mapping
Taking just the ConvertedAddress column, separating that out and de-duping can provide a nice simple view of IP addresses associated with hostnames on the domain. This can be expanded out to include the InsertDate and LastAccess date to get information over time and perhaps get insight into IP address changes over the last 3 years.

User names
We also get a nice list of user names that authenticated with each role that is tracked. Look for known compromised accounts and also used this to help understand which accounts may be affected in a breach.

For example, if “gothamlab\TheJoker” shows up, we might want to see when that account was created and what permissions it has!
Machine accounts
Looking at the AuthenticatedUserName column, you will see many entries related to machine accounts, identified by the “$” appended to the hostname (on the right).

One thing to notice here is that the machine account entries (right) line up with the IP and Hostname (left). This is helpful when you’re parsing a UAL database from a server without DNS turned on. Without DNS turned on, it’s not as easy to get the full host to IP mapping mentioned above. However, considering the machine account IPs will correlate to their own IP address, you can still get host details about these IP addresses.
Insert date, last access, total accesses
The “TotalAccesses” column is simply a tally of the accesses, each day, for that role.

“InsertDate” is associated with the first time a user authenticated with the particular role.
“LastAccess” is the last time a user authenticated with the particular role.
Keep in mind the UAL databases only contain data for a particular year. Such that there may be a database for 2022, 2023, 2024.
Of note here, it may be useful to perform some statistics on what looks like normal, compared to suspicious activity. It may be possible to identify suspicious activity related to network scans or perhaps a large amount of access to certain systems that a user does not typically access.
Other bits of info
Presentations
Check out the presentations that Brian and I put together in 2021 at the SANS Virtual Summit and at virtual OSDFCon.
SANS Summit 2021
OSDFCon 2021 — (Slides)
Alternative parsing options
Since this UAL artifact and KStrike tool have come into scope as part of regular investigations, there have been additional parsing implementations. A few public options that I’m currently aware of are:
- Autopsy Plugin — By markmckinnon
- SumECmd — By Eric Zimmerman & Andrew Rathbun
- Velociraptor Artifact — By Mike Cohen
ESE database recovery and repair
Though KStrike does not require these databases to be in a clean state. It’s worth mentioning the recovery and repair steps for these databases, if your situation will benefit from this.
Before performing these steps:
- Make sure you’re working on a copy of the files located in the SUM directory, shown above.
- Use a version of the Windows esentutl.exe tool that is the same or newer than the esentutl.exe tool on the system the logs were copied from.
Step 1: Recovery /r
Syntax : esentutl /r <3-character logfile base name> [<options>]
Usage : esentutl /r svc /i
Esentutl, using the command above, will work with the “svc” named base files in the SUM directory to perform recovery operations and set databases in the current directory to a clean-shutdown state. The “i” option will ignore mismatched/missing database attachments.

Step 2: Repair /p
Syntax : esentutl /p <database name> [options]
Usage : esentutl /p Current.mdb [options]

When running the repair operations, the process will create a temporary database, as shown in the image above. Also, a pop-up warning will confirm you want to proceed with the repair.

Once the repair is completed, you’ll see a message like the one below showing “Operation completed successfully.”

If you’re experience issues with the repair, confirm you’re using the esentutl utility on a Windows system that is the same or newer then where the UAL database files originated.
Registry data
One known registry key related to UAL is this WMI Autologger key. Here there is mostly configuration information.
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\WMI\Autologger\SUM
However, if you’re interested in performing some of your own research. The registry here can be helpful. Microsoft documents (here) an adjustment you can make here to increase the polling interval, so data is more readily available during testing.
REG ADD HKLM\System\CurrentControlSet\Control\WMI\AutoLogger\Sum /v PollingInterval /t REG_DWORD /d 60000 /F
Adjusting down to “60000” will get the interval down to one minute.

Event logs
UAL service stops and starts are viewable in the System.evtx log.
Event ID 7036:
- The User Access Logging Service service entered the stopped state.
- The User Access Logging Service service entered the running state.

PowerShell and UAL
Microsoft has a list of PowerShell cmdlets for UAL documented here.
Roles and GUIDs
Brian Moran has a list of known Roles and their associated GUIDs, that he maintains within the KStrike script itself. Here is the current list, as well:
C50FCC83-BC8D-4DF5-8A3D-89D7F80F074B : Active Directory Certificate Services
AD495FC3-0EAA-413D-BA7D-8B13FA7EC598 : Active Directory Domain Services
4AD13311-EC3B-447E-9056-14EDE9FA7052 : Active Directory Lightweight Directory Services
B4CDD739-089C-417E-878D-855F90081BE7 : Active Directory Rights Management Service
910CBAF9-B612-4782-A21F-F7C75105434A : BranchCache
48EED6B2-9CDC-4358-B5A5-8DEA3B2F3F6A : DHCP Server
7CC4B071-292C-4732-97A1-CF9A7301195D : FAX Server
10A9226F-50EE-49D8-A393-9A501D47CE04 : File Server
C23F1C6A-30A8-41B6-BBF7-F266563DFCD6 : FTP Server
DDE30B98-449E-4B93-84A6-EA86AF0B19FE : MSMQ
BBD85B29-9DCC-4FD9-865D-3846DCBA75C7 : Network Policy and Access Services
7FB09BD3-7FE6-435E-8348-7D8AEFB6CEA3 : Print and Document Services
952285D9-EDB7-4B6B-9D85-0C09E3DA0BBD : Remote Access
2414BC1B-1572-4CD9-9CA5-65166D8DEF3D : SQL Server Analysis Services
BD7F7C0D-7C36-4721-AFA8-0BA700E26D9E : SQL Server Database Engine
D6256CF7-98FB-4EB4-AA18-303F1DA1F770 : Web Server
4116A14D-3840-4F42-A67F-F2F9FF46EB4C : Windows Deployment Services
1479A8C1-9808-411E-9739-2D3C5923E86A : Windows Server 2016 DatacenterRemote Desktop Gateway
D8DC1C8E-EA13-49CE-9A68-C9DCA8DB8B33 : Windows Server Update Services
90E64AFA-70DB-4FEF-878B-7EB8C868F091 : Windows ServerRemote Desktop Services
You can look up the Roles and GUIDs on servers with this PowerShell command. If you find new entries, feel free to share it with Brian via his GitHub page.
Get-UalOverview | Format-Table -Property GUID, RoleName

Wrapping it up
Thank you for taking the time to check out this post! As time permits, I’m also considering a follow-up post with additional use case examples.
Thank you much, to Brian Moran for his continued support and David Cowen for his mentorship, as well!
Fun with ChatGPT and KStrike!
I couldn’t go without trying this out!