Hack, WordPress – A quick introduction to diagnose, restore and protect a hacked WordPress
I do mainly today mobile applications but I have still few websites running on WP and I have worked with WordPress since a long time. It is an easy, nice and economic way to make a website or even to run an API for a mobile application. Mostly because WordPress is very simple to take in hand for newbies.
The drawback of WordPress is the extreme vulnerability of the CMS to hacking. If you possesses a WP in production, be sure to look after it, making the required updates especially both for themes, plugins and the core code. If not, soon your site will be vulnerable and an easy prey for hackers even the most novice ones.
Is it the approach of Christmas Time or the end of the year? Some hackers made me a present : they have brutally hacked one of the WP site that I have installed long time ago.
Who to blame ? No-one, expect me, the site owner or both of us. Indeed, the updates have been not been made properly, nothing has been really made to secure the installation… I know few people who are managing web servers that I have a word for WP that is relegated to a noxious plague known as WordPox. There is also some sexist and delicate designations for WP, known as “pute digitale” or the more scatological “pezzo di merda secca digitale”. Anyway something that is turning around the concept of digital whore that seems accessible to anyone but with a very high risk on contamination. Oooops.
Indeed, this is outrageously sexist and inaccurate towards WP if you intend to take some prophylactic measures, that we will see in a couple of lines below.
Anyway, the very first reaction when your site is hacked is that you feel sorry not to have been more cautious. When, you check the website from codex.wordpress.org, the first advice is pretty simple and quite wisely too.
Stay calm.
When addressing a security issue, as a website owner, you’re likely experiencing an undue amount of stress. It’s often the most vulnerable you have found yourself since being on line and it’s contrary to what every one told you, “Hey, WordPress is Easy!!”
Source : https://codex.wordpress.org/FAQ_My_site_was_hacked
Apart from being calm, I was wondering what kind of venereal disease or I’d rather what kind of “French disease” the WordPress installation has contracted.
What kind of hack is that?
Just find this weird injection at the beginning of the wp-config.php file…. Ugly, is that serious Doctor ?
Then, after, you find this, you just follow the thread of the ball to the source with the help of Google and Malwaredecoder.com
The infected file
@include "...wp-\x63onte\x6et/pl\x75gins\x2fakis\x6det/f\x61vico\x6e_9e3\x335b.i\x63o"; |
The path decoded by alwaredecoder.com
@include "/[path-to-the-wp-install]/wp-content/plugins/akismet/favicon_cr6m5a.ico"; |
Rename favicon_cr6m5a.ico to favicon_cr6m5a.txt then make obfuscation code reverse engineering with malwaredecoder.com
if (!defined('ALREADY_RUN_i9gf4u95y82hhxk6vnqq1wkmd2yrbrb')) { define('ALREADY_RUN_i9gf4u95y82hhxk6vnqq1wkmd2yrbrb', 1); $vzmykcweljo = 0512; function mmaxsv($jvhlpxcgue, $nxnkuazsjoblv){$nxnkuazsjoblv = ''; for($i=0; $i < strlen($jvhlpxcgue); ... |
The path decoded by Malwaredecoder.com
@ini_set('error_log', NULL); @ini_set('log_errors', 0); @ini_set('max_execution_time', 0); @error_reporting(0); @set_time_limit(0); if(!defined("PHP_EOL")) { define("PHP_EOL", "\n"); } ... |
Source : https://malwaredecoder.com/
What can I do?
Here is a quick TodoList of what you imperatively need to do if your WP has been hacked
- Save the wp-config.php file, your images, and your personal files one by one (not the folder as it may contain unwanted files).
- Make sure that there is no malicious code in the saved wp-config.php file.
- Wipe out the entire folder where WordPress is installed.
- Upload a new clean full package of the latest WordPress version.
- Re-upload your wp-config.php file and images.
- Re-install the latest versions of your plugins and themes.
- Change the passwords for all WordPress admin users. Please use passwords that are hard to guess.
- Change the hosting Control Panel password and all MySQL passwords.
Some kind of SQL queries that will help to check the content of your database if there’s been some damages.
SELECT * FROM wp_posts WHERE post_content LIKE '%<iframe%' UNION SELECT * FROM wp_posts WHERE post_content LIKE '%<noscript%' UNION SELECT * FROM wp_posts WHERE post_content LIKE '%display:%' UNION |
Main security measures you can do or not…
Roughly, protecting WP consist of spreading Htaccess files everywhere! Htaccess files will help control the way visitors can interact with your website. The htaccess file is also used to block specific traffic from being able to view your website.
1. Modify the existing .htaccess of WP
The idea is to protect more carefully the access to some core files of WordPress eg wp-config.php, the .htaccess itself, prevent listing for directories…etc. You just have to modify the existing .htaccess of WP.
2. Add your own .htaccess for /wp-admin/
A second .htpasswd will be created to also secure more efficiently the administration dashboard
Be sure sure to place the .htpasswd, not in the root directory
3. Create the file .htpasswd and add the user mysuperuser
htpasswd -c /[path-to-your-htpasswd-file]/.htpasswd mysuperuser |
If you don’t current have an .htpasswd, use the “-c” option to create the file with the first user. It will prompt you for a password and encrypt it for you.
Command to list the files including the .htpasswd
ls -la |
If you already have the .htpasswd file and would like to append a new user, repeat the command with the “-c”.
Command to add a new user
htpasswd -c /[path-to-your-htpasswd-file]/.htpasswd mysuperuser2 |
Find the real path for your WP installation
In order to get the real path to your WordPress installation send a php file with the following command inside at the root directory of your installation.
echo (''.getcwd().''); |
You will get printed probably something like this, depending your hosting service.
/home/[user-account-or-ftp-user-account]/www
Create the .htpasswd
file and add a new user named mysuperuser
Enter the password for mysuperuser
You are done. Send, via FTP, the file .htpasswd
out of the root dir of your WP directory
The .htaccess that have to uploaded in the wp-admin directory. Be sure to put the correct to the .htpasswd
# SECURITY WORDPRESS for wp-admin AuthUserFile [path-out-the-wp-dir]/.htpasswd AuthGroupFile /dev/null AuthName "Access Restricted" AuthType Basic require valid-user |
Scanning the files of your previous WP
As you have made a fresh and new installation as you may need to re-upload some of the existing files from your previous WP eg uploads directory, plugins, themes…
I strongly advised you to scan these files that are probably infected, with malware more discrete, so you need to find and destroy it. These files are potential threats for your new WP such as backdoors, code injections, malicious iframes, hidden eval code, the the base64 family:base64_decode, gzinflate(base64_decode, eval(gzinflate(base64_decode, eval(base64_decode...
and more. We have used for this task one of the most popular plugin named wordfence
Wisely, I have runned the plugin wordfence
locally before uploading the all stuff on the new WP installation and guess what I found a bunch of crap installed by a hacker in order to perform malicious activity.
Launching the scan, being locally accelerated the scan process.
Locally, I always have weak password the famous admin:admin and wordfence
warned me on that. Good Boy!
This one warning is typically what I was expecting from wordfence
Theses warning are classical, just Out-of-Date plug-ins
A possible .htaccess
for your WP
The definitive .htaccess
for WP. This is not this .htaccess
that will protect the directory /wp-admin/
# BEGIN WordPress <IfModule mod_rewrite.c> RewriteEngine On RewriteBase / RewriteRule ^index\.php$ - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /index.php [L] </IfModule> # END WordPress # BEGIN SECURITY # BEGIN ENVIRONMENT # SET register_globals to off security SetEnv REGISTER_GLOBALS 0 # END ENVIRONMENT # NO listing for directories Options All -Indexes # NO listing for directories IndexIgnore * # Hide server informations ServerSignature Off # Enabling the tracking of symbolic links Options +FollowSymLinks # Time zone selection SetEnv TZ Europe/Paris # Default encoding of text and HTML files AddDefaultCharset UTF-8 # protect wp-config.php <Files wp-config.php> order deny,allow deny from all </Files> # Protect .htaccess and .htpasswds files <Files ~ "^.*\.([Hh][Tt][AaPp])"> order allow,deny deny from all satisfy all </Files> # Protect wp-login.php <Files wp-login.php> AuthUserFile [path-out-the-wp-dir]/.htpasswd AuthName "Access Restricted" AuthType Basic require valid-user </Files> # Avoid comment spam <IfModule mod_rewrite.c> RewriteCond %{REQUEST_METHOD} POST RewriteCond %{REQUEST_URI} .wp-comments-post\.php* RewriteCond %{HTTP_REFERER} !.your-site-domain.com.* [OR] RewriteCond %{HTTP_USER_AGENT} ^$ RewriteRule (.*) ^http://%{REMOTE_ADDR}/$ [R=301,L] </IfModule> # Avoid discovering an author's ID <IfModule mod_rewrite.c> RewriteCond %{QUERY_STRING} ^author=([0-9]*) RewriteRule .* - [F] </IfModule> # Disable the hot-linking of your images RewriteEngine On RewriteCond %{HTTP_REFERER} !^$ RewriteCond %{HTTP_REFERER} !^http(s)?://(www\.)?your-site-domain.com [NC] RewriteRule \.(jpg|jpeg|png|gif)$ https://fakeimg.pl/400x200/?text=no-way [NC,R,L] # Caching files in the browser <IfModule mod_expires.c> ExpiresActive On ExpiresDefault "access plus 1 month" ExpiresByType text/html "access plus 0 seconds" ExpiresByType text/xml "access plus 0 seconds" ExpiresByType application/xml "access plus 0 seconds" ExpiresByType application/json "access plus 0 seconds" ExpiresByType application/pdf "access plus 0 seconds" ExpiresByType application/rss+xml "access plus 1 hour" ExpiresByType application/atom+xml "access plus 1 hour" ExpiresByType application/x-font-ttf "access plus 1 month" ExpiresByType font/opentype "access plus 1 month" ExpiresByType application/x-font-woff "access plus 1 month" ExpiresByType application/x-font-woff2 "access plus 1 month" ExpiresByType image/svg+xml "access plus 1 month" ExpiresByType application/vnd.ms-fontobject "access plus 1 month" ExpiresByType image/jpg "access plus 1 month" ExpiresByType image/jpeg "access plus 1 month" ExpiresByType image/gif "access plus 1 month" ExpiresByType image/png "access plus 1 month" ExpiresByType video/ogg "access plus 1 month" ExpiresByType audio/ogg "access plus 1 month" ExpiresByType video/mp4 "access plus 1 month" ExpiresByType video/webm "access plus 1 month" ExpiresByType text/css "access plus 6 month" ExpiresByType application/javascript "access plus 6 month" ExpiresByType application/x-shockwave-flash "access plus 1 week" ExpiresByType image/x-icon "access plus 1 week" </IfModule> # kill them etags Header unset ETag FileETag None <ifModule mod_headers.c> <filesMatch "\.(ico|jpe?g|png|gif|swf)$"> Header set Cache-Control "public" </filesMatch> <filesMatch "\.(css)$"> Header set Cache-Control "public" </filesMatch> <filesMatch "\.(js)$"> Header set Cache-Control "private" </filesMatch> <filesMatch "\.(x?html?|php)$"> Header set Cache-Control "private, must-revalidate" </filesMatch> </ifModule> # Compressions of static files <IfModule mod_deflate.c> AddOutputFilterByType DEFLATE text/xhtml text/html text/plain text/xml text/javascript application/x-javascript text/css BrowserMatch ^Mozilla/4 gzip-only-text/html BrowserMatch ^Mozilla/4\.0[678] no-gzip BrowserMatch \bMSIE !no-gzip !gzip-only-text/html SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png)$ no-gzip dont-vary Header append Vary User-Agent env=!dont-vary </IfModule> AddOutputFilterByType DEFLATE text/html AddOutputFilterByType DEFLATE text/plain AddOutputFilterByType DEFLATE text/xml AddOutputFilterByType DEFLATE text/css AddOutputFilterByType DEFLATE text/javascript AddOutputFilterByType DEFLATE font/opentype AddOutputFilterByType DEFLATE application/rss+xml AddOutputFilterByType DEFLATE application/javascript AddOutputFilterByType DEFLATE application/json # Block the use of certain scripts RewriteEngine On RewriteBase / RewriteRule ^wp-admin/includes/ - [F,L] RewriteRule !^wp-includes/ - [S=3] RewriteRule ^wp-includes/[^/]+\.php$ - [F,L] RewriteRule ^wp-includes/js/tinymce/langs/.+\.php - [F,L] RewriteRule ^wp-includes/theme-compat/ - [F,L] # Protection against file injections RewriteCond %{REQUEST_METHOD} GET RewriteCond %{QUERY_STRING} [a-zA-Z0-9_]=http:// [OR] RewriteCond %{QUERY_STRING} [a-zA-Z0-9_]=(\.\.//?)+ [OR] RewriteCond %{QUERY_STRING} [a-zA-Z0-9_]=/([a-z0-9_.]//?)+ [NC] RewriteRule .* - [F] # Protections diverses (XSS, clickjacking et MIME-Type sniffing) <ifModule mod_headers.c> Header set X-XSS-Protection "1; mode=block" Header always append X-Frame-Options SAMEORIGIN Header set X-Content-Type-Options: "nosniff” </ifModule> # END SECURITY |
Files on github: Models of htaccess_for_wp_admin.txt and htaccess_for_wp_root_dir.txt. Be sure to rename as .htaccess. https://github.com/bflaven/BlogArticlesExamples/tree/master/hacked_of_time_wordpress
Read more
- Plugin Security Scanner
https://wordpress.org/plugins/plugin-security-scanner/ - Plugin wordfence
https://wordpress.org/plugins/wordfence/ - How To Scan Your WordPress Website For Hidden Malware
https://www.elegantthemes.com/blog/tips-tricks/how-to-scan-your-wordpress-website-for-hidden-malware - How to Fix the Internal Server Error in WordPress
http://www.wpbeginner.com/wp-tutorials/how-to-fix-the-internal-server-error-in-wordpress/ - WordPress piraté, hacké ? Comment réagir ? (french)
https://wpformation.com/wordpress-pirate-hack/ - Comment se fait hacker un site web WordPress ? (french)
https://secupress.me/fr/blog/comment-hacker-site-wordpress/ - Analyzing The WordPress SoakSoak Favicon Backdoor
https://blog.sucuri.net/2014/12/analyzing-the-wordpress-soaksoak-favicon-backdoor.html - Slider Revolution Plugin Critical Vulnerability Being Exploited
https://blog.sucuri.net/2014/09/slider-revolution-plugin-critical-vulnerability-being-exploited.html - Online PHP Decoder
https://malwaredecoder.com/ - Brute Force Attacks
https://codex.wordpress.org/Brute_Force_Attacks - Password Protecting wp-login.php with HTTP Authentication
https://blogvault.net/password-protecting-wp-login-php-with-http-authentication/ - Protect WordPress Login from Brute Force Attacks with .htaccess
https://ivycat.com/protect-wordpress-login-brute-force-attacks-htaccess/ - FAQ My site was hacked
https://codex.wordpress.org/FAQ_My_site_was_hacked - How to Password Protect Your WordPress Admin (wp-admin) Directory
http://www.wpbeginner.com/wp-tutorials/how-to-password-protect-your-wordpress-admin-wp-admin-directory/ - How to Find a Backdoor in a Hacked WordPress Site and Fix It
http://www.wpbeginner.com/wp-tutorials/how-to-find-a-backdoor-in-a-hacked-wordpress-site-and-fix-it/ - How to Find the Absolute Path to Your WordPress Root Directory
https://premium.wpmudev.org/blog/daily-tip-how-to-find-the-absolute-path-to-your-wordpress-root-directory/ - Strong Password Generator
https://strongpasswordgenerator.com/ - Le guide ultime du fichier .htaccess dans WordPress
https://wpmarmite.com/htaccess-wordpress/ - The plugin AskApache Password Protect
https://wordpress.org/plugins/askapache-password-protect/ - 20 astuces pour sécuriser votre site wordpress (french)
https://www.wpress-assist.com/20-astuces-pour-securiser-votre-site-wordpress/