Wazuh: File Integrity Monitoring

In this post, I show you how to configure and monitor File Integrity Monitoring (FIM) in Wazuh.
Wazuh: File Integrity Monitoring
In: Wazuh, SIEM, Defend, Home Lab

What is File Integrity Monitoring?

File Integrity Monitoring (FIM) is the process of monitoring for changes in the file system, such as file additions, deletions, or modifications. Wazuh's FIM solution – known as syscheck – can monitor the Windows Registry for changes as well.

File integrity monitoring - Capabilities · Wazuh documentation
User manual, installation and configuration guides. Learn how to get the most out of the Wazuh platform.

Syscheck can be configured to monitor various directories or files in several modes. You may want to use realtime monitoring on directories commonly abused by attackers, and scheduled for files or directories containing configuration files.

  • Scheduled
    • Monitor for changes at regular intervals
  • Real-time
    • Monitor for changes the moment they happen
  • Who-data
    • Monitor for changes the moment they happen (implies real-time)
    • Include audit info on the user making the changes
ℹ️
Every environment is different, so it's important to strategize a FIM paradigm that's suited to your needs.





Configuring FIM

Default Configurations

FIM is enabled by default on Wazuh Agent installations. There are default configurations depending on the operating system.

syscheck - Local configuration (ossec.conf) · Wazuh documentation
User manual, installation and configuration guides. Learn how to get the most out of the Wazuh platform.



Custom Configurations

The easiest way to push syscheck configurations to your agent is via Centralized Configuration (or shared configuration).

Centralized configuration (agent.conf) - Reference
User manual, installation and configuration guides. Learn how to get the most out of the Wazuh platform.
ℹ️
The core consideration with centralized configuration is the notion of precedence, as agent configurations in the ../shared/agent.conf file will take precedence over anything in the default ossec.conf file.

As mentioned before, Wazuh agents come configured with a default set of syscheck configurations in the default ossec.conf file. Therefore, anything you wish to keep from the default configuration should be added to the shared configuration.



Example Centralized Configuration

Default Group agent.conf

This is the standard shared configuration for the default group in Wazuh with the addition of some real-time directory monitoring configurations.

