Website Hacked...Continued

Hi Chaps,

After my clients’ site was hacked just over a week ago, I took down the site and made some changes to the PHP scripts.

  • Backed-up the database, then removed it from the webhost
  • Removed all web files
  • Changed the FTP and SQL login credentials
  • Encrypted all user passwords
  • Secured the login/signup scripts with a Captcha tool.
  • Secured all account & checkout pages with cookie checks (forces login).
  • I validated all the user inputs for XSS.
  • Secured the SQL scripts with mysql_real_escape_string()/strip_tags()/str_replace().
  • Used HTTP_REFERER on account/checkout pages

I’m hoping this will sure up the front-end site.

Whilst I was backing up the images folder (500Mb+) to my PC, I was warned of trojans and viruses.
It turned out the hackers had placed php files (cid.php/sniper.php/etc) and a couple of files without extensions, into the main Images folder.

Without knowing how they actually did this (whether they had access to the FTP site, gained access through the website, or through a virus on the laptop used to update the site/upload images), I would like to know what I can do to make sure that they can’t do this again. There is no option for front-end users to upload files, but the administration site does allow image uploads.

At the moment, the images folder permissions are set to 0775, I think this is correct.

Is there something I can do to the Image folder permissions as a whole, or should I just run a regular check on the directories, checking for all non-image files, or any file/directory that doesn’t have the 0775 permission?

Are there any resources on protecting FTP folders with PHP, uploading files/directories to protected folders, good practices to continually check for unwanted files?

Is there anything else I should be looking into, I did read something about the dangers of include()/require_once()

The site is hosted on a shared server, and don’t have access to the .htaccess files. Is there anything I can ask the hosting company to check that there firewall is working correctly?

Sorry for the range of questions in this, but any help or guidance would be most appreciated.

Many thanks

Probably too late now but you could have checked the file modification time of the malicious uploads against your http and ftp logs to see if there is any correlation.

Running a regular check on the images directory isn’t a good solution, you need to find and tackle the cause of the insecurity rather than accept it will happen and trying to catch the eventual effect.

Sorry I overlooked that you don’t have .htaccess access. That’s too bad. Alas, I’ll go ahead and post this anyway.

Nice job, all the things you did to better secure the site.

Some of the files you found in the images folder might have been PHP backdoor scripts. That’s common. As a protective measure in case that happens again, you could use an .htaccess file in that folder to prevent .php files from being run as PHP scripts. I don’t recall the specific code for doing that, but it probably involves RemoveHandler ( http://httpd.apache.org/docs/current/mod/mod_mime.html#removehandler ) . Any .php file called would just be served, rather than executed, preventing a backdoor script from executing even if it’s there. A web search should easily find example code.

At the moment, the images folder permissions are set to 0775, I think this is correct.
Folder should generally be 0755 (but I doubt this was the critical vulnerability; 0777 would have been more critical). Files should be 0644.

Is there anything else I should be looking into, I did read something about the dangers of include()/require_once()

The danger is “remote file inclusion”. This should help, and you can compare your code against the examples.
http://25yearsofprogramming.com/blog/2011/20110124.htm

There is no option for front-end users to upload files, but the administration site does allow image uploads.

You could apply Apache password protection to the administration folder, so the administrator must log in twice (to Apache, and then to the Admin area) to get in.

If the client only uses one IP address, you could even use an .htaccess in the admin folder to restrict access to that one (or a few specified) IP address(es).

If it’s possible that the original compromise was due to your client managing the site from an infected PC so the FTP password was stolen, there’s not much you can do about that except try to impress upon the client the importance of keeping their PC clean.

If the shared hosting account has SSH access (not common), you can probably disable it in cPanel. If the client uses SSH themselves, impress upon them the importance of strong random passwords.

The host’s firewall probably couldn’t help with defending against this. That’s more useful for large scale things like alleviating DoS attacks.

It doesn’t happen often that I advise anyone to switch webhosts, but if this turns into an ongoing hacking problem, some of your best protections involve .htaccess. I personally would not use a host that didn’t allow me to edit it.

I know I’m late to this game, but I thought I would throw in some feedback, otherwise, I’ll be twitching… :wink:

The code for the PHP-only directives is as follows (unless I’m either wrong or someone knows of a better solution):

# Force PHP...
ForceType application/x-httpd-php

It’s also important to keep in mind that this sort of crap happens with shared hosting… I’m sure you know this, but my question for you is as follows: have you expressed need to your client about requiring a better host due to specific issues regarding security and such?

If you have no access to your HTACCESS file, and the client is unwilling to relocate their site to a better host, it might be time to find greener pastures. This goes without saying that money is always a necessity and if you find yourself in financial straights that prohibit taking your skill set elsewhere, then so be it, but at least ensure that the client should expect this type of happenstance if they’re only willing to help you out with half a rope…

For whatever it’s worth, here are some more HTACCESS goodies (if anyone else has better candies, by all means…):
Disallow certain file types from executing:

AddHandler cgi-script .php .pl .py .jsp .asp .htm .shtml .sh .cgi
Options -ExecCGI

Disable “REQUEST” (shouldn’t be an issue if app logic is well-written):

Options -ExecCGI -Indexes -All +FollowSymLinks
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_METHOD} !^(GET|PUT)
RewriteRule .* - [F]

