They weren't lying.

Potatoe

BuSo Pro
Joined
Jan 4, 2016
Messages
737
Likes
1,115
Degree
3
All those people who say to avoid using extra plugins with wordpress, or to avoid using bloated themeforest-style themes, etc..etc...

They weren't lying!

One of my sites was recently hacked. It's my first time dealing with this.

I had a plugin that added avatars for authors (I always thought this was a default feature, but I guess some themes don't have it? Which is odd, because the themeforest theme I was using literally had an option for everything else under the sun.)

Anywoo - they did some sort of SQL injection using the WP User Avatar plugin, and were able to inject some sort of file that dynamically generated Google Webmaster Tools verification files, so they added themselves as a verified owner of the site, created 8000 spam pages, and submitted the new sitemap to Google lol. In order to unverify them, I had to remove the verification file from my server - but I couldn't, because it wasn't actually there? It was a whole to-do, it's all sorted out now (I hope lmao)... I think it was a page.ini file or something? And apparently they did something to my htaccess, according to my host.

I just wanted to post this because I KNEW BETTER than to use extra plugins and to not keep my stuff 100% up to date all the time, and to not use bloated themes even if they look nicer and have more features, but this wasn't a super active site so I didn't keep close enough tabs on it.

So if this massive waste of a day can happen to someone who knows better, I just wanted to give a heads up to any folks out there who don't know better - be careful!

Not sure if this was related or not, but my Dashboard was also running VERY slow. Turns out there was a brute force attack against my /wp-admin page, so I changed the URL of that and I'm going to look into setting up a better htaccess file that'll block the IP address at LEAST of people outside of my continent, since all of my staff are located on the same continent. I know that's not the perfect fix, but like 99% of people trying to hack my site every day are located in other continents, so it's a start. I had recently switched from iThemes security to Sucuri, which is around when the dashboard of wordpress slowed down to a crawl, so iThemes must have done a better job of blocking that sort of stuff. I switched back to it, sry sucuri. (I know, I know, more plugins... lol. I think I can do this with Carter's magical htaccess file, so I'll ditch the plugin eventually.)

So yeah, update your stuff, don't use plugins unless you NEED to and even if you do, try to lock them down as much as you can (There's something about blocking access to the plugins folder, I need to look into that...) use real minimalist themes like BuSo Lightning or mythemeshop is pretty decent too afaik (Always19 coupon gets you any of their themes for $19 instead of ~$60).

The plus side of all this is that my new theme runs twice as fast as my old one. And the new one hasn't been optimized at all yet, vs the old one that was optimized by a pro and still twice as slow. So.. all's well that ends well.

Just figured I'd share this because yeah, I should know better, so hopefully there's someone out there that gets the message and smartens up *before* it's too late, unlike me.
 
Also you should be removing as many of the WordPress footprints that you can.
 
Did you used iThemes at that time when you get hacked?
Some plugins can be disaster without the need of hackers. A few months ago, I installed a 404 to 301 plugin and just couldn't login to my wordpress dashboard afterward.

I'm searching for reliable wordpress theme at the moment..
Some of the themeforest theme looks good but heard that they might have really bloated code..
I've yet to try themes from mythemeshop or Thrive themes. They both seems to get really good reviews.
 
The gift that keeps on giving.

The folks who were borrowing my website and used it to create 1000's of spam pages, then granted themselves access to my WMT, then submitted a sitemap with all of those extra pages... They didn't stop there (Allegedly. It might have been a separate incident, to be fair. My host said the logs that could have helped identify this were removed. Apparently I have Hillary's people running my email server...)

Well, they also seemed to have been sending out tens of thousands of spam emails from a bunch of aliases that they created, and now my domain is blacklisted. Looks like I'll be emailing from brandname @gmail.com now.

So, I've still got over 2,000 spam pages showing up in Google's index, and now my domain is blacklisted from getting any email delivered.

I'm kind of annoyed at my host, even thought it's not their fault this happened. How does a spammer queue up 90,000 emails without raising any red flags? I only noticed this happened because I went to send an email and was told that I was over my hourly limit. When someone hits that limit, hour after hour, for days, shouldn't that kinda raise a red flag? I'm not feeling too confident in this right now: https://www.wiredtree.com/support-services/servershield-server-hardening/ My server is softer than Drake.

It seems to me... and I don't know anything... that if a site is hacked, the person working on cleaning it up should ask themselves "Why do people hack sites?" and common reasons would be "To spam google" and "To spam email". So, we already know they were using my server to spam google, why wouldn't you take a quick peek at the email side of things to make sure they aren't using it for that, too?

I let them know I was hacked the first time, they did a malware scan, moved the infected files to an abuse folder on my server, and marked it as complete - should they have taken a peek at the email logs and stuff to make sure there was nothing else going on, or is that asking too much? Honest question, I don't know what the standard practices are.

I've asked Knownhost (Because I always hear good things about them, so they'd be my first choice) how they would have handled it because I'm considering the switch - but they told me that they won't answer because they "don't second guess other providers." Still considering it, although I'd get about half to a third of the resources and pay about 20% more (I'm on a black Friday promo with WT). I've heard from a friend who uses them, and had the exact same thing happen to one of his sites (The initial hacking with spam pages created, and the email spam too) that they actually handled it worse than my current host did, so I guess it's a crapshoot either way.

