PHP code injection; how to prevent it?


I’ve had an ongoing issue with my PHP files on one of my websites being edited to include a line at the top that starts with <?php /**/ eval(("aWYoZnVuY3Rpb25fZXhpc3R or base64_decode( functions. My images folder contained 2 .php files with weird names (randy_mcqueen.php and tommy_confidence.php) that were similar jibberish and certainly were not put there by me.

I’ve had issues with my entire MYSQL database being dropped more than once, and right now google has my website flagged as malicious. I’ve cleaned up the problem on 2 prior occasions and appealed to google, but within a few months it happens again.

Nobody has my password and it’s fairly secure, and I don’t have anything that allows uses to upload files of their choosing. I have my CHMOD settings on 755 for all files (php, html, core, folders, images).

Any suggestions would be great, I suppose I can keep cleaning it up by hand every 3 months but I’d rather figure out why it keeps getting reinfected and how to truly clean it up.

As a side note, the problems started immediately after I blocked registration on my PHPBB forum. The first year I had PHPBB bots were registering accounts to put porn on the site. After a year of deleting posts and having literally thousands of junk accounts created I disabled registration and within a month all of the posts and tables and user accounts were dropped. Since the SQL wouldn’t allow me to log in as localhost I had to set chmod so the PHPBB folders could be written by group, which I suppose would allow any dreamhost user (or infected dreamhost website) write files into my folders. Given the ability to stick files into the /forum folder, they should be able to put files into …/ The issue didn’t happen with any of my other websites. Since then I’ve completely gotten rid of PHPBB and turned off group write, but the problem is still occurring.


Just to clarify, you have multiple sites under the same user, but only one is affected? If that’s the case, then the most likely cause would be a security flaw in the web app you are using.

I’m not sure what you mean about logging in as localhost. You should connect to your DB through a subdomain set up in the panel.

As I understand it, other users won’t be able to read / write to your files because a) they don’t belong to the same group as you and b) your home folder has pretty restrictive settings.


Thanks for the reply. As for the SQL, disabling group read/write causes my board to throw MYSQL errors. If that’s not the cause then I have no idea how someone is rewriting my files and forcing uploads into my images folder. All I know is that my users are being redirected to and Google has me flagged as a virus distributor, and every time I clean it up it’s infected again in a matter of days.

Maybe I can ask a few more direct questions: If I allow uses to upload images, is there a problem if they’re marked as guest executable? What kind of PHP functions do I need to be careful of? What CHMOD settings should I use for PHP/html/htaccess/folders? Should a folder with executable content also be executable?


In general you should not change any permissions, especially to be more lax than what the application comes with or recommends. You are using something such as phpBB or something like that? You MySQL errors are not related to folder permissions. The app might be trying to modify a file based on a result from a MySQL query, but MySQL doesn’t care one bit about any folders or permissions in your account. They are simply not related at all. It might be that the config file used to connect to the MySQL server has the wrong permissions so the webapp can’t read it or something that makes it look like the problem is MySQL, but I can’t think of any way it could happen.

Change all of your permissions back to the standard settings and look for the real problem.

Nothing that users upload should be executable. No, no, no, and no. By the way, nothing that your users upload should be executable. Nothing. Nada…

Do a search for that sweepstakes thing. There have been other reports on these forums with the same address. I can’t tell you exactly what caused it, but in general, most of these things are exploits of insecure plugins, addons, or apps themselves, usually written in PHP. Upgrade to the latest version, disable any sketchy plugins and addons, reset all permissions, and look long and hard for any backdoors. You might even try wiping everything that ends in php and reinstalling. Backup first, just in case.


I was recently hacked and found a bunch of php files with similar code to what you describe and weird names a la: someword_anotherword.php

The hacker also

  • added s to a bunch of html pages, mostyl just before
  • added some redirect code to the .htaccess files


I have not figured out how they got in yet.



We’re actually about to send out a mass notice to a number of customers that were affected by the “sweepstakes and contests info” injection. You should be getting the email in a few hours.

There’ll be details on your specific situation in the message you get, but in general it looks like that a lot of these injections resulted from attackers placing PHP scripts in world-writable (e.g, chmod 777) web directories.


