code injected inside PHP file with 777 permission

Solution 1:

Here is the de-obfuscated version of the script: http://pastie.org/private/iobgt7aetg8mezoepucsg

The code seems to include external PHP code from another website and collects information about your visitors while doing so.

One way this could of occurred is that you are allowing file uploads on a directory accessible from the outside. Doing so without proper validation is dangerous as a malicious user can upload a PHP file (using your image upload) with malicious code. If the web-server is not configured properly, the code will run when requested.

In order to avoid such problems, make sure that:

  • PHP processes are run by a limited user.
  • Files which do not need to be edited are set to be writable only by the owner (0644 or 0744 depending if you require the execute bit or not).
  • Only set the upload directory to writable.
  • Try to use an upload directory that is outside your webroot. Then use readfile() to serve the file.
  • Validate the files. If you want your form only to allow images, validate the magic bits and make sure that the image is valid. This is a hugely overlooked step. Same applies to any other format. Do not rely on the file extension or the mimetype sent by the client. Check the actual file content.

Solution 2:

There are at least 2 possibilities I can think of:

  1. They found your FTP password
  2. They found a flaw in your PHP software

To prevent them from happening:

  1. Use a complex password (minimum 9 characters, mixed case, digits and special characters)
  2. Run from 777 as if it was the number of the beast; try to give the webserver no more than read permissions on your scripts, and give special permissions to the (hopefully rare) folders/files where it has to write.

If you have access to some logs (the access logs from Apache and the FTP logs from whatever FTP server your website runs), that could prove helpful to see what happened.

It's doubtful that they managed to do so many changes with a simple flaw in your scripts, unless it's a really wide-open flaw (like you have an unprotected script only wrapping fopen() over whatever the user likes), so I'd check the FTP log in priority.