<agent_config os="linux">
	<localfile>
		<location>/opt/orbit/osquery_log/osqueryd.results.log</location>
		<log_format>json</log_format>
		<label key="log_source">osquery</label>
		<label key="osquery_log_type">differential</label>
	</localfile>
	<localfile>
		<location>/opt/orbit/osquery_log/osqueryd.snapshots.log</location>
		<log_format>json</log_format>
		<label key="log_source">osquery</label>
		<label key="osquery_log_type">snapshot</label>
	</localfile>
	<syscheck>
		<disabled>no</disabled>
		<!-- Real-time Monitoring -->
		<directories check_all="yes" realtime="yes">/tmp</directories>
		<directories check_all="yes" realtime="yes">/var/tmp</directories>
		<directories check_all="yes" realtime="yes">/home/*/.config</directories>
		<directories check_all="yes" realtime="yes">/home/*/.local/bin</directories>
		<directories check_all="yes" realtime="yes">/home/*/.local/share/powershell</directories>
		<directories check_all="yes" realtime="yes">/home/*/.ssh</directories>
		<directories check_all="yes" realtime="yes">/home/*/bin</directories>
		<directories check_all="yes" realtime="yes">/home/*/Code</directories>
		<directories check_all="yes" realtime="yes">/home/*/Desktop</directories>
		<directories check_all="yes" realtime="yes">/home/*/Documents</directories>
		<directories check_all="yes" realtime="yes">/home/*/Downloads</directories>
		<directories check_all="yes" realtime="yes">/home/*/Music</directories>
		<directories check_all="yes" realtime="yes">/home/*/Pictures</directories>
		<directories check_all="yes" realtime="yes">/home/*/Public</directories>
		<directories check_all="yes" realtime="yes">/home/*/Videos</directories>
		<directories check_all="yes" realtime="yes">/opt/</directories>
		<directories check_all="yes" realtime="yes">/var/opt</directories>
		<directories check_all="yes" realtime="yes">/var/www</directories>
		<directories check_all="yes" realtime="yes">/root</directories>
		<directories check_all="yes" realtime="yes">/usr/local</directories>
		<directories check_all="yes" realtime="yes">/srv</directories>
		<!-- Frequency that syscheck is executed default every 12 hours -->
		<frequency>43200</frequency>
		<scan_on_start>yes</scan_on_start>
		<!-- Directories to check  (perform all possible verifications) -->
		<directories>/etc,/usr/bin,/usr/sbin</directories>
		<directories>/bin,/sbin,/boot</directories>
		<!-- Files/directories to ignore -->
		<ignore>/etc/mtab</ignore>
		<ignore>/etc/hosts.deny</ignore>
		<ignore>/etc/mail/statistics</ignore>
		<ignore>/etc/random-seed</ignore>
		<ignore>/etc/random.seed</ignore>
		<ignore>/etc/adjtime</ignore>
		<ignore>/etc/httpd/logs</ignore>
		<ignore>/etc/utmpx</ignore>
		<ignore>/etc/wtmpx</ignore>
		<ignore>/etc/cups/certs</ignore>
		<ignore>/etc/dumpdates</ignore>
		<ignore>/etc/svc/volatile</ignore>
		<ignore>/opt/zeek/spool</ignore>
		<ignore>/opt/zeek/logs</ignore>
		<ignore>/opt/orbit/lenses</ignore>
		<ignore>/opt/orbit/osquery_log</ignore>
		<ignore>/opt/orbit/osquery.db</ignore>
		<ignore>/opt/orbit/staging</ignore>
		<ignore>/usr/local/owlh/src/owlhnode/conf</ignore>
		<!-- File types to ignore -->
		<ignore type="sregex">.log$|.swp$|.tif$|.png$|.jpg$|.gif$|.pid$|.lock$</ignore>
		<!-- Check the file, but never compute the diff -->
		<nodiff>/etc/ssl/private.key</nodiff>
		<skip_nfs>yes</skip_nfs>
		<skip_dev>yes</skip_dev>
		<skip_proc>yes</skip_proc>
		<skip_sys>yes</skip_sys>
		<!-- Nice value for Syscheck process -->
		<process_priority>10</process_priority>
		<!-- Maximum output throughput -->
		<max_eps>100</max_eps>
		<!-- Database synchronization settings -->
		<synchronization>
			<enabled>yes</enabled>
			<interval>5m</interval>
			<max_interval>1h</max_interval>
			<max_eps>10</max_eps>
		</synchronization>
	</syscheck>
</agent_config>
<agent_config os="windows">
	<!--PowerShell (https://github.com/OpenSecureCo/Wazuh/blob/main/PowerShell%20Logging) -->
	<localfile>
		<location>Microsoft-Windows-PowerShell/Operational</location>
		<log_format>eventchannel</log_format>
	</localfile>
	<localfile>
		<location>C:\Program Files\Orbit\osquery_log\osqueryd.results.log</location>
		<log_format>json</log_format>
		<label key="log_source">osquery</label>
		<label key="osquery_log_type">differential</label>
	</localfile>
	<localfile>
		<location>C:\Program Files\Orbit\osquery_log\osqueryd.snapshots.log</location>
		<log_format>json</log_format>
		<label key="log_source">osquery</label>
		<label key="osquery_log_type">snapshot</label>
	</localfile>
	<syscheck>
		<disabled>no</disabled>
		<!-- Real-Time Monitoring -->
		<directories check_all="yes" realtime="yes">%SystemDrive%/Temp</directories>
		<directories check_all="yes" realtime="yes">%SystemDrive%/Windows/Tasks</directories>
		<directories check_all="yes" realtime="yes">%SystemDrive%/Windows/Temp</directories>
		<directories check_all="yes" realtime="yes">%SystemDrive%/ProgramData</directories>
		<directories check_all="yes" realtime="yes">%SystemDrive%/Users/*/.ssh</directories>
		<directories check_all="yes" realtime="yes">%SystemDrive%/Users/*/Desktop</directories>
		<directories check_all="yes" realtime="yes">%SystemDrive%/Users/*/Documents</directories>
		<directories check_all="yes" realtime="yes">%SystemDrive%/Users/*/Downloads</directories>
		<directories check_all="yes" realtime="yes">%SystemDrive%/Users/*/Favorites</directories>
		<directories check_all="yes" realtime="yes">%SystemDrive%/Users/*/Links</directories>
		<directories check_all="yes" realtime="yes">%SystemDrive%/Users/*/Music</directories>
		<directories check_all="yes" realtime="yes">%SystemDrive%/Users/*/OneDrive</directories>
		<directories check_all="yes" realtime="yes">%SystemDrive%/Users/*/Pictures</directories>
		<directories check_all="yes" realtime="yes">%SystemDrive%/Users/*/Saved Games</directories>
		<directories check_all="yes" realtime="yes">%SystemDrive%/Users/*/Searches</directories>
		<directories check_all="yes" realtime="yes">%SystemDrive%/Users/*/Videos</directories>
		<directories check_all="yes" realtime="yes">%SystemDrive%/Users/*/Start Menu/Programs/Startup</directories>
		<directories check_all="yes" realtime="yes">%SystemDrive%/Users/*/AppData/Local/Temp</directories>
		<directories check_all="yes" realtime="yes">%SystemDrive%/Users/*/AppData/Local/Programs</directories>
		<directories check_all="yes" realtime="yes">%SystemDrive%/inetpub</directories>
		<!-- Files and/or Directories to Ignore -->
		<ignore>%SystemDrive%/inetpub/logs/</ignore>
		<ignore>%SystemDrive%/ProgramData/Microsoft</ignore>
		<ignore>%SystemDrive%/ProgramData/NoMachine/var/db</ignore>
		<ignore>%SystemDrive%/ProgramData/NoMachine/var/run</ignore>
		<ignore>%SystemDrive%/ProgramData/NoMachine/var/log</ignore>
		<ignore>%SystemDrive%/ProgramData/USOPrivate/UpdateStore</ignore>
		<ignore>%ProgramFiles%/orbit/lenses</ignore>
		<ignore>%ProgramFiles%/orbit/osquery_log</ignore>
		<ignore>%ProgramFiles%/orbit/osquery.db</ignore>
		<ignore>%ProgramFiles%/orbit/staging</ignore>
		<ignore>%ProgramFiles(x86)%/orbit/lenses</ignore>
		<ignore>%ProgramFiles(x86)%/orbit/osquery_log</ignore>
		<ignore>%ProgramFiles(x86)%/orbit/osquery.db</ignore>
		<ignore>%ProgramFiles(x86)%/orbit/staging</ignore>
		<ignore type="sregex">.tif$|.gif$|.swidtag$|.log1$|.log2$|.pid$|.lock$|.isfrozen$</ignore>
		<!-- Frequency that syscheck is executed default every 12 hours -->
		<frequency>43200</frequency>
		<!-- Default files to be monitored. -->
		<directories recursion_level="0" restrict="regedit.exe$|system.ini$|win.ini$">%WINDIR%</directories>
		<directories recursion_level="0" restrict="at.exe$|attrib.exe$|cacls.exe$|cmd.exe$|eventcreate.exe$|ftp.exe$|lsass.exe$|net.exe$|net1.exe$|netsh.exe$|reg.exe$|regedt32.exe|regsvr32.exe|runas.exe|sc.exe|schtasks.exe|sethc.exe|subst.exe$">%WINDIR%\SysNative</directories>
		<directories recursion_level="0">%WINDIR%\SysNative\drivers\etc</directories>
		<directories recursion_level="0" restrict="WMIC.exe$">%WINDIR%\SysNative\wbem</directories>
		<directories recursion_level="0" restrict="powershell.exe$">%WINDIR%\SysNative\WindowsPowerShell\v1.0</directories>
		<directories recursion_level="0" restrict="winrm.vbs$">%WINDIR%\SysNative</directories>
		<!-- 32-bit programs. -->
		<directories recursion_level="0" restrict="at.exe$|attrib.exe$|cacls.exe$|cmd.exe$|eventcreate.exe$|ftp.exe$|lsass.exe$|net.exe$|net1.exe$|netsh.exe$|reg.exe$|regedit.exe$|regedt32.exe$|regsvr32.exe$|runas.exe$|sc.exe$|schtasks.exe$|sethc.exe$|subst.exe$">%WINDIR%\System32</directories>
		<directories recursion_level="0">%WINDIR%\System32\drivers\etc</directories>
		<directories recursion_level="0" restrict="WMIC.exe$">%WINDIR%\System32\wbem</directories>
		<directories recursion_level="0" restrict="powershell.exe$">%WINDIR%\System32\WindowsPowerShell\v1.0</directories>
		<directories recursion_level="0" restrict="winrm.vbs$">%WINDIR%\System32</directories>
		<directories realtime="yes">%PROGRAMDATA%\Microsoft\Windows\Start Menu\Programs\Startup</directories>
		<ignore>%PROGRAMDATA%\Microsoft\Windows\Start Menu\Programs\Startup\desktop.ini</ignore>
		<ignore type="sregex">.log$|.htm$|.jpg$|.png$|.chm$|.pnf$|.evtx$</ignore>
		<!-- Windows registry entries to monitor. -->
		<windows_registry>HKEY_LOCAL_MACHINE\Software\Classes\batfile</windows_registry>
		<windows_registry>HKEY_LOCAL_MACHINE\Software\Classes\cmdfile</windows_registry>
		<windows_registry>HKEY_LOCAL_MACHINE\Software\Classes\comfile</windows_registry>
		<windows_registry>HKEY_LOCAL_MACHINE\Software\Classes\exefile</windows_registry>
		<windows_registry>HKEY_LOCAL_MACHINE\Software\Classes\piffile</windows_registry>
		<windows_registry>HKEY_LOCAL_MACHINE\Software\Classes\AllFilesystemObjects</windows_registry>
		<windows_registry>HKEY_LOCAL_MACHINE\Software\Classes\Directory</windows_registry>
		<windows_registry>HKEY_LOCAL_MACHINE\Software\Classes\Folder</windows_registry>
		<windows_registry arch="both">HKEY_LOCAL_MACHINE\Software\Classes\Protocols</windows_registry>
		<windows_registry arch="both">HKEY_LOCAL_MACHINE\Software\Policies</windows_registry>
		<windows_registry>HKEY_LOCAL_MACHINE\Security</windows_registry>
		<windows_registry arch="both">HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer</windows_registry>
		<windows_registry>HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services</windows_registry>
		<windows_registry>HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\KnownDLLs</windows_registry>
		<windows_registry>HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SecurePipeServers\winreg</windows_registry>
		<windows_registry arch="both">HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run</windows_registry>
		<windows_registry arch="both">HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunOnce</windows_registry>
		<windows_registry>HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunOnceEx</windows_registry>
		<windows_registry arch="both">HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\URL</windows_registry>
		<windows_registry arch="both">HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies</windows_registry>
		<windows_registry arch="both">HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Windows</windows_registry>
		<windows_registry arch="both">HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon</windows_registry>
		<windows_registry arch="both">HKEY_LOCAL_MACHINE\Software\Microsoft\Active Setup\Installed Components</windows_registry>
		<!-- Windows registry entries to ignore. -->
		<registry_ignore>HKEY_LOCAL_MACHINE\Security\Policy\Secrets</registry_ignore>
		<registry_ignore>HKEY_LOCAL_MACHINE\Security\SAM\Domains\Account\Users</registry_ignore>
		<registry_ignore type="sregex">\Enum$</registry_ignore>
		<registry_ignore>HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\MpsSvc\Parameters\AppCs</registry_ignore>
		<registry_ignore>HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\MpsSvc\Parameters\PortKeywords\DHCP</registry_ignore>
		<registry_ignore>HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\MpsSvc\Parameters\PortKeywords\IPTLSIn</registry_ignore>
		<registry_ignore>HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\MpsSvc\Parameters\PortKeywords\IPTLSOut</registry_ignore>
		<registry_ignore>HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\MpsSvc\Parameters\PortKeywords\RPC-EPMap</registry_ignore>
		<registry_ignore>HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\MpsSvc\Parameters\PortKeywords\Teredo</registry_ignore>
		<registry_ignore>HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\PolicyAgent\Parameters\Cache</registry_ignore>
		<registry_ignore>HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunOnceEx</registry_ignore>
		<registry_ignore>HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\ADOVMPPackage\Final</registry_ignore>
		<!-- Frequency for ACL checking (seconds) -->
		<windows_audit_interval>60</windows_audit_interval>
		<!-- Nice value for Syscheck module -->
		<process_priority>10</process_priority>
		<!-- Maximum output throughput -->
		<max_eps>100</max_eps>
		<!-- Database synchronization settings -->
		<synchronization>
			<enabled>yes</enabled>
			<interval>5m</interval>
			<max_interval>1h</max_interval>
			<max_eps>10</max_eps>
		</synchronization>
	</syscheck>