Process file types through app logic (as I understand it–I’ve never used it):

Action image/gif /cgi-bin/filter.cgi

Disable hot-linking:

Options +FollowSymLinks
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http://(www\\.)?blah.com/.*$ [NC]
RewriteRule \\.(gif|jpg|swf|flv|png)$ http://www.blah.com/feed.gif [R=302,L]

Error documents:

ErrorDocument 404 /favicon.ico
ErrorDocument 403 https://secure.blah.com
ErrorDocument 404 /cgi-bin/error.php
ErrorDocument 400 /cgi-bin/error.php
ErrorDocument 401 /cgi-bin/error.php
ErrorDocument 403 /cgi-bin/error.php
ErrorDocument 405 /cgi-bin/error.php
ErrorDocument 406 /cgi-bin/error.php
ErrorDocument 409 /cgi-bin/error.php
ErrorDocument 413 /cgi-bin/error.php
ErrorDocument 414 /cgi-bin/error.php
ErrorDocument 500 /cgi-bin/error.php
ErrorDocument 501 /cgi-bin/error.php

Examples of “Allow” directive:

# A (partial) domain-name
Allow from 10.1.0.0/255.255.0.0

# Full IP address
Allow from 10.1.2.3

# More than 1 full IP address
Allow from 192.168.1.104 192.168.1.205

# Partial IP addresses
# first 1 to 3 bytes of IP, for subnet restriction.
Allow from 10.1
Allow from 10 172.20 192.168.2

# network/netmask pair
Allow from 10.1.0.0/255.255.0.0

# network/nnn CIDR specification
Allow from 10.1.0.0/16

# IPv6 addresses and subnets
Allow from 2001:db8::a00:20ff:fea7:ccea
Allow from 2001:db8::a00:20ff:fea7:ccea/10

Temporal access:

Options +FollowSymLinks
RewriteEngine On
RewriteBase /
# If the hour is 16 (4 PM) Then deny all access
RewriteCond %{TIME_HOUR} ^16$
RewriteRule ^.*$ - [F,L]

I got a lot (if not all) of these snippets from the following address:
http://www.evolt.org/ultimate_htaccess_examples

Hope this helps. Also, make sure you sanitize your upload forms by using header checks, sanitize your MySQL queries by using prepared statements, sanitize your $_GET / $_POST transitions, use random salts for your sessions (to prevent downloads of forms and whatnot, and, um, lock your front door when you leave for work. :slight_smile: