PHPChangedBinaries is a simple server monitoring script. It's designed and exists to do one thing - detect and notify when system files change.
I've been running a very similar script for years, but in the wake of CDorked/DarkLeech decided it needed a refresh. The script works by generating checksums for all files within pre-configured paths (you can add more through the configuration file). These are then checked against a stored hash to see if anything has changed - if it has, the system admin is alerted.
Just download and extract the zip file (coming soon), or clone from the PHPChangedBinaries GitHub Repo.
Mode of Operation
There are two main modes of operation - LocalDB and RemoteHashStore. The default behaviour is LocalDB.
When configured to use a local database, generated hashes are stored on the server being checked. This leads to a much faster check, and removes the reliance on a remote API, but does leave the risk that an attacker could tamper with the stored hashes.
It also means that certain additional features, such as check-in periods won't be available.
RemoteHashStore is an inexpensive subscription service, providing a number of key security enhancements which just can't be implemented when storing hashes locally.
The service is an API used to store and check hashes. When enabled, the service will generate all notification emails and can also be configured with a 'check-in' period. This tells the API to send a warning email if a server hasn't checked hashes within a certain time period (as this may be indicative of an attacker tampering with security defences).
Up to 5 servers can be added to the service (per API Key) and detailed check logs are available for 2 weeks (after that, only the audit summaries will be available).
To enable and configure RemoteHashStore, follow the RemoteHashStore Documentation.
Running PHPChangedBinaries Manually
All commands need to be run as root.
Updating Hashes Globally
Warning: You should only ever run this if you're sure that the system is secure and uncompromised - there's absolutely no benefit to checksumming a file that's been tampered with!
php /path/to/install/bin/changed_binaries.php --upd
You'll then be asked to confirm by entering YES. If you're using RemoteHashStore you'll also be asked to enter the update password set when creating the APIKey. If an incorrect password is used, a security alert will be sent to the Server Admin.
The hash database will then be updated.
Updating Specific Hashes
You may only want to update hashes for specific files or directories, especially as this means you only need to be sure of the integrity of those files to run an update.
php /path/to/install/bin/changed_binaries.php --updfile /path/to/file
Again you will be asked to confirm, and if you're using RemoteHashStore will be asked for your password
Running a check
To run PHPChangedBinaries manually
The system will check all files against the stored hashes
Whilst you should still run manual checks from time-to-time, the easiest way to ensure that checks are made is to configure a cronjob to run the checks. The command is no different to that you'd use to run manually.
# Once a day at 2am
0 2 * * * php /path/to/install/changed_binaries.php
# Once a week - Sunday 2 AM
0 2 * * 6 php /path/to/install/changed_binaries.php
# Once a month - 1st 2AM
0 2 1 * * php /path/to/install/changed_binaries.php
Output will go wherever you've configured your CRON to send it (usually /var/log/cron.log) and email notifications will be sent as needed.
There are 5 output levels within PHPChangedBinaries
- Notifications - General text output
- Warning - Warnings that may be relevant (a file doesn't have a stored hash etc.)
- Alert - A file has changed, possible security compromise
- SecAlert - Security Alert: Usually someone attempted to update hashes but provided an incorrect password
- Debug - You'll never normally see this, but detailed information about the operation.
Notifications, Warnings and Alerts (debug too, if enabled) will be pushed to stdout as well as being emailed. Security Alerts are only ever sent via email.
Default Check Paths
It's important to try and have as comprehensive a sweep as possible, you can monitor any number of files or directories (directory checking is recursive) by adding new paths to config/additional_files.cfg.
The following paths and files are checked by default
- PHPChangedBinaries files
- Any directory in the environment's PATH variable (usually /bin,/sbin,/usr/bin,/usr/sbin as a minimum)
- PHP Include paths (usually /usr/share/php)
- CPanel bin directory (if it exists)
- Plesk bin directory (if it exists)
- /etc/ssh/sshd_config (if it exists)
- /etc/hosts.allow (if it exists)
To add new files or directories to the check, simply add the full path to config/additional_files.cfg. One file or directory per line, any file with # is assumed to be a comment and ignored.
It's fairly simple really: you can't check whether a file has changed if you don't have read access to it. Running with root privileges (whether directly or via sudo) means the script will be able to check every file. A lot of the files we're traditionally interested in monitoring, should be accessible to root only, so we need to be sure we can check these too.
PHPChangedBinaries is designed to assist in the monitoring of server security, it is by no means a panacea! The script has been designed to make it harder to tamper with the checks, but it's still not impossible to do so - especially if you aren't using RemoteHashStore. That's why it's important to run the system manually from time-to-time, the output may well give an indication that something isn't right.
If an attacker has gained root level access to your system, there's nothing they can't potentially tamper with. PHPChangedBinaries is likely to detect the change, but only if it (and it's dependancies) haven't been tampered with themselves. The RemoteHashStore addresses this to some extent, but the very nature of server security means there can never be a completely bulletproof solution.