How to detect if your webserver is hacked and get alerted

We all do our best to write excellent code and also keep our installations of popular open source tools like WordPress, Joomla, Oscommerce, Drupal, phpmyadmin and all its plugins always updated to prevent any attack or hackers using known exploits on them. This article is not aimed at going through all those methods to help you secure your website BUT focuses on how to send you an alert once your website is hacked and running “hidden” code that you didnt write.

The problem

Once hackers get into your website either by exploiting known vulnerabilities in any of the installed programs OR by getting FTP access to your server, the first thing they usually do is to plant backdoor scripts to log them in again at a later date. They need some executable script on the server to gain access to MySQL passwords, installation passwords or even edit settings in your wordpress or other installations.  We have also seen situations where the site was left largely unchanged except for malicious javascript code added to the bottom of the index.php or index.html files.

So in short the bad guys have taken over your server and running anything from a backdoor script or launching phishing attacks or sending tons of spam emails. You will not know that your server is hacked until you get blacklisted on spamhaus or your customers get redirected to some random site or worser still when you are contacted by ebay/paypal/some bank saying that your website is phisihing their customers. The problem is that we dont even have an idea that our site is hacked until it is too late or too embrassing.

Simple Solution – Website Change Detection System

We need a script on the server that detects any changes or to any executable file on the server or any new file on the server from HTML, JS, to PHP, ASP, Perl, Python files etc.  If we generate a hash value of all our files and then compare them periodically, then we will be able to detect when our codebase has changed on the server.

These are the steps that our change detection system performs (It takes about 500ms to execute on a typical server):

  1. Load configuration file (contains password, exclude list)
  2. Check password from request before starting (recommended)
  3. Recursively run through every file and sub folder on the server within the current directory of the script.
  4. Generate a hash for each file and arrive at the master hash.
  5. Compare master hash with hash the user has and alert if different!


  • This script at this simple level is almost 100% fool proof in detecting changes to the codebaes give that the hacker or bots don’t know of websiteCDS presence.
  • At this stage the script cannot detect SQL injection attacks and changes to code that are saved to the database.
  • The users hash is not stored on the server at any time, the comparison with master hash can be done at cron script level or using siteup as discussed below.

We have the following code written in PHP but you can do the same with any other scripting language to perform similar checks. We have started the project under google code and is available here: PHP code for WebsiteCDS
See the readme file in the download for help with setup.

Different ways to automate the alert system

Method 1: Using our trusted cron job
A cron job can be setup to run the website CDS, compare the results with the last known valid hash and send out an email alert.

Method 2: With Siteup
Siteup is a free tool for windows systems that can be set to periodically check if your website is reachable. This is recommended for those of us who don’t want to setup a cron job. It can be downloaded here We can use this to frequently call our change detection system and then use the siteup word search to check if the hash value is the same as what we have from our last codebase update. ( See screenshot )

NOTE: The project & code included is the first version of the change detection system and kindly submit your ideas and comments here or an issue or feature request in google code project for websitecds.

Also read...


  1. Capt. Sparrow said on :

    What is the best way to get to know which folder has the hacker’s code? What if I had this script on each and every sub folder on my server :)?

  2. Janet said on :

    Nice tip!

    One feature request – Can we find out which file has changed ?

  3. Anonymous said on :

    please use something more than md5. generate multiple hashes so that they can be verified against the file. it won’t take too much more time than now.

  4. php-manual said on :

    you can change the md5 to sha1 or any other hash function you like.

  5. Another Comment said on :

    This is a good mechanism to alert the user that something changed. Once you know that something has indeed changed, I would recommend using BeyondCompare or ECMerge or any other FTP to folder merge and comparison tools to see what has changed. This way you will be able to find out what file was hacked.

    SO, you CAN use this as it is and alert you, but once alerted, use some comparison tool along with your original codebase!

  6. Bugmaster said on :

    Nice idea! Also note – Attackers directly inject the malicious code in your CMS database by SQL Injection or XSS attacks.

  7. Paul said on :

    Also checkout TripWire. -Thanks!

  8. Pingback: Simple Website Change Detection System | California Dreams

  9. Pingback: Planet Android » Blog Archive » Simple Website Change Detection System

  10. antispin said on :

    Many people (such as myself) may not have any immediate alternative — and it’s definitely better than nothing. Thanks for the script.

    Tripwire, AIDE, AFICK, Samhain are alternatives but require you to have complete control over your web server.

  11. Ben said on :

    Thanks for the help! I’ve suggested it to my friends and colleagues. I’ve also referenced your article in my post. I’ve assumed the link is the way you want it. Keep up the great work!

    Thanks again,


  12. just_browsing said on :

    hmmm interesting little project, looking at some-point to implement something like this when I re-active my site. Shut it down due to getting compromised by a wordpress vulnerability that activated on my own PC when I went to view something on mysite – net result they got my FTP logins that resulted in over 50 different IP’s login each attempting to make a single file amend.

    So shut it all down – managed to nip it in the bud early.

    Easy tell tale sign of file change is the Date 😉 it not often when you have a site up and running that you amend the files so a compromised account will harbour a date newer than when you uploaded.

    Worthwhile using that sort of functionality to pick out altered files.

  13. Janice said on :

    Thanks for sharing the code. This is a script via a cron job to alert you for file changes. Something like the oscommerce site monitor contribution I guess.

    If you your server was hacked in the past you should not only restore from backups and change passwords, but figure out how they got in and fix the code. (You have the host’s server logs that should give you clues). As per the google code for the project the top request is to find out which file has changed. That will be a good enhancement. I hope someone will be able to do that for me 🙂

    Atleast this is a great solution to figure out if someone has tampered with any code on my site!

  14. Jerry Gav said on :

    Thanks for the detailed post!

  15. dungto said on :

    My method. List all executable / script files in your root using script and calculate it’s md5 save the result on text file or database. Periodically recheck md5 value and compare with last result. Pay some attention if you find difference.

  16. dd said on :

    Take a look at these links as well.. Sucuri does that for you remotely… Kinda like a tripwire for web sites, DNS, whois ,etc:

    For local servers, OSSEC is pretty good too (open source):

  17. Simone said on :

    This is wonderful.

  18. Deborah Steele said on :

    This is a wonderful program: thank you .

  19. TerryH said on :

    Nice work. My server was recently hacked – now cleaned up. I intend to use your file in case of future attacks. I have added the following features to my copy:

    Automatic refresh
    File names included in email
    A refresh button on web page
    A list of files that are changed with date/time the file was changed ( on web page)
    File names linked to actual file
    Some formatting for easy reading on web page

    However, I have 2 questions:

    1. Notifications of ‘Missing’ and ‘Modified’ files are repeated ad infinitum, is there any way to stop the repetition after the first notification?

    2. If a hacker gains access to the site, say by FTP, and he knows websitecds.php is a file-change reporting mechanism, all he has to do is delete the file before making his malicious changes. Has this been considered and is there a way to stop this happening?

    Cheers, and thanks for your efforts.

    N.B. if anyone wants a copy with my changes, please post a request.


    • php-manual said on :

      @TerryH Thanks for comments.

      1) Yes, that is a good suggestion. You can probably store the hash of the notification so that repeat alerts are not generated.
      2) Nothing stopping you from renaming websitecds.php to some other file name.

      Please post your code upate to the wiki

  20. Meg said on :

    Hi, and Thank you for the sharing of this tool…

    I think I have been hacked as my email inbox is full of returned emails and the subject matter is not something that I sent out. I have had 100’s of these emails come through in a matter of minutes. (I am trying to build a reputable website) I tested my email by changing the admin email from “X” to “Z” and my suspicions were confirmed when the returned emails changed right along with it.

    I am going to impliment this code on the site, but my question is: How do I find the hack?

    I am running a perl script behind the index pages which are html.

    Does anyone know if there is a script to detect the hack?

    Best Regards

  21. TerryH said on :

    Hi Meg

    A site on my server was recently hacked. The hacker claimed to be a representative of Al Queda (probably a hoax) but I found files in the route directory that I didn’t put there – index.htm, index.html some .asp files and some .txt files (which I wouldn’t exclude in the above script, if I were you). Create new FTP accounts and delete the old ones. If you are using a dedicated server, change your RDT access password, and do it often. There’s no point in installing the websitecds script until you know that your site is clean. Check sub-directories too. As far as I know, there’s no script to detect the hacker’s files. It has to be done manually.

    Hope that helps


  22. TerryH said on :

    Forgot to say. If it’s only email that’s affected, check that you’re server is not allowing open relay.

  23. wcdspro said on :

    Free service to detect website changes.

  24. iceorigin said on :

    Thanks for developing this script,I have put it in my own server.

  25. Nick said on :


    Any chance of a copy of the latest version of your modified script?

    My email is: support banana camstudio apple org
    (Replace banana with @ and apple with a .)

    Thanks in advance


  26. TerryH said on :

    Hi Nik

    I have written another script without md5, which comes in 2 files (you won’t get any ‘Missing’ and ‘Modified’ repetitions with these).

    Read the file comments for setup:

    File ‘web_search.php’ This one will display all deleted/modified/missing files from the site route through to the deepest sub-directory and send an email alert to the nominated email address. The link for this file is:

    File ‘web_search_cron.php’ This is basically the same file without any formatting and no response at all where no changes are found. It is intended to be used as a scheduled task or cron job. The link for this file is:

    Hope you find the code useful – if you have a question, upload it here.


  27. TerryH said on :

    Just noticed my error on the previous post:

    ‘deleted/modified/missing’ should read ‘added/modified/missing’


  28. Lucio Becze said on :

    Howdy! This post couldn’t be written any better! Reading through this post reminds me of my old room mate! He always kept talking about this. I will forward this post to him. Pretty sure he will have a good read. Thank you for sharing!

  29. TerryH said on :


    Sorry for the delay in reply – I don’t get email from this site any more for some reason.

    To answer your question – you’ve probably worked it out for yourself – directories can’t be excluded, only files. Sorry.

    I think the original websitecds is the same.


  30. Clinton Brits said on :

    I can’t get this to work universally.

    I tried something like this on my site but to design it differently, i creates and tested the site on my localhost and obviously had a htdocs folder on my local machine.

    I built a windows app on the local machine pointing to mu local directory which then losts every file (with relative path) and the md5 hash of that file. I then uploaded a php script which does exactly the same on the remote web server and then sends the results using html to my local app for comparison. This way you will know if files on the server have been hacked and by clicking on the update button it just replaces the remote file with the ,local file. It’s also useful for updating a site with many files because you just need to upload the changed files as opposed to the entire website.

    The problem with this is that ALL my html/php/txt files show a difference eventhough they are the same. It works great on the local machine web server so i’m assuming the webservers are configured some how to alter the files for space saving(ie disk compression) that changes the file. When you download the file again from ftp and compare it, they are identical.

  31. Stuart said on :

    Thanks for the great script. I am using websitecds-cron-only.php. I had a little trouble though, but finally managed to implement it.

    My directory structure is:

    In Cpanel my command is:
    php -q /home/MY-ACCOUNT/cron/websitecds-cron-only.php

    My problem was that websitecds-cron-only.php would not run in my server’s home folder, ie: /home/MY-ACCOUNT/
    So I put it in: /home/MY-ACCOUNT/cron/ but then I was getting errors like this:
    Dir /home/MY-ACCOUNT/cron/public_html not readable.
    I discovered the problem was with line 14:
    $dir = dirname(__FILE__) . ‘/’ . $dir;
    which was creating the bad directory path.

    I found a non generic inelegant solution by changing line 148 to:
    $dir = ‘/home/MY-ACCOUNT/’ . ‘/’ . $dir;

    I hope this might help others like myself who are inexperienced with php and cron jobs.

  32. Stuart said on :

    Should be:
    I discovered the problem was with line 149

  33. ethan said on :


    This seems like a great tool, but in case anyone wants something more complex to setup but highly robust, I have been using this on my linux servers:

    Its very fast, powerful and flexible but more complex to setup.

  34. Chris van der Westhuizen said on :

    Does anybody maybe have a modified version that also check when a file’s permissions or owner has changed?

    This is an excellent peace of work, thanks. 😉

  35. Pingback: PHP Base64 Virus « qwaxys' brain dump

Comments are closed.