I saw a new hack last week, and it scared me quite a bit.
Usually, I see hacks along the lines of compromised files. An attacker gains access to your site, uploads a file to the server, and uses that compromised file to hijack your site and do whatever they want.
I’ve seen compromised PHP files, compromised JavaScript, compromised HTML. Once I even saw a PHP file tacked on to the end of a PNG – the image looked fine, but loading its contents as a string and [cci]eval()[/cci]ing them to execute a payload.
It’s frustrating to see any hack on your site, but the variety above are fairly straight-forward, both to detect and to fix. It can take a long time to clear out all of the corrupt files, but with automated tools that verify checksums of, say, WordPress’ PHP files against a vanilla distribution, you have at least some help.
The Hack from Hell
Last week’s hack, though, was a different variety.
The first time I visited my compromised site,[ref]Note, it was not this site that was compromised but another one I host elsewhere. I’m 100% confident in the security backing this site. The site in question was on a new host with whom I had little previous experience.[/ref] I was redirected by way of a hidden iframe to some sort of spammy ad site. Inspecting the HTML of the compromised site showed some script injected into the body just below the footer.
I dug in, but nothing was wrong in WordPress. No compromised files existed in any plugins or the theme. Nothing looked wrong in our log files. Confused is an apt but insufficient term.
Add to this the fact that the exploit only affected first-time viewers – hitting the site a second time didn’t redirect the page. It didn’t even inject code into the footer.
It turns out the exploit was actually far deeper in the system than WordPress. Someone somewhere had gained access to another account on the same physical machine and used that access to push sideways into the virtual machine running the site. They replaced the Nginx binaries with one of their own design that kept track of visitor IPs and, when a new IP was detected, automatically injected a script tag after an HTML comment in the site’s output stream.
I’ve since changed all of my server passwords, regenerated SSH keys, and invalidated old ones. I’ve further locked down SSH access to my sites to a specific range of IPs, and also contacted my various hosts to help harden their security as well.
When someone hacks a plugin or theme, it’s bad. When someone hacks the foundation of those systems (WordPress), it’s worse. When someone hacks the base upon which WordPress is built (Apache, Nginx, or whatever server you use), it’s tragic.