I don't know enough about this to even know if they did enough or not, but it seems to me the email thing should have been caught before it was able to queue up and start sending 90,000 emails. They'd still be going through that queue if I hadn't tried to send an email and noticed what was happening.

Just thought I'd give an update.

Lesson #1 is that they weren't lying...
Lesson #2 is to make sure your server isn't being used to send out massive amounts of spam and probabally don't even host your own email on your cpanel either...

At least next time I have a site get hacked, I'll know to keep an eye on the emails.

Has anyone recovered from a domain being blacklisted?
 
It doesn't take much for your site to become vulnerable.

Some plugin updates and like idiots announce that they updated due to a specific vulnerability. Now all hackers need to do is crawl the web to see who's using any version that's not the most recent.

Same with these theme developers. Those option panels with the ability to change every specific detail of the theme is convenient, but it's introducing a zillion variables and it only takes one screw up to open you up to an attack. One unsanitized form input can leave you open to an SQL injection and in 3 or 4 steps your login and password are literally being loaded on your webpage. That's the least sophisticated method.

Really, all of this stuff makes you a low-level target for script kiddies. If you lock that down, you'll be invisible for the most part because the small timers can't get to you and you're not worth the big timers attention. That's how I think of it anyways. Nothing is safe. Take rolling daily backups.

It seems like once someone is in your server there should at least be some kind of administrator change log your server company should be able to look at and match to any IP that's not your own. Then again, maybe they spoofed yours. I have no clue what's possible. @SmokeTree might have insight into why this mass emailing wasn't caught.

I think the learning curve of rudimentary HTML / CSS / JS / PHP is well worth dealing with to dodge a lot of these issues, allowing you to replace plugins and theme features with the most simple form possible that you created yourself. You also get massive speed benefits. Security is part of the trade off though, especially when you're buying anything that's not on the Wordpress repository.

You can run the official Wordpress Theme Check Plugin on a theme and see the million ways it wasn't qualified for the repository. Some of it is pure nonsense but some of it shows you where you're vulnerable too. I can guarantee that most non-WP approved themes will throw up a ton of flags, even on the most up-to-date versions.
 
First off, sorry to hear that your WP site was compromised. As @Ryuzaki mentioned, it doesn't take much at all to compromise a site. The 2 biggest culprits I've seen are improper file permissions and/or rogue/poorly coded plugins.

Being that I don't know how your hosting provider is configured, I'll make this as general as possible and talk about the most common setup I see in the wild. On a typical server there are mail server, webserver and system logs at the very least. In a lot of cases with shared hosting/multiple sites, the web server logs are configured per site so each site can have its own log file. The directory the log files are kept is commonly outside of a public HTML root which would require a hacker to go backwards from the WP root directory to get to and "remove". I'd recommend asking your hosting provider what logs they are referring to and why they think the files were removed. Anything happening on the server, even remotely, should be logged by one of the files mentioned above. As far as "standard practices" go, there really aren't concrete standards, just good guidelines to follow and making sure that logging is enabled should be a given for any serious hosting provider/sysadmin.

