Hasty Scripts: Go Phish v2

Picking up where the last post left off, we are going to add some additional functionality to the previous Go Phish script. As discussed at the end of the previous post, another common tactic used in phishing campaigns are one use throwaway email accounts. In these scenarios, the goal is not to impersonate a trusted contact, but rather send an email as an unknown contact which may better slip through the cracks and get someone to click on link or attachment. In the post, we add functionality to alert on one-off emails potentially coming from throwaway email accounts. This is a useful category of emails to review in triage scenarios and typically comprise of only a few emails matching our criteria.

PST Go Phish

Be advised, this script does require pypff to be installed. Please refer to the previous post for instructions on installing that library. When running the help command, users will now see an additional switch called threshold. This switch is configured to store the Boolean value True if supplied by the user. We will check if threshold is True during script execution to enable the additional module. Let’s now look at some of the additional lines of code which add this behavior.

ubuntu@ubuntu:~/Desktop$ python pst_go_phish.py -h
usage: pst_go_phish.py [-h] [-i IGNORE] PST_FILE OUTPUT_DIR

PST Go Phishing..

positional arguments:
  PST_FILE              File path to input PST file
  OUTPUT_DIR            Output Dir for CSV

optional arguments:
  -h, --help            show this help message and exit
  -i IGNORE, --ignore IGNORE
                        Comma-delimited acceptable emails to ignore e.g.
                        (bounce lists, etc.)
  -t, --threshold       Flag emails where sender has only sent 1 email

First up, the compareMessage() function, which was used to process each message, compare header values and identify those that were potentially suspicious. If the ignore switch was supplied, we also removed from comparison those messages that should be ignored.

All we have changed to this function is, for messages which should be compared, we check if the global senders_dict has a key matching the email address. If it doesn’t, we create for the sender and add a list as its value of the message components we will later write to our CSV. Note that the first element of the list is going to represent the number of messages received by the sender.

Every time we find the sender already in this dictionary we increment the sender count by 1. We do not, however, add message components for any other additional message from that sender. The reasoning here is to keep overhead low. After all, at the end of all of this, we are only interested in senders who only sent one email to the mailbox. If they sent more than one email, they will exceed our static threshold of one and will be discarded anyways so storing those additional message components will be useless in this case.

Notice that, for the most part, we add the same message components as the emails found to be “suspicious” which gets added to the message_list. This is because we will later be adding emails at the threshold to our message_list variable for output to the CSV and so we want to add the same data elements for consistency.

def compareMessage(folder, msg, eml_from, reply, return_path, ignore, threshold):
	if threshold:
		if from_email in senders_dict:
			senders_dict[from_email][0] += 1
			senders_dict[from_email] = [1, folder.name, msg.get_subject(), msg.get_sender_name(), msg.number_of_attachments, from_email, return_email, reply_email]

	if suspicious is True:
		suspicious_messages += 1
		message_list.append([folder.name, msg.get_subject(), msg.get_sender_name(), msg.number_of_attachments, from_email, return_email, reply_email, found_suspicious])

In the main() function, we call the new senderThreshold() function after the recursePST() function completes and prior to the csvWriter() method.

def main(pst_file, output_dir, ig, threshold):
	if threshold:
		print "[+] Identifying senders complying with threshold limit"

The senderThreshold() function is quite simple, it is responsible for iterating through the senders_dict and identifying potential throwaway email addresses and their email. For those that it finds, it increments a counter by 1 to later print to the console and normalize the list a bit. Specifically, it removes the count of emails from this sender, which will be 1, as it is not necessary for the output. Additionally, it adds the string “Threshold” to this list.

If you recall from last time, the last column is the “Flag” column and will have “Reply-to”, “Return-Path”, or “Both” values based on which criteria the message was found to be “suspicious”. Now, a fourth value, “Threshold” will be present allowing the user to quickly filter on this column to review potentially relevant messages.

def senderThreshold(threshold):
	global message_list, senders_dict
	sender_count = 0
	for sender in senders_dict:
		if not senders_dict[sender][0] > 1:
			sender_count += 1
			tmp_list = senders_dict[sender][1:]
	print "[+] Identified {} senders equal to the threshold".format(sender_count)

After this function, the csvWriter() method is invoked which is responsible for writing the message_list global variable to a CSV file in the supplied output directory. As an example, in my sample PST dataset, this script compared ~12,000 messages and identified only ~250 matching our new threshold requirement (approx. 2% of emails were responsive to our threshold). This is obviously a much more manageable amount of emails to quickly review and would expedite any PST / OST mailbox review for evidence of phishing emails.

You can find the code on the blog Github account. I am enjoying working on this project and will likely continue adding additional features and improvements to improve its utility. Have any thoughts on additional features you’d like to see for this script? Let me know below!

Hasty Scripts: Go Phish v2

One thought on “Hasty Scripts: Go Phish v2

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s