Hopefully you’re caught up with our previous post, where we upgraded the hashing and added a way to collect the bytes of our files. In this post, we’ll be starting to clean up the code, as well as implementing a database and config file to be used for the remainder of the project. NOTE: Due to the depreciation of Python 2.7, we’ve swapped to Python3. The updated code is near identical except for print commands

Configure the Database

In the current state of the code, every file, hash, and byte are all being held in memory while the program runs. Our goal is to eventually rely on a single version of each file that can be carried over from one scan to the next, acting as a master backup. To accomplish this, we’ll need to set up a database to store the data.

Walk-through:

Adding Paths to Monitor

Now that we’ve got our database set up, we’ll have to add our paths from the monitor variable used in previous scripts. I’m using SQLiteBrowser to execute these Insert statements, but feel free to use whatever works best for you or even add them to your code.

Walk-through:

These scripts are just basic Insert statements. They tell the database what table (Monitor) to add the data to, which fields (Path, Recursive) are being populated, and the values being entered. Notice that we left out the ID field, as it was set to AUTOINCREMENT in our previous step. We’ll be writing a lot more SQL throughout this post, so take a look at some of these tutorials in case you want to learn more about how it works.

Initialize Monitored Files

The first time we run our File Integrity Monitor, it’ll need to set up a baseline to work with. This includes identifying all the files we’ll need to monitor, their hashes to compare against, and a base64 encoded version of their contents we can eventually restore from.

Walk-through:

Create Config File

Another feature we’ll be adding is the ability to read from a configuration file. This is where we can store customizable values to change how the tool behaves, without having to modify the source code.

Walk-through:

We can name configuration categories by placing them between [], such as the [Timer] example above. Any configurations belonging to that category will be placed on the lines below it, and be read until another category is named, or the end of the file is reached. For this simple config file, we’ll just add a Wait, with the value of 1. Save the file as FileIntegrityMonitor.ini in the same directory as our script.

Parsing Config Files

With the configuration file created, we can test our ability to read from it. This is just a basic demonstration of the functionality we’ll be adding to the larger script.

Walk-through:

Output:

ConfigParser

Putting It All Together

Taking all of our changes, we’re able to update the previous version of the tool to include a local database for storage, a getHash() function, and the ability to read settings from a configuration file. Lets go over those changes here.

Walk-through:

Conclusion

This wraps up part 3 of building our File Integrity Monitor. We’ve added not only the ability to read configurations from a file, but also implemented data storage allowing us to store hashes between runs and pave the way for future features such as data recovery. In the next post, we’ll be looking at setting up some alerting for when file changes take place, see you then!