Re email config: With a properly configured email server, no one should be able to send emails from just any random alias and certainly not from just any IP. The email server should, at the very least, check to ensure that the originating email is valid. What you describe sounds like a possible open-relay condition (https://en.wikipedia.org/wiki/Open_mail_relay) and/or a very poorly configured email server. Configuring SPF (https://en.wikipedia.org/wiki/Sender_Policy_Framework) and DKIM (https://en.wikipedia.org/wiki/DomainKeys_Identified_Mail) should also be high on the TODO list.

A note on IP spoofing: Traditional IP spoofing (https://en.wikipedia.org/wiki/IP_address_spoofing) is generally used for DDOS type attacks where the attacker isn't concerned about the response from the server. What happens in that case is the IP packet header is forged to show a false originating IP. The response is sent to the IP contained in the header and is obviously not the real originating IP which prevents bi-directional communication. The gateway at your hosting provider should have ingress filtering to reject spoofing of IP addresses inside the network. That being said, it's not likely a hacker is doing anything other than using SOCKS proxies and/or VPN to put a layer between them and your server.

I'm going to look into setting up a better htaccess file that'll block the IP address at LEAST of people outside of my continent

Shameless plug alert: The article I wrote for the Digital Strategy Crash course (https://www.buildersociety.com/threads/day-24-site-security-online-privacy.1361/) might be of interest to you as it goes through file permissions, basic security concepts and I even touch on why .htaccess should be used as sparingly as possible.

One final word. Any site that has been compromised should be taken offline and evaluated with great scrutiny before putting it back online because you never know how many potential backdoors there could be. Hope this helps. If you have any questions, feel free.
 
@j a m e s That sucks bro, huge pain I know. I've dealt with similar and was able to get the email back in good standing by switching the email server to Google with https://apps.google.com - It's $5/mo per account but you can have up to 30 "aliases" that go to the same inbox per account.

Also +1 for KnownHost, they've been top notch in my experience.
 
Thanks everyone, I appreciate your time and your thoughtful responses. I've got a list of things to do and was able to add a few more. I'll definitely be hosting my email elsewhere from now on, rather than on the same servers as my sites. I'm going to see if there's a way to just completely disable email so that even if someone gets in again, they can't send anything.

I'm on the fence about switching hosts, I have such a good plan with WT and they're always quick to respond 24/7. It annoyed me when their support guy was like "These malware scans that we run are just provided as a courtesy ... If you need a security expert to look at your site, you should hire one."

https://www.wiredtree.com/support-services/proactive-monitoring/

"We provide advanced monitoring for your server and the services on it. Each server comes with 24/7/365 monitoring, anticipating, diagnosing and correcting any problems, so you can rest easy knowing we’ve got you covered."

I know it's just marketing speak, same with the other link in my last message that talks about how hard their servers are and how it stops brute force attacks and spam and all those other things that didn't end up getting stopping ... And I know this can and does happen with any host... but it still rubs me the wrong way that 90,000 spam emails can stack up and that still doesn't set off any red flags for being 'proactive'. I asked how that doesn't trigger any kind of heads up, and he said it's not necessary because people will notice their email has been hacked when they try to send an email and it doesn't work.

Would any of you switch hosts, or is this pretty much par for the course?
 
Would any of you switch hosts, or is this pretty much par for the course?

Back before they started to cut costs and cut back on support, even HG used to be more than happy to clean up almost any kind of mess and help you with the results of hacking.

I'd definitely switch if you're paying for fully serviced hosting. If you wanted to deal with 'things' yourself you'd have bought or rented a super cheap unserviced server and done everything yourself, after all.
 
I'd switch to Knownhost and never look back. There's a reason they cost a little more, although still very cheap. Their support is god-tier. They'll literally do anything you ask them, immediately. Fully managed is no joke over there. I suspect they might send a rep out to cook me breakfast if I phrased it correctly.
 
Shitty situation, I've been there many times. Out of all the hosting companies I've used (30+), Wired Tree is definitely not at the top of the list. Before I knew what a crawling load on a server was, Wired Tree could not properly advise me on a box that kept going down consecutively a few years ago. "You need to upgrade" was always the answer. lol Needless to say, brought down their highest available stock config at the time... It was then I realized I was at Toys R Us, when I needed to be at the Mack dealership if you know what I mean.

Your unfortunate situation isn't their fault, but there's a few things you could look for that will make your life easier by switching hosts. Doesn't seem like you have any admin experience, so one of the easiest things you could do is get yourself in a pseudo cloud based environment... Fully managed of course.

If you look at a company like Liquid Web, you have the ability to clone a server at any time, as well as daily backups. This is different than a website backup, whereby the entire container is getting replicated. For instance, if you were to encounter this issue again with no experience, you could simply have the support techs go through the logs, identity the vulnerability date, and roll back the entire server to the day before. You can then clone the server when it's in "safe mode", and redeploy at any time if your mitigation attempts were unsuccessful.

Not the perfect solution, but works pretty well to get by without experience. Half the time with most of the big box hosting providers, it's knowing what questions to ask. Unless you get a hold of a tier 3 or NOC tech, a lot of what you're asking falls on deaf ears... Or so it would seem.

Liquid Web isn't the only provider who has these features by any means, but very reliable and has 365 phone support which is a must... I still keep a dedi there to this day. Knownhost is awesome if budget is a concern, but a completely different setup.
 
I asked for a new IP address (Not sure if it would even really help, but I want a victory here no matter how small lol... They said earlier that a new IP would help with the whole email blacklist thing potentially, but I'm going to be grabbing google apps or zoho either way. I guess my server has 1 ip addresses, and they wanted to switch from one to the other) and they said I can't have one because my site may still be infected. =\

I'd hope for more of a "Your site might still be infected, so we'll get a server admin to dig deeper and make sure that it's not."

I always thought wired tree had a reputation right up there with the likes of liquid web and knownhost, but it sounds like they're a tier lower now perhaps, I dunno. I've decided I'm going to get this all settled down, and then switch. It's nice having a $90/mo server for $45/mo from WT, but it's not like I'm using anywhere near those specs anyways, I just over-bought to lock in the deal... but now I'm realizing that when I'm at a point where I'm maxing out the server, the price of the server is a drop in the bucket anyways.

Also realizing I've been at this game for too long to not know more about the server and code side of things, so this has been an eye-opening experience and I'm going to definitely use it as a catalyst to expand my personal toolbox of skills.
 
Really, all of this stuff makes you a low-level target for script kiddies. If you lock that down, you'll be invisible for the most part because the small timers can't get to you and you're not worth the big timers attention. That's how I think of it anyways. Nothing is safe. Take rolling daily backups.

TRUTH.

It's like protecting your home from criminals. NOTHING is impenetrable. The main goals are:

  • Make it difficult
  • Make it time-consuming
  • Make it costly
Do that, and you're solid when it comes to all of the average, apathetic hackers out there. The average ones, are precisely like the average criminal in that they are all about the quick and easy score. A dedicated and focused opponent will eventually find a way, but they tend to only go after the truly big scores where they stand to gain the most.

Sorry to hear about your troubles. Had one of my WP sites hacked a few years ago, which really ruined one of my businesses and opened my eyes. That really started my hatred for WP.

Beyond the obvious stuff (little to no plugins, update frequently, etc.), here's a few things that might help, if they're an option, depending on your situation:

Complex passwords

This is obvious but, it always bears reiterating. Easiest place to start is coming up with a realistic way (that you can stick to consistently) to generate and store complex passwords. Simple/low-level attacks, like a dictionary attack, are much more likely to be successful with short passwords that contain common words, phrases, etc.

Easiest thing is using a generator like KeePass. Create long, complex passwords (like 30-60+ characters) that contain all different types of characters. For fun, on one site that I unfortunately must still maintain Wordpress for the time being, I have 500+ character passwords. Literally takes like 3 minutes just for the password to SAVE. LOL

Figure out a secure storage method. Now get used to copy/pasting passwords (preferably only over a VPN or otherwise encrypted connection so you don't leak any cleartext anywhere).

SELinux

This may not be available on your server, or it may not even be an option for some servers, depending on the type of hosting and server structure/architecture. Also, if you don't have experience with backend stuff, this option is probably not a great place to start. If it is an option, though, it's one I highly recommend considering investing a bit of effort into learning how to utilize, provided you actually have time for mundane backend stuff (most people probably don't). People hate this one, but they simply don't understand how to use it. SELinux is basically a program/system of creating and monitoring security policies across files, directories, processes, etc. It provides a layered defense to a good degree of access and attack vector restrictions.

Once they get their foot through the door, a big focus of most hackers is the lateral attack. You gain access somewhere obscure, or you successfully run some exploit, and you find yourself a bit farther through the door. Now where can you go from there? Oh what's that you say? Here's a vital system folder with recursive 777 permissions, because someone took the "easy way" to fix some function permission issue that was giving them an annoying warning message. Well, with SELinux, you can really start to layer those defenses. A word of caution, however. Most of us really can't afford the time to dive deep into hand-crafting complex security policies to try and plan for every possibility. Just remember, time is money. Figure out your "Pareto" here (the 20% that does 80% of the work), knock those things out, then move on.

To cut to the chase, here's the highlights. SELinux has 3 main modes:
  • Enforcing
  • Permissive
  • Disabled
Disabled is obvious = not even once. The cheater's way out, if you have SELinux installed on your server.
Enforcing means SEL is actively enforcing your policies, blocking what should be blocked, etc.
Permissive is where most beginners probably need to start. Think of it as "training" mode, only it's yourself that's being trained. In effect, policies are being monitored, are generating logs, but are not actively restricting. In short, set SEL to Permissive, then just go start doing stuff. Mod your site, save files, just generally do stuff you do. Keep checking the logs, noting any errors/blockages. Implement policy changes so that important files, directories, and processes have appropriate access levels to ensure proper function.

Sorry, running out of time tonight. Here's a few links and vids with more on SEL:


https://wiki.centos.org/HowTos/SELinux
https://wiki.gentoo.org/wiki/SELinux/Tutorials/Permissive_versus_enforcing
https://www.centos.org/docs/5/html/Deployment_Guide-en-US/rhlcommon-chapter-0001.html
http://www.serverlab.ca/tutorials/l...ring-selinux-policies-for-apache-web-servers/
https://francispereira.com/deploying-wordpress-with-selinux-enabled.html
 
https://squidix.com/

using the semi dedicated for a long time . No issues at all

also know this guy on skype - cainhosting.com

Always talks about security and how he is patching his servers .Must be good
 
Last edited:
For money sites that I care about and that is making me money, I would subscribe to Sucuri so they will monitor your server constantly and act ASAP if something happens worth the investment in my opinion.
 
I should have prefaced my last post with this disclaimer. I kind of touched on this, but I probably could have stated it in more of a clear manner:
There are a LOT of options to improve security that do not necessarily require an expert level of knowledge or programming. For the average site owner that maybe just has one or a few affiliate sites, the majority of your time is likely filled with WORK and actually implementing ideas towards forward progress in your business. In essence, most people probably don't have the time, and in fact it might even be detrimental for them to spend significant time on mundane and in depth back end stuff for security purposes. Remember the Pareto principle, and consider whether to invest the time yourself, or whether it would be better to simply invest money in services or a developer that can mitigate these problems for you.

That being said, I had a few more recommendations on both sides; in depth technical or high level and relatively efficient.

Write Your Own Plugin

One WP tactic is simply minimizing possible attack vectors by minimizing the plugins you have installed and/or are using. Honestly, lots of simple plugins are practically unnecessary as an entire separate plugin. For example, I've seen so many people use the Yoast program almost entirely just so they have "pretty" meta tag fields to fill out... That's a whole LOT of code, for a popular plugin that is heavily targeted by hackers, if all you need is a couple custom fields... (more on that below) Much of the time, we might find ourselves using an entire separate plugin for simply one single function that it performs. So why not just mash that individual piece of code (where legal and license terms allow, of course) into your own super plugin to consolidate all of that stuff? You would then have a "portable" option to use across other sites you might have.

You will want to consider the fact that, if you're creating your own plugin, YOU might also inadvertently create your own security vulnerabilities. :wink: Most of the time, though, we're usually talking about features and functions that are relatively simple, and just make our lives a little bit easier. For example, I highly recommend checking out the thread about the BuSo Lightning WP theme by Ryuzaki (and check out the theme too; excellent, fast, and minimalistic!). Take note of users' comments in the thread, and some of the custom solutions people have come up with for some of those relatively simple functions (qwianghomingh has a bunch of good ones). For one site, I might just modify my existing PHP files. If I'm running multiple sites and need to reuse those functions, that's when I might just bake them into my own custom plugin for easy reuse. Here's a few decent articles to get you started:

https://codex.wordpress.org/Writing_a_Plugin
https://www.smashingmagazine.com/2011/09/how-to-create-a-wordpress-plugin/
https://www.elegantthemes.com/blog/tips-tricks/how-to-create-a-wordpress-plugin

In short, getting started is as simple as:
  • Create a folder in wp-content/plugins (Ex: wp-content/plugins/badass-plugin)
  • Create a PHP file in this folder
  • Add a header to your PHP file (this tells WP your plugin is a plugin, allowing it to show up in your WP plugins dashboard)
  • Add some code to your PHP file
That's all there is to it! Here's an example of some simple functions:

Code:
<?php
   /*
   Plugin Name: Deathstar Plugin Of DOOM
   Description: My plugin
   Version: 0.1
   Author: Restricted
   License: Restricted
   */

// Clean up unnecessary stuff in HEAD section

remove_action('wp_head', 'rsd_link');
remove_action('wp_head', 'wp_generator');
remove_action('wp_head', 'feed_links', 2);
remove_action('wp_head', 'feed_links_extra', 3);
remove_action('wp_head', 'wlwmanifest_link');
remove_action('wp_head', 'wp_shortlink_wp_head');
add_filter('the_generator', '__return_false');
add_filter('show_admin_bar','__return_false');
remove_action( 'wp_head', 'print_emoji_detection_script', 7 );
remove_action( 'wp_print_styles', 'print_emoji_styles' );

?>

^ Don't just blindly copy that without knowing what you're doing and what you want to accomplish, as that's just an example. If anyone sees any issues with that code, please feel free to correct me, as I did it from memory and can't currently access one of the custom plugins I've written, to verify it.
 
This may seem obvious but, it's worth considering taking a few extra steps to completely eliminate access for at least certain components of WP. Here's a couple things that can help:

IP Restrict Logins

If you have a site that does not allow user accounts for visitors, then you might as well restrict access to any account/login pathways. The thing to determine here is whether you only ever work on your site locally, or whether you're often doing so remotely as well. This will determine exactly how you might want to implement this. For example, if I only work locally, I might IP restrict everything except my own local IP. Everyone else trying to access wp-login.php or /wp-admin/ would just get a 403 error. You can add other files/directories to this as well. You'll want to test and verify with a proxy or other non-local connection, to ensure you don't end up breaking functionality of the user-facing parts of your site, and that you're not actually blocking yourself.

For Apache servers, here's what you can add to your .htaccess file to accomplish this:
Code:
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{REQUEST_URI} ^(.*)?wp-login\.php(.*)$ [OR]
RewriteCond %{REQUEST_URI} ^(.*)?wp-admin$
RewriteCond %{REMOTE_ADDR} !^123\.123\.123\.123$
RewriteRule ^(.*)$ - [R=403,L]
</IfModule>

Just add additional REQUEST_URI lines for other files and directories you want to restrict. REMOTE_ADDR is for setting your local IP and restricting all else. Add additional REMOTE_ADDR lines if you have multiple IP's you work from.

For NGINX, you can add this or something similar to your nginx.conf:
Code:
location ~ ^/(wp-admin|wp-login\.php) {
                allow 1.2.3.4;
                deny all;
  }



Password Protect Login

Require a password...before you can even enter your password. In effect, a 2 step login. One additional layer of security. Even better, generate an insane, unique, 500 (or whatever size) character password for

For Apache .htaccess:
Code:
<Files ~ "^\.ht"> Order allow,deny Deny from all </Files>

<Files wp-login.php>
AuthUserFile ~/.htpasswd
AuthName "Private access"
AuthType Basic
require user thisisyourusername
</Files>
You can use this to generate your .htpasswd file, and store it where your .htaccess file is. You'll now have to enter 2 passwords before you're logged in to your site.

For NGINX nginx.conf (you'll still need to generate an .htpasswd file and store it, like above):
Code:
location /wp-admin {
    location ~ /wp-admin/admin-ajax.php$ {
        # PHP Handler
    }
    location ~* /wp-admin/.*\.php$ {
        auth_basic "Authorization Required";
        auth_basic_user_file  /home/path/to/passwords/.htpasswd;
        # PHP Handler
    }
}
In the NGINX example, we're restricting the entire /wp-admin/ subdirectory, but still allowing admin-ajax.php. Once you start blocking and limiting access to the /wp-admin/ subdirectory, admin-ajax.php can start having issues. Since a great many plugins use that file for performing various functions, this is something you're going to have to determine for your site. Just beware, some of the code above will probably cause admin-ajax.php issues. There are modified methods of some of the above codes, to account for this, but that's something you'll have to determine whether you need to do or not.

If you'd prefer to just password protect wp-login.php in NGINX, this should work:
Code:
location ~* (wp-login)\.php$ {
    auth_basic            "GTFO: srsly bro";
    auth_basic_user_file  /home/path/to/passwords/.htpasswd;
}

When in doubt, just monitor your server logs and take note of things like PHP errors or warnings, as your blocking/limiting efforts may have interfered with the normal function of something important.



Rate Limit Login Attempts

There's a WP plugin of a similar name, though I don't know that I can recommend it, seeing as it hasn't been update in something like 4 years. Generally speaking, though, what you'd be trying to accomplish with this is rate limiting to mitigate brute force/dictionary style attacks. It takes nothing for a script or malicious program to fire off an endless and massive number of password variations against a login gateway. It's only a matter of time before they succeed, provided they are allowed enough time and attempts.

The strategy I like to use here is to limit to 1 or 2 attempts, with a healthy, temporary IP ban for a long enough period of time (say 15 minutes). If you use that restrictive of a strategy, just beware that you better be used to copy/pasting your hopefully ridiculous (hundreds of random characters is awesome lol) passwords so that you are assured a perfect login, or else you're just going to annoy yourself. The great thing with this is, no more worrying about bots firing off hundreds or thousands of attempts per second.

As far as how to do it, here's a nice writeup for NGINX:
https://easyengine.io/tutorials/nginx/block-wp-login-php-bruteforce-attack/

As far as Apache, unfortunately it's been about 5 years since I've used an Apache server, and I didn't see a decent writeup after a quick search, so you're on your own with that one.

Try to use as many of these different methods to protect your site(s) and you will have created a layered defense that will largely make your site a significantly less attractive opportunity for the average hacker.
 
Brilliant, thank for you taking the time to explain all of that! I am going to implement as many of these as I can.

Can anyone recommend a service for looking through my site and making sure there aren't any leftovers from the previous hackings? My host won't give me a new IP address until I can prove to them that it's clean. It might all be moot, since I plan on switching anyways, but in any case - it would be good to know that it's all good. What does that even involve? Having a security expert look through each line of code for anything malicious? I asked the host if they could check the dates that files were edited to see if the hackers changed anything else, and they said it's pointless since some of them would be overwritten already and that the rest of them can be easily faked.

I spent a few hours last night getting a different site setup on a flat file CMS on an unmanaged server. Flashbacks to IRC and MS DOS. I just wanted a break from this wordpress stuff. I'm going to keep playing around with that, but I don't think it will be practical to make the switch for all sites, especially ones that will be sold. None the less, the whole process of changing settings and adding a theme has been interesting.
 
I feel your pain man. I, myself, am in the process of attempting to convert a lot of sites over to the Hugo static site generator, built on Go (Golang), as the performance looks damn impressive. I'm still a bit on the fence, at least with certain sites, as moving away from a dynamic site architecture has the potential to significantly restrict, or at least complicate, the potential for user interaction.

I wish I had more recommendations for a service to audit your site/server, but unfortunately I'm not up to date on what's available out there now.

One thing I'm really liking the idea of lately, is attempting to achieve something akin to a self-replicating server. Digital Ocean seems nice for this. Basically, create and configure your droplet (server), setup your site, then take regular snapshots of your droplet. Site got hacked significantly? No problem. Kill that droplet, then spin up a copy with the snapshot. I'm not 100% sure that it will completely work like this without issue, but theoretically it can. Worst case, maybe lose a few days worth of posts and activity, but it has the potential to eliminate a whole lot of stress, if you knew that you can just clone your droplet with a known good copy, and not have to worry about what could have still been hiding on the previous droplet.
 
This may seem obvious but, it's worth considering taking a few extra steps to completely eliminate access for at least certain components of WP. Here's a couple things that can help:

IP Restrict Logins

If you have a site that does not allow user accounts for visitors, then you might as well restrict access to any account/login pathways. The thing to determine here is whether you only ever work on your site locally, or whether you're often doing so remotely as well. This will determine exactly how you might want to implement this. For example, if I only work locally, I might IP restrict everything except my own local IP. Everyone else trying to access wp-login.php or /wp-admin/ would just get a 403 error. You can add other files/directories to this as well. You'll want to test and verify with a proxy or other non-local connection, to ensure you don't end up breaking functionality of the user-facing parts of your site, and that you're not actually blocking yourself.

For Apache servers, here's what you can add to your .htaccess file to accomplish this:
Code:
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{REQUEST_URI} ^(.*)?wp-login\.php(.*)$ [OR]
RewriteCond %{REQUEST_URI} ^(.*)?wp-admin$
RewriteCond %{REMOTE_ADDR} !^123\.123\.123\.123$
RewriteRule ^(.*)$ - [R=403,L]
</IfModule>

Just add additional REQUEST_URI lines for other files and directories you want to restrict. REMOTE_ADDR is for setting your local IP and restricting all else. Add additional REMOTE_ADDR lines if you have multiple IP's you work from.

For NGINX, you can add this or something similar to your nginx.conf:
Code:
location ~ ^/(wp-admin|wp-login\.php) {
                allow 1.2.3.4;
                deny all;
  }



Password Protect Login

Require a password...before you can even enter your password. In effect, a 2 step login. One additional layer of security. Even better, generate an insane, unique, 500 (or whatever size) character password for

For Apache .htaccess:
Code:
<Files ~ "^\.ht"> Order allow,deny Deny from all </Files>

<Files wp-login.php>
AuthUserFile ~/.htpasswd
AuthName "Private access"
AuthType Basic
require user thisisyourusername
</Files>
You can use this to generate your .htpasswd file, and store it where your .htaccess file is. You'll now have to enter 2 passwords before you're logged in to your site.

For NGINX nginx.conf (you'll still need to generate an .htpasswd file and store it, like above):
Code:
location /wp-admin {
    location ~ /wp-admin/admin-ajax.php$ {
        # PHP Handler
    }
    location ~* /wp-admin/.*\.php$ {
        auth_basic "Authorization Required";
        auth_basic_user_file  /home/path/to/passwords/.htpasswd;
        # PHP Handler
    }
}
In the NGINX example, we're restricting the entire /wp-admin/ subdirectory, but still allowing admin-ajax.php. Once you start blocking and limiting access to the /wp-admin/ subdirectory, admin-ajax.php can start having issues. Since a great many plugins use that file for performing various functions, this is something you're going to have to determine for your site. Just beware, some of the code above will probably cause admin-ajax.php issues. There are modified methods of some of the above codes, to account for this, but that's something you'll have to determine whether you need to do or not.

If you'd prefer to just password protect wp-login.php in NGINX, this should work:
Code:
location ~* (wp-login)\.php$ {
    auth_basic            "GTFO: srsly bro";
    auth_basic_user_file  /home/path/to/passwords/.htpasswd;
}

When in doubt, just monitor your server logs and take note of things like PHP errors or warnings, as your blocking/limiting efforts may have interfered with the normal function of something important.



Rate Limit Login Attempts

There's a WP plugin of a similar name, though I don't know that I can recommend it, seeing as it hasn't been update in something like 4 years. Generally speaking, though, what you'd be trying to accomplish with this is rate limiting to mitigate brute force/dictionary style attacks. It takes nothing for a script or malicious program to fire off an endless and massive number of password variations against a login gateway. It's only a matter of time before they succeed, provided they are allowed enough time and attempts.

The strategy I like to use here is to limit to 1 or 2 attempts, with a healthy, temporary IP ban for a long enough period of time (say 15 minutes). If you use that restrictive of a strategy, just beware that you better be used to copy/pasting your hopefully ridiculous (hundreds of random characters is awesome lol) passwords so that you are assured a perfect login, or else you're just going to annoy yourself. The great thing with this is, no more worrying about bots firing off hundreds or thousands of attempts per second.

As far as how to do it, here's a nice writeup for NGINX:
https://easyengine.io/tutorials/nginx/block-wp-login-php-bruteforce-attack/

As far as Apache, unfortunately it's been about 5 years since I've used an Apache server, and I didn't see a decent writeup after a quick search, so you're on your own with that one.

Try to use as many of these different methods to protect your site(s) and you will have created a layered defense that will largely make your site a significantly less attractive opportunity for the average hacker.

This is an awesome resource. I need to remember to come back to this and implement it in a few weeks.
 
Just a small update. Setup DKIM and SPF (Or something like that haha) on the site that as originally hacked. The IP that was blasting out all that spam doesn't seem to be blacklisted anymore, and I've got my email setup with Zoho moving forward on a new IP address.

It was fun playing around with flat file cms on non-managed servers but it's too much of a can of words for me right now, I'm going to be moving that site (Not the same site that was hacked btw) back to Wordpress on a manager server.

I've got page size ~400kb and ~400ms loading time for my homepage on Wordpress and only slightly higher on article pages (Mind you, haven't added ads back yet... Wanted to let the dust settle re: the whole hacking thing first), and still in the process of patching up as many holes as I can based on all of the great advice in this thread. What I'm still missing is finding somebody I can hire to check it all over so that I'm not just relying on my host's impression that everything is okay, for now just keeping a close eye on everything and waiting for all those spammy pages that the hacker created to finally clear out from Google's index. I have been submitting some of them for removal one at a time, but just opted to create a new sitemap and submit that instead.

I'm going to put a lot of the things mentioned in here and in the crash course into a step-by-step really concise checklist that I'll follow when creating new sites, if anyone's interested in a copy, but it won't have anything that isn't already mentioned.

Anywoo... that's it for now.
 
For Apache .htaccess:
Code:
<Files ~ "^\.ht"> Order allow,deny Deny from all </Files>

<Files wp-login.php>
AuthUserFile ~/.htpasswd
AuthName "Private access"
AuthType Basic
require user thisisyourusername
</Files>

I had a heck of a time getting this to work. I don't think that's the right relative file path for the same place .htaccess is at. Doesn't that indicate /home/.htpasswd ? Seems like you'd want /home/unix_username_or_whatever/public_html/.htpasswd

The official Apache docs say: "The AuthUserFile directive sets the name of a textual file containing the list of users and passwords for user authentication. File-path is the path to the user file. If it is not absolute, it is treated as relative to the ServerRoot.

I wasn't sure what the implications above meant other than how I interpreted them as being outside public_html. In the end, I said screw it and went with an absolute path and locked down .ht files as you suggested.

Any insight into this?

Oh, and does this drop a cookie or something? I'm having all kinds of weird behavior. With caching and CDN's and all that It's making me nervous.
 
@Ryuzaki sorry that was off! I haven't had an Apache server in ~4 or 5 years, so I unfortunately don't have a way to test it right now. The path will differ, depending on people's server setup. The basic function names should be good though.

As far as cookies, can you explain what you mean and the behavior you're seeing? I don't know how this would have any effect on caching or cookies? Only thing I can think of is, with the "deny" commands, maybe depending on the server structure and the exact directory all of this is located, maybe there are other things in that directory that have some involvement with cookies or caching?
 
Back