We have been securing/cleaning Joomla websites for so long that we have identified the three-step process a malicious attacker performs to hack a Joomla website:
- The attacker injects a PHP file in the images directory.
-
The attacker then replicates the PHP script into other directories where it’s under the radar. This strategy ensures that the attacker maintains access to the Joomla website even if the main PHP script uploaded to the images directory is deleted. The attacker usually replicates the PHP script simply by executing it with specific parameters.
-
The attacker then executes the PHP script or one of its clones with different parameters. This script execution results in at least one of the following:
- Permission changes in core files.
-
Code change in core files. Such code change includes, but is not limited to:
- Malicious lines in the .htaccess file often resulting in Google seeing the website as spammy.
-
Changes to the application.php or framework.php files, mainly adding some malicious content from a remote website, thus infecting your visitors’ machines with malware and slowing down your whole website.
-
Changes to core JS files essentially doing the same as above.
-
Sending spam – either directly from the uploaded file or after creating a not-so-easy to find file somewhere on your machine and using it to send spam.
-
Reading critical information from the configuration file (such as the database host, name, username, and password).
-
Manipulating your data or wiping out your whole database.
-
Wiping out your whole website – especially if you have very loose permissions on your Joomla website.
The above is a standard process, and there are certainly many variations, but a common step is, in 90% of the cases, the first step. Once an attacker is able to upload and execute a PHP file onto your website, then he’s already in control.
Now, of course, the heart of the problem is how-oh-how was the attacker able to upload that PHP file in the first place. Was it a Joomla vulnerability issue? Was it a loosely secured extension? Was it an exploitable text editor? Was it something else?
The reasons may be many – but the result is the same, the website will become compromised! But… What if we could disable PHP execution in the images directory, wouldn’t that stop this vicious change of events?
The answer is yes!
Disabling PHP execution in the images directory will mean that even if someone sneaked a PHP file to your images directory, it won’t be executed. In fact, when the attacker tries to execute the malicious script, he will only see the code. Nothing will happen!
So, how to disable PHP execution?
Well, it’s simple. In fact – it’s very simple! Here’s what needs to be done:
- If your Joomla website runs under Plesk:
- Create an .htaccess file with the following content:
php_flag engine off AddType text/plain .php AddType text/plain .php5 RemoveHandler .php
-
Upload the above .htaccess file to the images directory.
-
Change the permissions of the .htaccess file to 444.
- Create an .htaccess file with the following content:
-
If your Joomla website runs under WHM/cPanel
- Create an .htaccess file with the following content:
RemoveType .php
-
Upload the above .htaccess file to the images directory and change its permissions to 444 as nobody needs to write to it.
-
That’s it!
- Create an .htaccess file with the following content:
If everybody applies the above tip, then there would be a huge reduction in the number of hacked Joomla websites, but, unfortunately, many Joomla administrators think that their websites are immune or are just intimidated to do the above. In case you’re one of the latter, then we understand your fear. Just contact us and we’ll do the above for you in no time and for a very little fee.
Note: It’s an excellent strategy to apply the above method to any folder that Joomla writes to (except those folders where Joomla creates/writes to PHP files).
[…] the malicious file (the one containing the query), we then secured the website (especially the images folder), and finally we have reverted back to a previous backup of the #__users table. That fixed the […]