CIA Triad #
Before we jump into the project let’s understand why something like a File Integrity Monitor is required, for this we will need to understand the CIA triad. The CIA triad is a fundamental model in information security that stands for Confidentiality, Integrity, and Availability. This project will focus on the Integrity part.
Integrity protects a file from being altered or tampered with, ensuring it’s accuracy and reliability.
All the code in this blog will be in this repository:
File Integrity Monitor #
Level 1: Hashing #
Hashing is a one-way function, The output for a specific input will always be the same, but we cannot derive the input from the output. Hashing is used to store passwords securely in databases. To further enhance security, a random salt is added to each password before hashing. This ensures that even if two users have the same password, their hashes will be different. Salting also helps protect against rainbow table attacks, making it more difficult for attackers to crack passwords, even if they know the hashing algorithm.
We will use the property that a hash derived from a file changes if the file’s contents change. This allows us to detect when a file has been modified, as any alteration in the file will result in a different hash, providing an alert when unauthorized modifications occur. We will also have alerts for file creation and deletion
This initial script is a Proof-of-concept, there are more efficient ways to implement this which we will look into later. For now we will keep it simple to understand the concept first.
When the script is first started there are 2 options for the user:
A) Collect new baseline: A baseline represents the original state of the files. This means the system will scan the files as they are now and save that information for future comparisons.
B) Begin Monitoring files with saved Baseline: The script starts monitoring the files with previously saved baseline.
You will find the Powershell, Bash and Python version of the script here:
All of these scripts function in the exact same way so feel free to follow along in whichever scripting language you are familiar with. All 3 of the scripts function in the same way on both Linux and Windows.
For the script to work make sure you have a folder called Files
containing the files to be monitored in the same folder as the script. The directory structure should look something like this:
Files
can be changed to anything in the script. If you want to install Powershell on Linux please refer this
Level 2: System calls #
We saw how we can use hashes to develop an FIM, now we will see how we can leverage system calls to come up with a more efficient solution. We will see how it is implemented in both Windows and Linux.
Windows #
In Windows, we can use the FileSystemWatcher
class, a .NET API built into Windows, to monitor file changes. Internally, it leverages underlying OS mechanisms like ReadDirectoryChangesW. Unlike Linux, where we can directly work with system calls, Windows abstracts these through APIs, which expose the underlying system functionality
- Logging: All the changes that occur to the files will be logged in baseline.log (Can be changed). The file is also limited to 5MB so that it does not get too large, a new file will be created once 5MB is reached.
- Resource Efficiency: Reduces CPU and memory usage by monitoring only active file changes rather than continuously scanning the filesystem. Also minimises overhead as it works in the background and only activates on specific file system events.
- Real-Time Monitoring: Our level 1 method can have a delay due to periodic scanning and hashing of files but in this method we get an immediate notification
- Event handling: Allows for precise event handling (e.g., distinguishing between file creation, modification, and deletion), hashing method can tell the file has changed but not how.
View the C# code here
Check the repository for the Visual Studio Solutions file and build it to get the compiled exe file.
Linux #
For the Linux version we can use inotify which is a system call which allows applications to watch for changes to files and directories.
It is possible to use it directly using C but we will use wrappers to use inotify in Bash and Python as it is much easier and let’s us focus on adding more features instead of re-inventing the wheel.
Bash #
First install inotify
# Ubuntu/Debian
sudo apt-get install inotify-tools
# Arch
sudo pacman -Syu inotify-tools
# Fedora
sudo dnf inotify-tools
Now get the code from my repository here
Make the script executable:
chmod +x FIM_Level-2_Linux.sh
Run it:
./FIM_Level-2_Linux.sh
Python #
Install inotify_simple :
pip3 install inotify_simple
Now get the code from my repository here
Execute the script:
python FIM_Level-2_Linux.py
╰(°▽°)╯
Pyinstaller #
Okay so here’s something I found really cool, Pyinstaller is a python package that converts a python script/application into a standalone executable. This standalone executable is Cross-platform and can run on machines without python installed!
The way it does this is by packaging the python interpreter along with our application and all it’s dependencies (inotify_simple in this case), let’s not get into the nitty-gritty of how it works and see how it’s done.
- Create a python virtual environment (this is not required but I recommend doing this to avoid issues with dependencies)
python -m venv myenv
Activate it:
# Linux/ macOS
source myenv/bin/activate
# Windows
myenv\Scripts\activate
- Install the dependencies
pip install inotify_simple
- Run pyinstaller
pyinstaller --onefile -p /home/aditya/Documents/python_FIM/myenv/lib/python3.12/site-packages ./FIM_Level-2_Linux.py
--onefile
- for creating a single file executable
-p
is the path where third-party libraries and packages are installed within the virtual environment
- Run the executable The executable will be in the dist folder
./FIM_Level-2_Linux
As we can see the script can be executed. Note that in this case the script will not be cross-platform as we use inotify which is only available on Linux.