Intro
A long-running spam campaign has been bothering me lately. In this post I analyze it from a sendmail perspective and provide a simple script I wrote which helped me fight back.
The details
Let’s have a look see at the July 3rd variant of this spam. Although somewhat different from the previous campaigns in that this did not provide users with a carefully phished email to their inbox, from a sendmail perspective it had a lot of the same features.
So the July 3rd spam was a spoof of Marriott. Look at these from lines. They pretty much shout the pattern out:
Jul 3 14:12:20 drjemgw sm-mta[4707]: r63IA8dJ004707: [email protected], size=0, class=0, nrcpts=1, proto=SMTP, daemon=sm-m ta, relay=eu1sysamx113.postini.com [217.226.243.182] Jul 3 14:12:22 drjemgw sm-mta[7088]: r63ICDA7007088: [email protected], size=0, class=0, nrcpts=1, proto=SMTP, daemon=sm-mta, r elay=eu1sysamx138.postini.com [217.226.243.227] Jul 3 14:12:23 drjemgw sm-mta[7220]: r63ICIhL007220: [email protected], size=0, class=0, nrcpts=1, proto=SMTP, daemon=sm-m ta, relay=eu1sysamx103.postini.com [217.226.243.52] Jul 3 14:12:24 drjemgw sm-mta[7119]: r63ICEp6007119: [email protected], size=0, class=0, nrcpts=1, proto=SMTP, daemon=sm -mta, relay=eu1sysamx112.postini.com [217.226.243.181] Jul 3 14:12:33 drjemgw sm-mta[7346]: r63ICO8H007346: [email protected], size=0, class=0, nrcpts=1, proto=SMTP, daemon=sm-mta, relay=eu1sysamx110.postini.com [217.226.243.59] Jul 3 14:12:34 drjemgw sm-mta[7425]: r63ICTsI007425: [email protected], size=0, class=0, nrcpts=1, proto=SMTP, daemon=sm- mta, relay=eu1sysamx107.postini.com [217.226.243.56] Jul 3 14:12:35 drjemgw sm-mta[7387]: r63ICRMP007387: [email protected], size=0, class=0, nrcpts=1, proto=SMTP, daemon=s m-mta, relay=eu1sysamx108.postini.com [217.226.243.57] Jul 3 14:12:39 drjemgw sm-mta[1757]: r63I7dfa001757: [email protected], size=0, class=0, nrcpts=1, proto=SMTP, daemon=sm-mta, re lay=eu1sysamx138.postini.com [217.226.243.227] Jul 3 14:12:40 drjemgw sm-mta[6643]: r63IBpYm006643: [email protected], size=0, class=0, nrcpts=1, proto=SMTP, daemon=sm-mta, relay=e u1sysamx120.postini.com [217.226.243.189] Jul 3 14:12:42 drjemgw sm-mta[4894]: r63IAFug004894: [email protected], size=0, class=0, nrcpts=1, proto=SMTP, daemon=sm-mta, relay=eu1sysamx110.postini.com [217.226.243.59] Jul 3 14:12:43 drjemgw sm-mta[7573]: r63ICZJq007573: [email protected], size=0, class=0, nrcpts=1, proto=SMTP, daemon=sm-mt a, relay=eu1sysamx140.postini.com [217.226.243.229] Jul 3 14:12:45 drjemgw sm-mta[7698]: r63ICfP9007698: [email protected], size=0, class=0, nrcpts=1, proto=SMTP, daemon =sm-mta, relay=eu1sysamx102.postini.com [217.226.243.51] Jul 3 14:12:46 drjemgw sm-mta[7610]: r63ICblx007610: [email protected], size=0, class=0, nrcpts=1, proto=SMTP, daemon=sm- mta, relay=eu1sysamx109.postini.com [217.226.243.58] Jul 3 14:12:50 drjemgw sm-mta[7792]: r63ICl6Y007792: [email protected], size=0, class=0, nrcpts=1, proto=SMTP, daemon=sm-mta, rela y=eu1sysamx112.postini.com [217.226.243.181] Jul 3 14:12:51 drjemgw sm-mta[6072]: r63IBGCU006072: [email protected], size=0, class=0, nrcpts=1, proto=SMTP, d aemon=sm-mta, relay=eu1sysamx126.postini.com [217.226.243.195] Jul 3 14:12:51 drjemgw sm-mta[7549]: r63ICYnm007549: [email protected], size=0, class=0, nrcpts=1, proto=SMTP, daemon=sm-mta, rela y=eu1sysamx115.postini.com [217.226.243.184] Jul 3 14:12:55 drjemgw sm-mta[7882]: r63ICrUW007882: [email protected], size=0, class=0, nrcpts=1, proto=SMTP, daemon=sm-mta, r elay=eu1sysamx139.postini.com [217.226.243.228] Jul 3 14:12:57 drjemgw sm-mta[7925]: r63ICtav007925: [email protected], size=0, class=0, nrcpts=1, proto=SMTP, daemon=sm-mta, relay=e u1sysamx110.postini.com [217.226.243.59] Jul 3 14:12:57 drjemgw sm-mta[7930]: r63ICu5c007930: [email protected], size=0, class=0, nrcpts=1, proto=SMTP, daemon=sm- mta, relay=eu1sysamx125.postini.com [217.226.243.194] Jul 3 14:12:58 drjemgw sm-mta[7900]: r63ICsOE007900: [email protected], size=0, class=0, nrcpts=1, proto=SMTP, daemon=sm-mta, relay=eu1 sysamx131.postini.com [217.226.243.220] Jul 3 14:13:00 drjemgw sm-mta[7976]: r63ICwmu007976: [email protected], size=0, class=0, nrcpts=1, proto=SMTP, daemon=sm-mta, relay= eu1sysamx127.postini.com [217.226.243.196] |
Of 2035 of these that were sent out, 192 were delivered, meaning got into the users inbox past Postini’s anti-spam defenses. So that’s a pretty high success rate as spam goes. And users get concerned.
Now look at sendmail’s access file which I created shortly after becoming aware of similar phishing of linkedin.com more recently on July 11th:
# 7/11/13 linkedinmail.com DISCARD linkedinmail.net DISCARD linkedinmail.org DISCARD linkedinmail.biz DISCARD linkedin.net DISCARD linkedin.org DISCARD linkedin.biz DISCARD inbound.linkedin.com DISCARD complains.linkedin.com DISCARD emalsrv.linkedin.com DISCARD clients.linkedin.com DISCARD emlreq.linkedin.com DISCARD customercare.linkedin.com DISCARD m.linkedin.com DISCARD enc.linkedin.com DISCARD services.linkedin.com DISCARD amc.linkedin.com DISCARD news.linkedin.com DISCARD |
You get the idea.
What I noticed in these campaigns is a wide variety of subdomains of the domain being phished, with and without “mail” attached to the domain. In particular some rather peculiar-looking subdomains such as complains and emalsrv. So I realized that instead of waiting for me to get the spam, I can constantly comb the log file for these peculiar subdomains. If I come across a new one, voila, it means a new spam campaign has just started! And I can send myself an alert so I can decide – by hand – how best to treat it, knowing it will generally follow the pattern of the recent campaigns.
Now here’s the script I wrote to catch this type of pattern early on:
#!/usr/bin/perl # DrJ, 7/2013 # I keep my sendmail log file here in /maillog/stat.log and cut it daily $sl = "/maillog/stat.log"; # 10000 lines occurs in about eight minutes $DEBUG = 0; $i = 0; $lastlines = "-10000"; $access = "/etc/mail/access"; open(ACCESS,$access) || die "Cannot open $access!!\n"; @access = <ACCESS>; open(SL,"/usr/bin/tail $lastlines $sl|") || die "cannot run tail $lastlines on $sl!!"; print "anti-spam domain: "; while(<SL>){ ($domain) = /from=\w{1,25}@(?:emalsrv|complains)\.([^\.]+)\./; if ($domain) { # test if we already have it on our access table $seenit = 0; foreach $line (@access) { # lazy, inaccurate match, but good enough... $seenit = 1 if $line =~ /$domain/; print "seenit, domain, line: $seenit, $domain, $line\n" if $DEBUG; } if (! $seenit) { $i++; print "$domain\n" if $i == 1; } } } |
I call the script spam-check.pl. I invoke spam-check.pl every couple minutes from HP SiteScope. There I have alerts set up which email me a brief message that includes the new domain that is being phished.
No sooner had I implemented this script than it went off and told me about that linkedin phishing spam campaign! That was sweet.
Recent campaigns
Here is a chronology of spam campaigns which follow the pattern documented above. They seem to cook them up one per day.
5/16 wallmart.com - their misspelling, not mine! 5/29 amazon.com 6/20 adp.com date uncertain ebay.com 7/9 eftps.com 7/10 visabusinessnews.com 7/11 linkedin.com 7/15 ups.com 7/16 twitter.com 7/17 marriott.com mmm.com - this one changed up the pattern a bit 7/18 marriott.com - again ups.com - with somewhat new pattern 7/22 AA.com 7/23-28 a bit more AA.com, a smattering of marriott.com and ebay.com 7/29 tapering off... 7/30 and later spammer seems to have gone on hiatus, or finally been arrested 10/2, they're back staples.com |
One example spam
Here was my phishing spam from 3M which I got yesterday:
From: "3M" <[email protected]> To: DrJ __________________________________________________ This is an automated e-mail. PLEASE DO NOT RESPOND TO THIS EMAIL ACCOUNT. This account is not reviewed for responses. -------------------------------------------------------------------------------- This email is to confirm that on 07/17/2013, 3M's bank (JP Morgan) has debited $15,956.64 from your bank account. If you have any questions, please visit the 3M EIPP Helpline at this link. |
The HTML source for that last line looks like this:
If you have any questions, please visit the 3M EIPP= Helpline <a href=3D"http://vlayaway.com/download/mmm.com.e-marketing.ht= ml?help">at this link.</div> |
When I checked Bluecoat’s K9 webfilter, which I even use at home, the URL in the link, vlayaway… was not rated. I submitted a suggest category, Malicious Sources, and they efficiently assigned it that category within minutes of my submission.
Also, note that the envelope sender of my email differs from the Sender header. The envelope sender was [email protected].
A word about DISCARD vs ERROR
While I’m waiting for more spam of this sort to come in as I write this on July 22nd, I had a brainstorm. Rather than DISCARDind these emails, which doesn’t tip the sender off, it’s probably better to send a 550 error code, which rattles the system a bit more. I think a sending IP with too many of these errors will be temporarily banned by Postini for all their users. So I changed all my DISCARDs. Here is the syntax for one example line:
linkedin-mail.com ERROR:"550 Sender banned. Please use legitimate domain to send email." |
I originally wanted to put the message “No such user,” to try to get the spammer to take that specific recipient off their spam list, but it doesn’t really work in the right way: the error is reported in the context of the sender address, not the recipient address.
Here is the protocol which shows what I am talking about:
$ telnet drj.postini.com 25 Trying 217.136.247.13... Connected to drj.postini.com.. Escape character is '^]'. 220 Postini ESMTP 133 y678_pstn_c6 ready. CA Business and Professions Code Section 17538.45 forbids use of this system for unsolicited electronic mail advertisements. helo localhost 250 Postini says hello back mail from: [email protected] 250 Ok rcpt to: [email protected] 550 5.0.0 [email protected]... Sender banned. Please use legitimate domain to send email. - on relay of: mail from: [email protected] quit 221 Catch you later |
So that – on relay of: mail from: … is added by Postini so it really doesn’t make sense to say No such user in that context.
Conclusion
My satisfaction may be short-lived. But it is always sweet to be on top, even for a short while.
References
For a lighthearted discussion of HP SiteScope, read the comments from this post.
Sendmail is discussed in various posts of mine. For instance, Analyzing the sendmail log, and Obscure tips for sendmail admins.