Email spam - using DKIM verification for analysis
A few days ago I received a spam email from my friend Jack on my personal Gmail account. The email came from his Yahoo! Mail account and looked in every way legitimate, except that it had no subject and contained only a link. The recipient list, unlike many spam bulk emails, wasn't even in alphabetical order.
About an hour later I received another email from the same friend, this time sending a legitimate bulk email to multiple recipients apologizing for spamming them.
Email spam coming from your account is embarrassing, and in all cases the first thing you should do is change your password because the most likely cause of spam email being sent from your account is that your email password credentials were stolen.
Was His Email Account Hacked?
Jack, who I contacted for more details, at first refused to believe that his password was compromised, until I laid out two possible reasons why spam had been sent out from his account and let him decide which was more likely:
- Yahoo!'s private key had been stolen and used to sign spam emails.
- His Yahoo! email password, which he most likely uses on multiple Web sites, was somehow phished or stolen.
Being the smart friend that he is, Jack went with option number 2.
Let me share how I came to my conclusion and how DomainKeys Identified Mail (DKIM) verification can be used in analysis to verify that the email sent came from Yahoo!, was not forged, and that his credentials were used to send the email.
Figure 1: Spam Email - click this link to view the original email with headers removed for privacy reasons.
For the purposes of this blog post, I'm going to focus less on what happens to the user when they click on the URL, and more on how we can determine whether the email was sent from Yahoo! using the credentials of the user in question ( I will state that Websense had the URL above categorized into Web and Email Spam as it's a Fake Canadian Pharmaceutical website).
When you look at an email, much like a Web page, there is more than meets the eye on the details behind that email. Gmail allows you to view the email as we see it above or in its original form, which has more details than the average person would ever want to see. Here is a snippet:
Figure2 : Spam Email snippet in original form with personal details removed
One interesting header in the email is the header called the DKIM signature:
The DKIM signature is a signature used by the SMTP receiver of an email to verify that it came from the sender it claims to come from and that the message hasn't been tampered with.
In this case Gmail received a message from Yahoo!, looked at the DKIM signature, and applied the following algorithm:
- Took a SHA-256 as the cryptographic hash of the message.
- Signed SHA-256 hash using RSA as the public key encryption scheme.
- Encoded the encrypted hash using Base64.
So, for someone to send an email claiming to originate from Yahoo! and pass through a server that checks the DKIM signature, they would have to obtain the private key that Yahoo! uses for signing email messages from Yahoo! mail servers.
Verifying DKIM Signatures
Let's manually verify the DKIM signature to make sure it came from Yahoo!.
To do this we have to retrieve Yahoo!'s public key. To retrieve DKIM public keys the SMTP receiver uses DNS and looks at the TXT resource record type.
Using the s and d fields in the DKIM signature, which stands for the selector, we're going to make a manual DNS query for the TEXT resource record type for a host in the form: s._domainkey.d
s1024._domainkey.yahoo.com is the host we'll want to do the DNS look up the public key.
We can programmatically do this with a PERL using a set of scripts I co-wrote with my colleague David Saunders. The first script will pull the public key from the DNS request:
host: s1024._domainkey.yahoo.com key: k=rsa; t=y; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDrEee0Ri4Juz+QfiWYui/E9UGSXau/2P8LjnTD8V4Unn+2FAZVGE3kL23bzeoULYv4PeleB3gfm JiDJOKU3Ns5L4KJAUUHjFwDebt0NP+sBK0VKeTATL2Yr/S3bT/xhy+1xtj4RkdV7fVxTn56Lb4udUnwuxK4V5b5PdOKj/+XcwIDAQAB; n=A 1024 bit key;
Figure 3: Script to fetch Yahoo! DKIM public key - full script source code can be found here
As you can see, the script above fetches the DKIM public key which allows us to verify the message. To accomplish this we could use PERL's Crypt::OpenSSL::DSA or various other libraries and languages, but instead we're going to use a CPAN module Mail::DKIM::Verifier against the initial message that includes the DKIM signature and all lines below to verify whether the message is valid and hasn't been tampered with. Mail::DKIM::Verifier will even download the public key so you don't have to fetch it explicitly. Here is a script you can use for verification of an email message that includes a DKIM signature:
message.txt passed DKIM validation
Figure 4: DKIM verification script - full script source code can be found here
OK, so let's tie this all together. We received a SPAM email and wanted to verify that it came from Yahoo! as opposed to an open relay or a server claiming to be Yahoo!. The email message contained a DKIM signature, which we used to verify the DNS domain, the email sender, and the message integrity. Using the provided scripts, we verified this information, which led us to conclude that:
- The email message was sent from Yahoo!.
- The headers, including who it was sent from, were not forged.
All of this leads us to the conclusion that the person's email account that the spam email was sent from was most likely compromised by stolen password credentials. This isn't to say that digital certificates can't be stolen or replaced, this can happen, e.g. DigiNotar CA, but these types of occurrences are rare.
Back to my friend Jack, a smart technical guy who probably still doesn't understand how his credentials were stolen. Upon questioning Jack, he disclosed his password to me, which wasn't one I'd consider easy to brute force, but added that he uses that password on multiple Web sites and had recently signed up for about 4 different sites using that password where he used his email address as his username.
My advice to everyone is never use your email address password anywhere else but for your email account, and especially not on sites where your user name is your email address and your password is the password you use for that email address. You should realize that Web site databases get compromised all the time, so whether Jack's credentials were stolen because he was unknowingly phished, his computer had a keylogger on it, or one of the sites he registered for using his email address and email address password stole it, we'll never know. The important thing is that after such an incident to change the password to your email account.
DKIM signatures are used by all major Web-based email providers, including Yahoo!, Gmail, Microsoft Live, etc. If you see a DKIM signature, you can verify the DNS domain of an email sender and the message integrity by using the PERL scripts linked in this blog.
For More Information on DKIM:
- RFC 4870 Domain-Based Email Authentication Using Public Keys Advertised in the DNS (DomainKeys)
- RFC 4871 DomainKeys Identified Mail (DKIM) Signatures
Please leave feedback or comments, so we can make sure to fully address any questions or concerns you have.
Stephan Chenette - Principal Security Researcher