It would be great if you could add info to the wiki as well for those who weren’t caught up in it but wish to avoid similar exploits in future…


It might have been this (or something similar):


@andrewf - yes, I should have mentioned this was the injection

that’s great - looking forward to getting that email.


I am having this exact same problem with all my Dreamhost sites. I have edited the htaccess file, but it is rewritten with the offending site redirect, AFTER changing my FTP password. I have also discovered over 8 separate php files with the naming convention detailed above across all my domains.


Having just finished cleaning up two domains and two subdomains for the same thing, I can relate. So far there hasn’t been a re-intrusion, but it’s only been five days since Google flagged me for malware.

I’m not all that savvy, but I read in an article that I needed to change my password immediately, clean out the infection (even if it meant dumping everything and re-installing), and then change my password a second time. Seemed to make sense - if their code is inside my site already, they’d be informed of my password changing the first round. Maybe a second change would be in order after you’re certain the infection is gone.



The WordPress FAQ has some good tips as well (mentioned in another post). Something it mentioned which I had never considered is cookies. If an adversary has logged in somehow, changing your passwords won’t help because that person still has an authenticated cookie. You’ll need to change your salt as well.


Thanks for your insight. Since my post, I have:

  • Reset my FTP password
  • Restored all domains back to the oldest available backup
  • Upgraded all software installations
  • Removed some old unneeded software installations
  • Set all software installations to auto-update
  • Manually edited all files listed in hackedfiles.txt (generated by Dreamhost) to remove the offending code
  • Delted several infected files with the randomword_randomword.php naming convention
  • Reset my FTP password a 2nd time (from an alternate computer) as well as my dreamhost panel password

Google still says all my sites are infected with Malware and I’m at a loss at where to go from here…


Have you requested that Google rescan your site? They don’t pick up all these changes immediately.


I have requested a review - not sure how to tell when/if that completes?


Even if you do all of that, there may still be problems if your adversary has an authenticated cookie because it appears that you have not changed the salt used to encrypt that cookie. Also, if your adversary has changed your config file to include another email address, then it would be easy to gain access again. Or if you have used the same password as your email account, your adversary may have access to your email account as well which represents a backdoor to your account.

From my own security notes to myself for Dreamhost sites which do not make use of [font=Courier]https[/font]:

There are basically four basic accounts involved for every website, with the possibility of others. No usernames or passwords should be recycled across accounts.

