Investigating a WordPress Compromise

It’s been a while since I updated this blog, and this lack of attention (and falling behind a few versions in WordPress) led to this very site getting hacked! Fortunately, I was quickly alerted to it thanks to Google, and if nothing else, this presents an interesting case study in investigating what happened. Full details below.

It all started Saturday afternoon when I got an alert from the Google Search Console team. Long ago I set up my site in Google’s tool, and this led to the alert. It stated that it had detected some hacked content, providing a long URL ending in .amm. I quickly logged into my main Joomla site dashboard and saw nothing amiss. I also logged directly into the server via FTP by using WinSCP to look for that file, without seeing anything. However, attempting to log into the WordPress dashboard failed with an unknown user error. Trying to send a password reset also failed, stating that my email address was invalid. This tipped me off that something was definitely up

Since WordPress stores everything in MySQL, I logged into my hosting control panel and fired up phpMyAdmin. Data about users is stored in the wp_users table, and I opened that up. Sure enough, my existing admin account had been hijacked. The email address had been changed to javaintelegentcyber@gmail[.]com, and the username/password had also been updated. Googling that email address revealed that they call themselves ./51N1CH1 and are an Anonymous-affiliated bunch of hackers who go by other names such as United Islamic Cyber Force, etc. They appear to be based out of Indonesia. It also revealed that they had taken over a number of WordPress sites, as several people had complained about seeing their WP admin accounts taken over by this email address.

We had Identified the incident, now it was time for Containment. To do that, since I still had access to mySQL, I could take that admin user back by creating a new user following these instructions (I also could have just updated the data for the existing user). Once that was completed and I had reset the password to my main admin user and set all the other data back, I updated my WordPress instance from 4.8.5 to the latest version, 4.9.4.

Next was the Investigation piece. As you will no doubt recall, I had long ago set up a pull of my website logs into Splunk. Thankfully this was still up and running, and so I had Apache logs. To figure out who had logged in, I did a simple Splunk query to show the successful POSTs to my wp-login.php page:

clip_image001

Aha! Now I had a source IP address, so I could easily search for events from that IP address (incidentally, the IP address was located in Indonesia, consistent with this group). Once I did a search for that in the Apache logs, I had an exact timeline of everything that happened, starting on the morning of 11 January 2018:

  1. The attacker arrived at my login page with a referrer header from hxxp://teti[.]az/wp-admin/network/anu/wp-login.php
  2. The attacker somehow was able to successfully authenticate (the POST above)
  3. The attacker navigated to my Plugins page
  4. The attacker then installed a new Plugin via the plugin-install.php page
  5. The plugin was successfully installed in my /blog/wp-content/plugins/Aviliate folder

While I was investigating these logs, I also had a search via WinSCP for any files that were touched on 2018-01-11. The only files that returned were all in that Aviliate directory again, providing confirmation that this was the backdoor they had installed. In my console, the plugin appeared as Akismet, which is a popular anti-spam plugin that many WordPress sites have, which made it blend in and appear to be legitimate.

I removed this plugin manually from my site for containment, but not before I downloaded a copy for investigation. Here’s where it started to get even more interesting. First, however, it was back to Investigation mode.

I returned to Splunk to see what traffic to this Aviliate plugin had occurred after installation. Turns out there was very little traffic to that plugin, but I did get a few hits from additional IP addresses. In addition, I saw a pattern in the traffic: the attacker would hit /blog/wp-content/plugins/Aviliate/user.php and then go to /NTI5enhqLzk2MjUvMjkvNDU5MDEvOQ== which certainly isn’t a valid URL on my site, or at least shouldn’t be. That meant that there was something interesting going on in that user.php file, so that was the next place to look.

