How to Set up Windows File Integrity Monitoring Using Osquery and Kolide

Using the ntfs_journal_events table in Osquery 4.2.0

Fritz Ifert-Miller

The Wait for Windows FIM Is Over!

Prior to Osquery 4.2.0, Osquery’s FIM capabilities only worked on macOS and supported version of Linux. To fill this gap, Trail of Bits engineer @woodruffw created a new virtual table called ntfs_journal_events to finally bring basic FIM capabilities to osquery on Windows.

In this tutorial, we will take a look at how you can use Kolide’s SaaS app (K2), to configure and ingest ntfs_journal_events output.

What You Will Need

  1. A Kolide account. You can learn more about our Device Trust solution here.
  2. A Windows 10 device enrolled in K2 with Osquery 4.2.0 or greater.
  3. Physical or remote access to the Windows 10 device so that you can generate events to monitor.

Osquery FIM Basics

The FIM in osquery is composed of two distinct pieces:

  • A FIM category which defines monitored paths. (eg. C:\Users\fritz\Downloads)
  • An events table query which populates results. (eg. SELECT * FROM ntfs_journal_events;)

Kolide K2 makes it easy to get up and running with the osquery FIM with minimal configuration. Let’s setup a basic FIM configuration to monitor the changes of the User’s Downloads folder on a Windows device.

To do so we will need to perform three easy steps:

  1. Enable the osquery Options for Windows events.
  2. Define a FIM category.
  3. Write an ntfs_journal_events query.

Enabling Windows Events

To use the FIM we will first need to Enable the NTFS Event Publisher by going to the Osquery Settings page and setting the dropdown state to true.

A screenshot displaying the osquery setting within the Kolide app.

Define a FIM Category

Next, we will configurea FIM category. A FIM category defines a watched path, or set of paths, which will be flagged as the target of our events query.

FIM categories support the usage of wildcards, to accommodate relative paths that may be different across devices. For example watching directories within a User directory:


All of these directories can be distilled down to a single relative path using the following wildcard approach:


A trailing slash or trailing %% wildcard should NOT be used when defining paths or you will not recursively search subdirectories.

A screenshot displaying the window that is presented when creating a new FIM category.

We can create a new FIM Category by navigating to: Osquery Settings/FIM Categories and then clicking on the Add New FIM Category button. We can then name our category and define its watched paths.

Write an ntfs_journal_events Query

A screenshot displaying the sidebar window that populates when writing a ntfs journal events entry.

The last piece needed before we can start emitting data is a valid osquery SQL query to populate results. We will need this query to run on a recurring schedule which we can configure by including it in an osquery Query Pack.

  1. Create a new Query Pack by going to Log Pipeline/Osquery Packs
  2. Click the button Add Pack > New Empty Pack
  3. Name your pack and select Windows as the Platform

Once we’ve created our Query Pack, we can add our query to it:

  1. Within the new pack Click the button labeled Add New Query
  2. Type a name for your query
  3. Add the following query: SELECT * FROM ntfs_journal_events;
  4. Select Windows for Platform
  5. Configure an interval (3600 is the default, which is every hour but we suggest choosing a shorter interval like 10s so that you can verify everything is working)
  6. Choose Diff (additions only) as the log type. (Evented tables in Osquery are different from other tables in that diff removals and snapshot results are not semantically meaningful.)
  7. Click Save.

Viewing Results of Your FIM Configuration

Now that you have your new FIM configuration setup, you can test it by downloading some files to your test Windows device. If you set a frequent interval for your ntfs_journal_events query, you should start seeing results quickly once you perform any actions that trigger the FIM.

Results can be previewed in Kolide’s Live Log Viewer. This viewer listens for all logs emitted by the queries in your pack schedule and allows you to preview the output of your configured Query Packs and confirm that osquery is emitting the desired output.

Let’s take a look at what we have got so far by renaming and changing the contents of a file:

A screenshot displaying the Kolide live viewer after renaming and changing the contents of a file.

As we can see we have two actions recorded by osquery a FileRename_NewName and a FileOverwrite.

Today the ntfs_journal_events table can emit one of thirty-two distinct events.

Setting a Log Destination

Now that we’ve generated useful logs, Kolide enables you to forward them to any valid log destinations. For more information on supported Log Destinations and how to configure them, please refer to our help documentation.

Nuances to Be Aware of

There are a couple of items to consider while configuring your FIM ingestion rules.

Wildcard behavior

Since the FIM supports file GLOBs you may be tempted to specify something like C:\Users\%\Downloads\%% in your FIM category. While this doesn’t cause errors, specifying this way, in-lieu of monitoring the directory itself, may result in unexpected behavior like the following:

  1. Osquery agent retrieves FIM configuration
  2. Recursively searches paths specified by the FIM category (eg. C:\Users\%\Downloads\%%)
  3. Registers each file found via that pattern to be watched for changes.

This means that files created after FIM configuration retrieval (during which, files are registered to be watched) will be ignored by the FIM.

Service restarting

In our testing we have found that you may need restart the Kolide Launcher after enabling the NTFS Event Publisher from the K2 Osquery Options screen. To restart the service, simply open the Services manager, right-click the service named LauncherKolideK2Svc and press Restart.

Further Reading & Resources

Get Started Using the Windows FIM in Osquery Today

Kolide, our Device Trust solution, is the easiest to use and most advanced osquery fleet manager available today.

If you’d like to read more osquery content like this, sign up for our biweekly newsletter.

Share this story:

More articles you
might enjoy:

Deep Dives
Are Your Employees Slack Messages Leaking While Their Screen Is Locked?
Fritz Ifert-Miller
How to Read Nested Complex Plists in Osquery
Fritz Ifert-Miller
Deep Dives
Why You Can't Trust Your NULLs in Osquery
Fritz Ifert-Miller
Watch a Demo
Watch a Demo