</agent_config>

Looking at this example configuration, you'll see that it does the following:

  • Breaks the configs up by operating system
    • Linux
    • Windows
  • Establishes realtime monitoring with check_all="yes" on some directories that are commonly abused by attackers
    • realtime allows collection of file additions, modifications, and deletions as they happen
    • check_all allows collection of MD5, SHA1, and SHA256 file hashes of any new, modified, or deleted files
  • Keeps the default configurations shipped by the Wazuh team intact



Getting this default configuration deployed is a matter of choosing the group to deploy this to. I want this configuration to be applied to all agents. So, I will add this configuration to the default group.

Choose Groups
Click the pencil icon next to the default group
Paste the configuration into the editor and click save

Now, the Wazuh Manager server will push the configuration to your registered agents and the agents will restart and adopt their new configuration.





Monitoring FIM Alerts

At the Wazuh Dashboards home screen, choose the Integrity Monitoring module to be brought to the Integrity Monitoring Dashboard.

Example dashboard of alerts over time

Click the Events tab to see the actual FIM events and drill down into the alerts.

Filtering by rule description can help you target specific events
Example File added to the system alert





Extending FIM Capabilities

One obvious way you can complement FIM is by utilizing the file hashes that are generated by syscheck . Wazuh is modular and extensible and already has integrations for YARA and VirusTotal. Once added, you could use those extensions to check file hashes for known signatures.

Detecting malware using Yara integration - Proof of Concept guide
User manual, installation and configuration guides. Learn how to get the most out of the Wazuh platform.
Detecting and removing malware using VirusTotal integration
User manual, installation and configuration guides. Learn how to get the most out of the Wazuh platform.





Wrapping Up

In this post, we discussed:

  • Wazuh FIM and some of its capabilities
  • Configuring FIM
  • Monitoring FIM alerts
  • Extending FIM capabilities

If you've read up until this point, thank you for checking out my blog. I do hope it has been helpful for you.

More from 0xBEN
Table of Contents
Great! You’ve successfully signed up.
Welcome back! You've successfully signed in.
You've successfully subscribed to 0xBEN.
Your link has expired.
Success! Check your email for magic link to sign-in.
Success! Your billing info has been updated.
Your billing was not updated.