That file was nothing more than a function to grab the contents of another site and PHP eval it. No legitimate PHP site grabs data from random URL and evals it, so this was clearly malicious. The URL was hxxp://elro[.]us/fina25/wso.txt, which Virus Total shows as malcious, hosting a PHP Backdoor Webshell (details here). Visiting that site over TOR brings up a fairly standard PHP backdoor console. This backdoor requires the user agent to look like an Indexer, otherwise it returns a 404. This would likely explain why so much traffic had suspicious user agent strings.

The afore-mentioned IP addresses all hit the user.php script then did various other things. Most were on the 11th and 12th of January, but I did find one repeat visitor who arrived at the site via Yahoo search. That particular search led to them hitting /NGlfMzgyMTVfaXRrYS90Xzg4Njdfa2F5.html, which may have been a persistent backdoor link. Further Splunk searches on that particular URL found even more visits from other IPs.

The original Google Search Console alert was for /eWYtOTgyNy1mdi8xNjEyLXZ1.amm, which I also search for in Splunk and saw a number of hits.

The other Aviliate file that was accessed was the file ass.php, which appeared be another file management tool called “B Ge Team File Manager”. Googling that term brings up an alarming number of sites that appear to have once had this backdoor as well. The attacker only accessed ass.php once on my site, POSTing something that I could not determine. As this event happened on 12 January, a search for files modified at this time returned two sitemap files, site_map.xml and home-site-map.xml. The former had a bunch of random URLs, including the ones above. This user also accessed a file that should not have existed, at /wp-content/uploads/2014/09/cropped-DSC04285.jpg, although searching for this file now returns no results.

Finding no other artifacts, I feel that this has been taken care of. A review of the Apache log from today shows continuing attempts to access certain URLs, but they all return 404s. Thus, this appears to have been Eradicated at this time. However, it was certainly an interesting exercise, and not all of the items that I found appear to be detected as malware. IOCs of the event below:

Type Value Note
Email javaintelegentcyber@gmail[.]com Email address for altered WordPress admin user
IP 114.125.62.180 Initial attacker IP
URL hxxp://teti[.]az/wp-admin/network/anu/wp-login.php Referrer for initial attack
MD5 90d3aea687c0b53e69f8100fd7ed5f07 admin.php in Aviliate plugin
MD5 b21a404710858576e4e674c7847d014a ass.php in Aviliate plugin
MD5 b086f53b3f1258c5012afaa3a4aa2e04 b.php in Aviliate plugin*
MD5 781c312fe0acf6c79f59bc1663090975 ftp.php in Aviliate plugin
MD5 fa66278d9f284cb080931a49768efe47 index.html in Aviliate plugin
MD5 23ef3628ab19af2a8127f4c0abc40dd5 index.php in Aviliate plugin*
MD5 33bf39fd010e3312cde659469bebc18d k.php in Aviliate plugin*
MD5 756023c23273fa840d7af376545a1f04 systems.php in Aviliate plugin*
MD5 63605007c074d272ea2407203e2c7d48 user.php in Aviliate plugin
URL hxxp://elro[.]us/fina25/wso.txt URL hosting code loaded by user.php
URL hxxp://kalined[.]com/tmp/a.tx URL hosting code loaded by b.php
URL hxxps://pastebin[.]com/raw/BYZj83nV URL hosting DH-5HELL 2014 backdoor loaded by ftp.php
URL hxxp://kalined[.]com/includes/random.css URL hosting code loaded by k.php
URL hxxp://www.avatarfilms[.]org/wordpress/wp-content/plugins/Premium_Gallery_Manager/04.txt URL hosting code loaded by systems.php
MD5 3b725e982e9c54a26a8a77cdaa8a8fcb 04.txt code for the above*

The starred MD5 hashes above are not in Virus Total, so they may represent new tools used by this group.

The only remaining question that I have is, how did they get in? My Admin password is stored in KeePass and is random, so it’s hard to see how it could be brute-forced. Could it have been intercepted in transit somehow? I’m not sure.

Lessons learned?

  1. Keep logs!
  2. Patch all the things.
  3. Pay attention to those emails that say your site is compromised.