PHP Changed Binaries

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

php /path/to/install/bin/changed_binaries.php

The system will check all files against the stored hashes


Automating Checks

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.


Program Output

There are 5 output levels within PHPChangedBinaries

  1. Notifications - General text output
  2. Warning - Warnings that may be relevant (a file doesn't have a stored hash etc.)
  3. Alert - A file has changed, possible security compromise
  4. SecAlert - Security Alert: Usually someone attempted to update hashes but provided an incorrect password
  5. 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/init.d
  • /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.


Why PHPChangedBinaries needs to be run as root

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.


Security Considerations

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.