{"id":1257,"date":"2018-03-01T20:46:05","date_gmt":"2018-03-02T02:46:05","guid":{"rendered":"http:\/\/www.nathanhunstad.com\/blog\/?p=1257"},"modified":"2018-03-01T20:47:32","modified_gmt":"2018-03-02T02:47:32","slug":"investigating-a-wordpress-compromise","status":"publish","type":"post","link":"https:\/\/www.nathanhunstad.com\/blog\/2018\/03\/investigating-a-wordpress-compromise\/","title":{"rendered":"Investigating a WordPress Compromise"},"content":{"rendered":"<p>It\u2019s 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.<\/p>\n<p><!--more--><\/p>\n<p>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\u2019s 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<\/p>\n<p>Since WordPress stores everything in MySQL, I logged into my hosting control panel and fired up phpMyAdmin. Data about users is stored in the <span style=\"font-family: 'Courier New';\">wp_users<\/span> 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.<\/p>\n<p>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 <a href=\"http:\/\/www.wpbeginner.com\/wp-tutorials\/how-to-add-an-admin-user-to-the-wordpress-database-via-mysql\/\" target=\"_blank\" rel=\"noopener\">these instructions<\/a> (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.<\/p>\n<p>Next was the Investigation piece. As you will no doubt recall, I had long ago set up a <a href=\"http:\/\/www.nathanhunstad.com\/blog\/2014\/09\/log-file-automation\/\" target=\"_blank\" rel=\"noopener\">pull of my website logs into Splunk<\/a>. 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 <span style=\"font-family: 'Courier New';\">wp-login.php<\/span> page:<\/p>\n<p><a href=\"http:\/\/www.nathanhunstad.com\/blog\/wp-content\/uploads\/2018\/02\/clip_image001.png\"><img loading=\"lazy\" decoding=\"async\" style=\"background-image: none; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border: 0px;\" title=\"clip_image001\" src=\"http:\/\/www.nathanhunstad.com\/blog\/wp-content\/uploads\/2018\/02\/clip_image001_thumb.png\" alt=\"clip_image001\" width=\"721\" height=\"321\" border=\"0\" \/><\/a><\/p>\n<p>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:<\/p>\n<ol>\n<li>The attacker arrived at my login page with a referrer header from <span style=\"font-family: 'Courier New';\">hxxp:\/\/teti[.]az\/wp-admin\/network\/anu\/wp-login.php<\/span><\/li>\n<li>The attacker somehow was able to successfully authenticate (the POST above)<\/li>\n<li>The attacker navigated to my Plugins page<\/li>\n<li>The attacker then installed a new Plugin via the <span style=\"font-family: 'Courier New';\">plugin-install.php<\/span> page<\/li>\n<li>The plugin was successfully installed in my<span style=\"font-family: 'Courier New';\"> \/blog\/wp-content\/plugins\/Aviliate<\/span> folder<\/li>\n<\/ol>\n<p>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.<\/p>\n<p>I removed this plugin manually from my site for containment, but not before I downloaded a copy for investigation. Here\u2019s where it started to get even more interesting. First, however, it was back to Investigation mode.<\/p>\n<p>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 <span style=\"font-family: 'Courier New';\">\/blog\/wp-content\/plugins\/Aviliate\/user.php<\/span> and then go to <span style=\"font-family: 'Courier New';\">\/NTI5enhqLzk2MjUvMjkvNDU5MDEvOQ==<\/span> which certainly isn\u2019t a valid URL on my site, or at least shouldn\u2019t be. That meant that there was something interesting going on in that <span style=\"font-family: 'Courier New';\">user.php<\/span> file, so that was the next place to look.<\/p>\n<p>That file was nothing more than a function to grab the contents of another site and PHP <span style=\"font-family: 'Courier New';\">eval<\/span> it. No legitimate PHP site grabs data from random URL and evals it, so this was clearly malicious. The URL was <span style=\"font-family: 'Courier New';\">hxxp:\/\/elro[.]us\/fina25\/wso.txt<\/span>, which Virus Total <a href=\"https:\/\/www.virustotal.com\/#\/url\/177d89df3db98a04e48203105b04b385e2207ebc8a463aef53681e813644e549\/detection\" target=\"_blank\" rel=\"noopener\">shows as malcious<\/a>, hosting a PHP Backdoor Webshell (details <a href=\"https:\/\/www.virustotal.com\/#\/file\/a6a0f7094fb1d440ef2adbf68ef111f8db8d30e23edf08466ddffed8618d9273\/detection\" target=\"_blank\" rel=\"noopener\">here<\/a>). 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.<\/p>\n<p align=\"left\">The afore-mentioned IP addresses all hit the <span style=\"font-family: 'Courier New';\">user.php<\/span> 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 <span style=\"font-family: 'Courier New';\">\/NGlfMzgyMTVfaXRrYS90Xzg4Njdfa2F5.html<\/span>, which may have been a persistent backdoor link. Further Splunk searches on that particular URL found even more visits from other IPs.<\/p>\n<p align=\"left\">The original Google Search Console alert was for <span style=\"font-family: 'Courier New';\">\/<\/span><a><span style=\"font-family: 'Courier New';\">eWYtOTgyNy1mdi8xNjEyLXZ1.amm<\/span><\/a>, which I also search for in Splunk and saw a number of hits.<\/p>\n<p align=\"left\">The other Aviliate file that was accessed was the file <span style=\"font-family: 'Courier New';\">ass.php<\/span>, which appeared be another file management tool called \u201cB Ge Team File Manager\u201d. Googling that term brings up an alarming number of sites that appear to have once had this backdoor as well. The attacker only accessed <span style=\"font-family: 'Courier New';\">ass.php<\/span> 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, <span style=\"font-family: 'Courier New';\">site_map.xml<\/span> and <span style=\"font-family: 'Courier New';\">home-site-map.xml<\/span>. The former had a bunch of random URLs, including the ones above. This user also accessed a file that should not have existed, at <span style=\"font-family: 'Courier New';\">\/wp-content\/uploads\/2014\/09\/cropped-DSC04285.jpg<\/span><span style=\"font-family: Arial;\">, although searching for this file now returns no results.<\/span><\/p>\n<p align=\"left\">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:<\/p>\n<table border=\"0\" width=\"400\" cellspacing=\"0\" cellpadding=\"2\">\n<tbody>\n<tr>\n<td valign=\"top\" width=\"133\"><strong>Type<\/strong><\/td>\n<td valign=\"top\" width=\"133\"><strong>Value<\/strong><\/td>\n<td valign=\"top\" width=\"133\"><strong>Note<\/strong><\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"133\">Email<\/td>\n<td valign=\"top\" width=\"133\">javaintelegentcyber@gmail[.]com<\/td>\n<td valign=\"top\" width=\"133\">Email address for altered WordPress admin user<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"133\">IP<\/td>\n<td valign=\"top\" width=\"133\">114.125.62.180<\/td>\n<td valign=\"top\" width=\"133\">Initial attacker IP<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"133\">URL<\/td>\n<td valign=\"top\" width=\"133\">hxxp:\/\/teti[.]az\/wp-admin\/network\/anu\/wp-login.php<\/td>\n<td valign=\"top\" width=\"133\">Referrer for initial attack<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"133\">MD5<\/td>\n<td valign=\"top\" width=\"133\">90d3aea687c0b53e69f8100fd7ed5f07<\/td>\n<td valign=\"top\" width=\"133\">admin.php in Aviliate plugin<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"133\">MD5<\/td>\n<td valign=\"top\" width=\"133\">b21a404710858576e4e674c7847d014a<\/td>\n<td valign=\"top\" width=\"133\">ass.php in Aviliate plugin<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"133\">MD5<\/td>\n<td valign=\"top\" width=\"133\">b086f53b3f1258c5012afaa3a4aa2e04<\/td>\n<td valign=\"top\" width=\"133\">b.php in Aviliate plugin*<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"133\">MD5<\/td>\n<td valign=\"top\" width=\"133\">781c312fe0acf6c79f59bc1663090975<\/td>\n<td valign=\"top\" width=\"133\">ftp.php in Aviliate plugin<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"133\">MD5<\/td>\n<td valign=\"top\" width=\"133\">fa66278d9f284cb080931a49768efe47<\/td>\n<td valign=\"top\" width=\"133\">index.html in Aviliate plugin<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"133\">MD5<\/td>\n<td valign=\"top\" width=\"133\">23ef3628ab19af2a8127f4c0abc40dd5<\/td>\n<td valign=\"top\" width=\"133\">index.php in Aviliate plugin*<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"133\">MD5<\/td>\n<td valign=\"top\" width=\"133\">33bf39fd010e3312cde659469bebc18d<\/td>\n<td valign=\"top\" width=\"133\">k.php in Aviliate plugin*<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"133\">MD5<\/td>\n<td valign=\"top\" width=\"133\">756023c23273fa840d7af376545a1f04<\/td>\n<td valign=\"top\" width=\"133\">systems.php in Aviliate plugin*<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"133\">MD5<\/td>\n<td valign=\"top\" width=\"133\">63605007c074d272ea2407203e2c7d48<\/td>\n<td valign=\"top\" width=\"133\">user.php in Aviliate plugin<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"133\">URL<\/td>\n<td valign=\"top\" width=\"133\">hxxp:\/\/elro[.]us\/fina25\/wso.txt<\/td>\n<td valign=\"top\" width=\"133\">URL hosting code loaded by user.php<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"133\">URL<\/td>\n<td valign=\"top\" width=\"133\">hxxp:\/\/kalined[.]com\/tmp\/a.tx<\/td>\n<td valign=\"top\" width=\"133\">URL hosting code loaded by b.php<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"133\">URL<\/td>\n<td valign=\"top\" width=\"133\">hxxps:\/\/pastebin[.]com\/raw\/BYZj83nV<\/td>\n<td valign=\"top\" width=\"133\">URL hosting DH-5HELL 2014 backdoor loaded by ftp.php<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"133\">URL<\/td>\n<td valign=\"top\" width=\"133\">hxxp:\/\/kalined[.]com\/includes\/random.css<\/td>\n<td valign=\"top\" width=\"133\">URL hosting code loaded by k.php<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"133\">URL<\/td>\n<td valign=\"top\" width=\"133\">hxxp:\/\/www.avatarfilms[.]org\/wordpress\/wp-content\/plugins\/Premium_Gallery_Manager\/04.txt<\/td>\n<td valign=\"top\" width=\"133\">URL hosting code loaded by systems.php<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"133\">MD5<\/td>\n<td valign=\"top\" width=\"133\">3b725e982e9c54a26a8a77cdaa8a8fcb<\/td>\n<td valign=\"top\" width=\"133\">04.txt code for the above*<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>The starred MD5 hashes above are not in Virus Total, so they may represent new tools used by this group.<\/p>\n<p>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\u2019s hard to see how it could be brute-forced. Could it have been intercepted in transit somehow? I\u2019m not sure.<\/p>\n<p>Lessons learned?<\/p>\n<ol>\n<li>Keep logs!<\/li>\n<li>Patch all the things.<\/li>\n<li>Pay attention to those emails that say your site is compromised.<\/li>\n<\/ol>\n","protected":false},"excerpt":{"rendered":"<p>It\u2019s 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&hellip; <a class=\"more-link\" href=\"https:\/\/www.nathanhunstad.com\/blog\/2018\/03\/investigating-a-wordpress-compromise\/\">Continue reading <span class=\"screen-reader-text\">Investigating a WordPress Compromise<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"om_disable_all_campaigns":false,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[127],"tags":[282,283,252,281],"class_list":["post-1257","post","type-post","status-publish","format-standard","hentry","category-security","tag-forensics","tag-malware","tag-splunk","tag-wordpress","entry"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.nathanhunstad.com\/blog\/wp-json\/wp\/v2\/posts\/1257","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.nathanhunstad.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.nathanhunstad.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.nathanhunstad.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.nathanhunstad.com\/blog\/wp-json\/wp\/v2\/comments?post=1257"}],"version-history":[{"count":4,"href":"https:\/\/www.nathanhunstad.com\/blog\/wp-json\/wp\/v2\/posts\/1257\/revisions"}],"predecessor-version":[{"id":1261,"href":"https:\/\/www.nathanhunstad.com\/blog\/wp-json\/wp\/v2\/posts\/1257\/revisions\/1261"}],"wp:attachment":[{"href":"https:\/\/www.nathanhunstad.com\/blog\/wp-json\/wp\/v2\/media?parent=1257"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.nathanhunstad.com\/blog\/wp-json\/wp\/v2\/categories?post=1257"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.nathanhunstad.com\/blog\/wp-json\/wp\/v2\/tags?post=1257"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}