Two weeks ago I noticed I wasn’t getting any email notifications for this site, not even spam. Confidently I told myself that the host had most probably done something to curb the perennial spam I had experiencing. That’s until last week when I got an alarming email from my panel indicating I had hit my daily limit of sending 1000 emails for another site I own.
But how could this happen? To my knowledge I hadn’t setup anything to send out any automated emails and especially not with this sort of volume. Is it possible that my site had fallen victim to some hackers despite using what I thought was a secure firewall/antimalware solution?
I had many questions indeed but no answers were forthcoming. So I decided to contact support from my hosting who immediately surmised that my sites had been compromised and suggested I restore my backups.
And as to why this site was sending out emails, well it turns out that its default email account got automatically suspended after sending out a lot of spam. Strangely, I was never informed of this as it had been the case for my other site.
Thankfully I had some old backups but I wasn’t fully convinced my sites had been compromised. I wanted to dig dipper into the underlying cause before going with what seemed like a “nuclear option”.
So I started by checking my emails logs and true to the alerts I was getting, my default WordPress email was sending out thousands of emails to innocent mailboxes, the vast majority being Gmail accounts.
Conspicuously in each of these emails was what seemed like harmless subjects: titles of posts shared from my blog in the following format:
At first I thought, this doesn’t look like spam. This must be people sharing my posts. But that assertion didn’t make any sense since my traffic hadn’t improved despite what seemed like thousands of legitimate shares.
It’s only after closer inspection that I stumbled on a smoking gun: hundreds of Russian domain email addresses (.ru) which seemed to suggest that somehow my local content was very appealing to Russians. Well this could only point to one thing: spam.
Disabling WP Mail
I immediately decided to disable WordPress’s default mailer which is clear was being used to send this spam. To do this I replaced it with SMTP using the Post SMTP Mailer/Email Log plugin configured to use Sendgrid.
But all that proved to be futile as it wasn’t long before I started noticing on Sendgrid’s Activity Feed the same spam being sent out. It seemed I had even enabled the spammers more only this time they couldn’t send more than 100 emails per day since that’s the maximum daily allotment for Sengrid accounts using the Free plan.
Jetpack the Culprit
At this point I decided to check the usage logs for the site to see if I could spot something that could explain the spam. In hindsight now I realize this should have been my first stop. Why? Well, it only took one look for me to notice something wasn’t right.
The whole log appeared to be filled with only one kind of request – an email share query on different posts but from different IP addresses. The only thing similar about all these requests as far as I could tell was their user agent string. An example is as follows:
184.108.40.206 – – [09/Apr/2020:00:15:40 +0200] “POST /post-url-here/?share=email&nb=1 HTTP/1.1″ 200 24912 “-” “Mozilla/5.0 (Windows NT 10.0; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0”Log entry
So I quickly googled that query [?share=email&nb=1] and that returned some damning results. This blog post from TechJourney dating 3 years ago was the first result on Google and it chronicles how Jetpack was being used to send the same kind of spam I was dealing with.
If that’s not enough, there are more reports of the same spam attacks on the WordPress support forum here and here. On the former a JetPack support indicates that this was high on their priority list then and suggests users make use of Recaptcha in the meanwhile. There are no reports on that thread whether this hole was eventually fixed.
All the above cases took place about 2-3 years ago and so it’s safe to assume Jetpack never got around to fixing the issue. Or probably they did and the hackers found a workaround. I honestly don’t know but I suspect this could be a symptom for not using Akismet which is needed in order to enable the email share button.
There’s however a workaround to bypass installing Akismet using this filter which I made use of since I prefer a different antispam solution. Nevertheless, this is mere speculation on my part not to mention the other victims don’t cite doing something similar.Anyway, its clear what had to be done.
Removing the email share button would suffice to end the spam however I found it more prudent to just disable the entire share module. In its place I now use some simple HTML share buttons; there’s certainly no need to use a script for the email button when it can just use a HTML email link (mailto). That way, if someone badly wants to share via email they won’t mind composing one via their email app/client.
The Spammers’ Payload
Now up until this time none of the logs had shown me the full contents of the spam that was being sent. What possibly could be the payload for these spammers, it surely can’t be my random posts? Perhaps a coordinated effort to malign my site as a spam domain coupled with the fallout of search engine penalties? I don’t think so.
Remember the aforementioned Post SMTP Mailer/Email Log plugin? As its name alludes to it does provides a full log of all emails it sends. Using it I established the spam is being used for what seems like a Russian scam for a dubious VAT compensation by a seemingly government body called the NDS/VNDS.
The following is a transcript of one of the emails:
From: 000 dollars https://rebrand.ly/vnds <[email protected]>Spam Email
Reply-To: 000 dollars https://rebrand.ly/vnds <[email protected]>
Date: 2020-04-06 18:20:24
Subject: [Shared Post] How to Remove Blogger’s Render Blocking Comment JS
You can receive compensation to 300,000 dollars https://rebrand.ly/vnds (####@hotmail.com) thinks you may be interested in the following post:
How to Remove Blogger’s Render Blocking Comment JS
All the spam emails are promoting that one shortened URL that finally redirect to the scam site (https://kompennds.site).
Blocking the Spam Bot
Now the unfortunate thing about this exploit is that the spammers can continue sending those requests to your site long after you’ve removed Jetpack’s email share button. Right now as I write this I’m just from checking my user log and can still see hundreds of similar requests in the past hour.
At first I figured I could just block their IPs using Cloudflare but unfortunately they seem to be using very many different IP addresses all which fall in different ranges. It seems we may be dealing with a botnet here. (check update at the end)
Fortunately, they’re all using the same UA string which we can use instead. The downside with blocking the UA however is that it has the unintended consequence of blocking legitimate users. At the moment they’re all using the UA for Mozilla 45 on Windows 10 X64:
Mozilla/5.0 (Windows NT 10.0; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0
As a remedy to this we can use a JS Challenge or ReCaptcha rather than a complete block. This will block the spammy bots (can verify this since it’s what I initially used) but may be quite annoying to legitimate users that have to complete the test to access your site. Nevertheless, the spammers could easily change the UA so either way this may prove ineffective in the long run.
That leaves us with one last option and by far the best: block all requests using the URI Query String. Just go to Cloudflare Firewall Rules or your Firewall and set a rule to block all request that have the following query that’s used by the Jetpack email share button:
Since you’re not using Jetpack’s email share button any more this shouldn’t have any negative effects on your site. I recommend you use Cloudflare or a similar cloud firewall (WAF) so that these requests are blocked before reaching your server.
Once completely blocked the spammers are sure to give up somewhere down along the line. Or so I hope. Cheers!
Update: After blocking the query string for two days, Cloudflare logs shows that all the requests were actually originating from one IP address: 220.127.116.11. On the bright side, after thousands of failed attacks it seems the spammer has finally given up, at least with my site.