WordPress site hacked! How to Identify, search, and destroy malicious code

So recently when doing an update to a client’s site, I noticed some strange at the top of php file. Uh-oh, I’d seen this before and knew what that meant. The site was hacked. Expecting the worst, I logged into my site and started to identify, search, and destroy this code. Since the steps to do this aren’t always straight-forward, I thought I’d do a post on the steps that I took, along with some comments about the process itself. It’s a little technical and perhaps intimidating for users, but with some time and effort, you can get through it.

Uh-Oh! I’ve been hacked… I think?

The first step is to identify that you’ve been hacked. It’s important to realize that there are MANY kinds of hacks that take advantage of various vulnerabilities, either in PHP itself (very rare), the WordPress codebase (rare, but it happens, like in the Trojan emoji vulnerability of 2015), plug-ins ( common ). There are different ways that these hacks happen, but most of the time, the first place you’re going to look are your Plugins. If you’re using Plugins that haven’t received an update in a while, or plug-ins that are rare, don’t have many installs, or not maintained, watch out! There’s a chance that these Plugins could have some code that allows a hacker to inject stuff into your PHP files.

What’s ZM5j2q0shf_pirogok?

The particular hack that this site was infected had attached itself to a bunch of PHP files. The files all started with a whole bunch of blank characters and then what looked like a bunch of gobbledygook.

Blanketty-blank-blank-blank characters

Why start out with blank characters? Well, it turns out it’s a clever trick to try and hide the code. If you open up a text editor that doesn’t wrap text, you won’t see any of the code. Tricky. I usually have word wrap on by default on my text editor (SublimeText) but editors like vim usually don’t.

 Why Equal (==) is the Magic Character Combo

Essentially, there was some php at the beginning of some files that started out like this:

function  I8tc9h3RL1CtBlQ($WyzWpwAZHM,$Mk6sP4LS3,$QLvCeO4qvJET8r9vR){return str_replace($WyzWpwAZHM,$Mk6sP4LS3,$QLvCeO4qvJET8r9vR);} function  dRKTwncRUH17OKllfQIa($WyzWpwAZHM,$Mk6sP4LS3,$QLvCeO4qvJET8r9vR){return str_replace($WyzWpwAZHM,$Mk6sP4LS3,$QLvCeO4qvJET8r9vR);} function  Y4y67oHbY0SE($WyzWpwAZHM,$Mk6sP4LS3,$QLvCeO4qvJET8r9vR){return str_replace($WyzWpwAZHM,$Mk6sP4LS3,$QLvCeO4qvJET8r9vR);} $QN6bbTRMgYvIF5BavP4k = 'bgMJbBXqYz3Jc0LeJsQPagM...

So, I did what any curious developer would do. I searched for the name of the first function I8tc9h3RL1CtBlQ as this looked like a hack. I wanted to know more about what was going on before taking action. Google turned no results. DuckDuckGo provided one result, but it wasn’t terribly helpful. Then I noticed something. Near the end of the 26,000+ character line… there was two equal (==) signs.

...FYVG5ST1J6bExVakExTWxsdE5WTmlSMHAxVlc1d1RGWklUa3hhYkVaM1QxVk9jRkZWZEdsTmEzQnRXWHBPVTJGSFRuVlZWemxLWWtoQ1QxUnNaSFpsVjA1VlVXNXdhRkl4Y0cxWFZFcEhZekpLU0ZOdGFGcE5iazV3VXpGU2VsTXdUblZOUlhSdFZWaEJOVkV5WXpsUVUwbHdTMVJ6WnlJcEtUc2ciKSk7IA==');?>

Ah-ha! Now, I knew what I was dealing with here. Whenever you see 1 or 2 equal sign at the end of a string, it means that the string is probably Base64 encoded. It’s actually padding do to how the encoding works, and if you want to know more I wrote a post on the ins and outs of Base64 encoding. There are plenty of online Base64 encoders online, so I went to one and decoded that string  "ZXZhbChiYXNlNjRf ...EtUc2ciKSk7IA==" and ended up with… eval(base64_decode("ZXZhbCh...yIpKTsg"));. Yep, another base64 encoded string. So, I took THAT string, and decoded that. Another base64 string. It was base64 encoded 5 times! FINALLY, a bunch of code was output:


error_reporting(0);
if (!function_exists("ZM5j2q0shf_pirogok")){
  function ZM5j2q0shf_pirogok(){
  return false;
}

Well, turning off error reporting. Definitely not good. I won’t go into the details of what the script does, but searching for ZM5j2q0shf_pirogok yielded some results on Stack Overflow as well as other places, which I encourage you to check out.

Before we get to fixing stuff… why would a hacker care about your site? Maybe you just run some small hobby site? Well, wrote an article about why hackers care about your site, but the short answer is that there’s money involved. And it’s usually not what you think. It’s usually NOT so dramatic as trying to hack your site so that they can extort money out of you. In any case, it’s time to go on to the next step.

Next step… search and destroy

My next focus was getting rid of this malicious code…. and making sure it didn’t happen again. How could I be sure that I found all the files where this code was? This article is getting kind of long, so in my next article, I’m going to talk about how the unix commands grep  and find  are your new BFFs.

Leave a Reply

Your email address will not be published. Required fields are marked *