Disinfecting a hacked WordPress site

Recently I took over management of a WordPress site for a nonprofit that had been hacked at some point in the previous few months, and my job was to recover it.  It had been hosted at the time on GoDaddy and it appeared that there had been a GoDaddy-specific exploit that the hackers had known of.

Pretty quickly I found the hackers’ PHP files (for malware, it appeared) in both the webroot and under /app/uploads – so those were quickly deleted.  I thought that was it, but I was wrong.

The site was running a somewhat-dated version of WordPress, maybe 3.9 – so it was 6-12 months old, which isn’t too bad.  It used a hodgepodge of plugins though, and I was afraid to upgrade it for fear of breaking some plugin (I had not budgeted any debugging time to this).  So I didn’t upgrade WordPress core, but should have in retrospect: as it turned out, there was also a spam-relay PHP hack under /wp-includes that I had missed.  When I got the site up on a new locked-down server, I didn’t notice at first that the postfix queue was getting absolutely hammered with outbound mails from this domain – which wasn’t hosting email in any case.

So I was in a situation where there were dozens of mails entering the queue per second.  I had no idea where they were coming from, as this server wasn’t even the destination of the MX records for the domain.  So I did the following:

  1. Remove the MX records, and all associated A records (like email, smtp, webmail, etc.) from the zone entirely.  Now in hindsight I doubt it would have had any impact in this case, but if you’re not running mail on a domain, you don’t need any of that.
  2. Check the mail queue via mailq and individual mails via postcat.  There’s more detail on syntax as this link.  You can delete the entire queue via

    nice postsuper -vv -d ALL
  3. To be safe, I also set up postfix to reject all emails being sent from this domain, by following the steps here.

Eventually I thought to look at the access logs and found the hackers’ requests to /wp-includes which obviously is wrong.  I then did a clean reinstall of the WordPress core via git, and the outbound spam attempts ceased.

Moral of the story, always do a clean reinstall of the core.

Leave a comment

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