These accounts are ordered from least to most likely to be accessed which, ironically and unfortunately, is roughly proportional to the severity of a potential breach. Each level entails access to all levels below it except for #4.
[]database account: this should rarely be needed except for maybe development work. The username and password should both be long and complex. There’s no reason to make either easy to remember or even type.
]username: ≥12 from [[font=Courier]a-z0-9_$[/font]]
[]password: ≥15 from any printable characters
]vulnerability: password can be viewed by other users on the same machine when passing the password as an argument when invoking [font=Courier]mysql[/font] ∴ [font=Courier]-p[/font] should be used and the password entered at the subsequent prompt. Web-based interfaces should never be used unless they are routed through a secure connection such as [font=Courier]https[/font] or an [font=Courier]ssh[/font] tunnel.
[]connection: command line from shell, [font=Courier]ssh[/font] tunnel
]breach: all data stored in the database including all usernames, email addresses, hashed passwords, and possibly PII.
[]shell account: this account should also rarely be needed. It is useful when installing new software, viewing log files, and other low-level maintenance work.
]username: ≥6
[]password: public key authentication (preferred if the private key is adequately protected) or ≥12 from ⊇ [[font=Courier]a-zA-Z0-9+/[/font]]
]vulnerability: few if connections are made over secure channels and public key authentication. Keyloggers may capture passwords on compromised systems
[]connection: [font=Courier]ssh[/font], [font=Courier]sftp[/font], [font=Courier]scp[/font], or other secure communications channel only
] breach: as database connection information is stored at this level, all data in database information would be lost. In addition, viruses, malware, and other unpleasant garbage could be added surreptitiously to the site to make it dangerous for all future visitors. Depending on the severity of the breach, changes made to the site by an adversary could result in a violation of the Terms Of Service Agreement with Dreamhost which would lead to a complete loss of all sites hosted under the hosting account.
[]Dreamhost panel account: this account is used for higher level maintenance such as (setting up|installing|removing|modifying) new software, domain names, databases, email addresses, discussion lists, statistics reporting, etc. as well as requesting assistance from Dreamhost Support.
] username: email address or Dreamhost-supplied WebID which is derived from email address
[]password: ≥12 from any printable characters
]vulnerability: Email account is the single biggest threat due to the password recovery mechanism which will forward a working key to get into the panel with no questions asked. If possible, set email address to be one not used often or one which is very secure. Other than that, mostly keyloggers or other malware on the machine used to connect to the panel.
[]connection: [font=Courier]https[/font] only. There is an option which can be set under [font=Courier]Edit Profile[/font] > [font=Courier]Preferences[/font]: Require email confirmation before allowing a new IP to log in to your web panel (more secure). Enabling this option is highly recommended as it limits the ability of an adversary to use compromised credentials but assumes that the associated email account has not been compromised as well.
]breach: everything, complete disaster.
[]Application admin account: this account is full permissions account for WordPress, Joomla, or some other web-based application.
] username: ideally avoid ([font=Courier]admin[/font]|[font=Courier]administrator[/font]) because they are usually defaults and most web apps have no protection against brute-force attacks. It’s better to change the default admin username to something else and possibly create a more limited account for daily content creation and moderation if the app has that level of granularity (see breach section and optional accounts sections for details).
[]password: ≥12 from any printable characters
]vulnerability: this is the only account which can not be authenticated over a secure channel ∴ this set of credentials should be assumed to be disposable and/or compromised from the beginning. It’s like leaving a spare key under the doormat or using a combination lock to secure a bicycle. Usually you’ll be fine, especially if you don’t do it often, but if an adversary really wanted to attack, it would not be very difficult.
[]connection: [font=Courier]http[/font] only ∴ credentials are passed in cleartext. The only way to avoid this situation is to set up a local mirror and open an [font=Courier]ssh[/font] tunnel to forward database queries to the remote database. Unfortunately this will result in slow queries which can make some applications frustrating to use. Another way is to create an authenticated cookie either through a local mirror or through a slow but secure [font=Courier]ssh[/font] tunnel to the live database, then switch to normal [font=Courier]http[/font] for the rest of the session. It’s still possible to capture an authenticated cookie by listening in over unencrypted channels, but the ability to use the cookie on another computer depends on the sophistication of the app (i.e. if the app is also encoding your browser type, IP address, and other identifying features, it will be harder to reuse the cookie elsewhere, but few apps do this).
]breach: full admin rights as granted by the application will be gained by an adversary if an admin account is breached. Some apps, such as WordPress, allow administrators to edit plugins and themes from within the application which is basically an open door to the database and shell account, but not the panel. If possible, most accounts should be set at a level below admin, such as Editor or Author in the case of WordPress, with an admin account reserved for actual application maintenance such as upgrades or changes to themes and plugins.


I’m trying to determine what level of access an attacker currently has. A client has a wordpress site that has been hit repeatedly with a pharma-hack that targets search engines to make the site look like it is full of viagra ads. Looks normal to a casual visitor.

I am able to detect an attack quickly with, and I am able to quickly identify the php-injection points, and restore files to earlier states. I have also found and removed a number of backdoors. However, the attacks keep coming. In the most recent one, a php script points to a file outside of the public directory. Specifically, the .core file in the users home directory. This file was filled with php eval code etc. that is typical of this attack.

Up until now, I have been assuming that there were some folder permissions somewhere that I was unknowingly keeping open, or that there were still some undetected backdoors letting people in. Given that files are now being changed outside, is this still likely a backdoor php script issue, or does it suggest that they have user account details?


could be either, but i’d guess it’s a backdoor php script. check your logs very carefully to see what’s being accessed.

also, change your salt. if they have an authenticated cookie, they can keep coming back even if you change your passwords.


Thanks, I’ll try out your suggestions. Appreciated.


I’m pretty web savvy, but have never heard of ‘salt’. What is it and how do I change it? All google searches point me to Angelina Jolie. :slight_smile: