using Programming;

A Blog about some of the intrinsics related to programming and how one can get the best out of various languages.

Phishing: how do we identify it?

Holy phishing batman

Note: this will be part of a longer series on identifying, preventing, and remedying issues related to phishing attempts.

I don't usually post about issues like this, but this is a huge problem and can definitely ruin people's lives, I think it's important to get more information on the topic out there.


So recently I tweeted about two very obscure phishing scams I was sent:

Recently I got two very good-looking phishing emails, annotated to help future potential victims identify them and prevent scams.

It was obvious to me that they were scams, based on all the tell-tale signs of the email I was immediately thrown to the fact that they were not legitimate emails from either of these organizations. (I happen to have accounts with both of them, which made identification slightly easier.)

We're in the year 2017, and if anyone tells you Email or computer systems are dying then they're absolutely wrong. We're entering an age where the internet is becoming a necessary requirement for anyone's life, and I want to talk about one of the biggest problems with email: phishing,

What is phishing?

When I went to college (and even before then) we studied a term called 'social engineering', that is, the idea that an attacker will not attempt to hack/crack/break into your system through technical means, but will convince you to do it for them. This is the broader category that phishing fits into.

Phishing is the act of an attacker convincing a victim (usually a user) to deliver secured information to them in a means that makes the victim completely unaware that they just gave secure information away through the use of faked online forms/websites/emails. The most common (in my experience) is banking information.

With all this in mind, I want to try to help you prevent becoming a victim. There isn't a true "guide" for how you can stop yourself from becoming a victim, but there are steps you can take. I'm going to use actual phishing emails I was sent for this demonstration. Real emails you may receive and how you can identify them and prevent yourself from becoming a victim.

Do note: I'm not even going to talk about the technical aspects of these emails, this guide will be an end-user guide, for the people these emails are designed to victimize.

What does phishing look like?

To see what phishing looks like we're going to use two very real examples, which I've already annotated with some of the tell-tale signs of a phishing email (any one of these signs on it's own isn't necessarily an indicator, but all of them together add up quickly).

Screenshot 1 - Wells Fargo Phishing Attempt Screenshot 2 - Capital One Phishing Attempt

As you can see, I drew a lot of red. Let's talk about this section by section to explore how we can apply this more broadly.


The Wells Fargo email broke down

The first image is from 'Wells Fargo' (or someone that wants you to think they're Wells Fargo). We can see an issue with this right off the bat: the 'From' address. I happen to be a Wells Fargo customer (funny: the email that this phishing scam was sent to is not my account email), and all the emails I get from them have a specific from address: Wells Fargo Online <alerts@notify.wellsfargo.com>. So of course that was the first big red flag for me. However, let's assume you don't know that the usual alert email is alerts@notify.wellsfargo.com, the address itself has one fatal flaw that should give you at least a yellow flag:

wellsfargo_notification_alerts@wellsfargo.com

Generally a bank won't send you an email from bankname_notification_alerts@bankname.com, that's not their usual M.O., typically the email address is just notifications@bankname.com or alerts@bankname.com.

So let's assume that the sender address isn't the problem, that's fine. We'll move to the 'To' line. They sent this email To: Recipients. If you are using Outlook you can expand the contact card and you'll find that the Recipients email address is wellsfargo_notification_alerts@wellsfargo.com. So the attacker sent the email to themselves, and they must have blind-carbon-copied us on it. That immediately tells me it's a phishing attempt. Why would my bank send an email to itself and blind copy me in?

If that wasn't obvious enough, and for some reason you're still in the yellow zone, we have this attachment named Wells Fargo Online Verification.htm.

For those of you that aren't technical users: an htm document is synonymous for an html document, which is basically a webpage. (It is a webpage, but it's not on the web at this point, it's on your PC.) This type of document can easily be processed by a web-browser on your computer (Internet Explorer, Mozilla Firefox, Apple Safari, Opera, Microsoft Edge, Google Chrome) and can do many very cool things, and also many very bad things.

The problem is most people aren't aware of what to do with these documents, so they're not used much for actions with the end-user. Generally you can just double-click the document and it will open in your browser of choice, whatever your default is.

Professional organizations don't usually send you these types of documents. Usually when this type of information needs to be sent you get one of two things: a link to a web-page or a PDF file. Why? Because msot people know what to do with both of those. They know to click a link, and they know to download/save/print a PDF.

The problem with HTML files is that they can contain malicious data. (There are more technical terms for it, but I'll save you the hassle.) They can install files on your PC, they can change settings (in some cases), and they can make you think you're going to a legitimate banking website.

We're not going to open it yet, we're going to mark it as a red flag and continue with the email.

The next thing we see that's a moderately yellow flag is the email body. There is a lot of text in this body that rubs me the wrong way.

We recently reviewed your account, and we are suspecting that your Wells Fargo account may have been accessed from an unauthorized computer.

This may be due to changes in your IP address or location. Protecting the security of your account and of the Wells Fargo network is our primary concern.

We are asking you to immediately login and report any unauthorized withdrawals, and check your account profile to make sure no changes have been made.

This alone isn't a bad phrase, but when it's combined with the next phrase it becomes more disturbing:

To protect your account please follow the instructions below:

  • LOG OFF AFTER USING YOUR ONLINE ACCOUNT

If it were truly a security concern, the bank wouldn't just recommend logging off after you finish using your account. They would also recommend changing your credentials. If your account is being accessed by another PC/user then logging off will not fix it. (In almost all cases, this is true.) So, if the sender were truly concerned about your information, as a bank would be, the recommendation would be to change your password.

Please Download the Attachment file of your Wells Fargo Online Verification and Open on on a browser to complete your account verification process:

Verify the information you entered is correct.

We apologize for any inconvenience this may cause, and appreciate your support in helping us maintaining the integrity of the entire Wells Fargo System. Please verify your account as soon as possible.

Why would I need to download an attachment to login? If I simply need to login to my account, send me a URL/address.

Lastly:

Copyright © 1999 - 2016 Wells Fargo. All rights reserved..

No self-respecting bank would leave that double-period typo in an email. Bank emails go through a rigorous approval process, that typo alone isn't justification for a phishing attempt, but when added to the rest of the email, 'Mark as Spam'.


Breaking down the Capital One attempt

So we just broke the Wells Fargo attempt down, let's do the same for the Capital One phishing attempt.

I have an account with Capital One, and I have seen three distinct email addresses from them: Capital One <capitalone@service.capitalone.com>, Capital One <capitalone@notification.capitalone.com>, and Capital One <capitalone@email.capitalone.com>.

I've also seen a fourth one, but the address itself is slightly disconcerting: Capital One <capitalone@capitaloneemail.com>. That's a really bad email for a bank.

We do at least see a pattern: emails from them are generally Capital One <capitalone@somedomain.capitalone.com>, which is a mostly good thing. This means we can write off Capital One <notifications.alerts@capitalone.com> as a non-legitimate email.

Next we have the same problem as the Wells Fargo email: Recipients and the .htm attachment. We'll skip those since we talked about them above.

We get to the body, and we run into a few things that are fairly alarming:

It has come to our attention that your Billing Information records are recently changed.

That's grammatically wrong, 'records have recently changed' is better.

That requires you to verify your Billing Information. Failure to validate your billing information may result to account termination.

Capital One isn't going to terminate my auto-loan over this, they would call me and verify it first. Better: 'may result to'? Bad grammer again.

To verify your billing information, Please Download Attachment and open in a browser to Continue. We value your privacy and your preferences...

Why are 'Please Download Attachment' and 'Continue' all upper-case on the first letter (capital-case)? That's not normal. Just as well: 'value your privacy and your preferences'? What does that even mean? Then the three dots / elipsis? This is atrocious.

Failure to abide by these instructions may subject you to Capital One account restrictions or inactivity.

That's not what you said above.

TM and copyright © 2017 Capital One Inc. 1 Infinite Loop, MS 96-DM, Cupertino, CA 95015.

For those who don't know, that's Apple's address.


Summary

Overall, I hope this is helpful to increase your ability (and your friends, family, coworkers and loved one's abilities) to identify phishing scams that look legitimate, and prevent becoming a victim to the tactics that these attackers use to steal your information. In a future blog post I'll talk about why it's important to identify them, and how they steal your information.

Demonstrating Insecurity of Managed Windows Program Memory

Is Memory in a Managed Windows Program Secure?

Recently I was on one of the (many) Stack Exchange sites answering a question a user posted, like usual. This question was a bit different though: the asker was concerned about the best way to make sure people couldn't read the password the user entered out of memory.

Unfortunately, this is not a task that can really be solved on consumer devices. Anyone with enough knowledge (and it's not really a lot) can do it. I'm going to demonstrate how to today with a simple Visual Studio programme.

Essentially, what I'm going to do is 'connect' to a fake SQL server (nothing about it will really exist) and then demonstrate how one can (with a copy of Visual Studio) extract the entire Connection String of that SQL connection out. It's actually quite trivial and with enough practice can be done in seconds.

Of course there are other ways to do this, it can be done programatically, there are other bits of software for it, etc. I'm just going to demonstrate how any developer can do it with the tools (s)he has at their disposal.

Creating our test projects

So the first step is to create a test project we can use to 'attack'. We're going to consider this an attacker/victim scenario, since that's what one of the real world applications is.

Our code is going to be pretty simple:

using Evbpc.Framework.Utilities.Prompting;
using System;
using System.Data.SqlClient;

namespace VictimApplication
{
    class Program
    {
        static void Main(string[] args)
        {
            var consolePrompt = new ConsolePrompt(null);

            var connectionString = new SqlConnectionStringBuilder();
            connectionString.DataSource = consolePrompt.Prompt<string>("Enter the SQL server hostname/ip", PromptOptions.Required);
            connectionString.UserID = consolePrompt.Prompt<string>("Enter the SQL server user id", PromptOptions.Required);
            connectionString.Password = consolePrompt.Prompt<string>("Enter the SQL server password", PromptOptions.Required);
            connectionString.InitialCatalog = consolePrompt.Prompt<string>("Enter the SQL server database", PromptOptions.Required);

            using (var sqlConnection = new SqlConnection(connectionString.ToString()))
            {
                try
                {
                    Console.WriteLine("Connecting...");
                    sqlConnection.Open();

                    using (var command = new SqlCommand("SELECT 15", sqlConnection))
                    {
                        Console.WriteLine($"Command output: {command.ExecuteScalar()}");
                    }
                }
                catch
                {
                    Console.WriteLine("Could not establish a connection to the server.");
                }
            }

            Console.WriteLine("Press enter to exit.");
            Console.ReadLine();
        }
    }
}

Do note this uses my ConsolePrompt from GitHub.

So we have our victim application, now we'll go ahead and attack it.

Attaching Visual Studio to a running application

You're probably expecting a title like 'attacking an application with Visual Studio' but that's not as descriptive as what we're doing. Yes, this is how you attack it, but attack sounds nefarious. We're not doing anything nefarious, we're just attaching a debugger to a running application.

So we're going to open a new instance of Visual Studio, and not open or create a project. Just open the instance.

Screenshot 1 - Fresh Visual Studio Instance

So, we've opened Visual Studio (I'm using 2015 but this should work on 2010+). The next thing we'll do is launch our application.

Screenshot 2 - Launch Application Outside Debugger

Right, so we have the application running outside the debugger. No other instances of Visual Studio need to be open, nothing else needs to be running, just that application and our fresh instance. The next step is to attach the debugger to a process.

This is under Debug -> Attach to Process. You should see a new window open, and we want to find our 'Victim Application' (VictimApplication.exe).

Screenshot 3 - Attach to Process

We'll go ahead and attach it. Our screen should change to look like we're in a regular debug session, even though we didn't launch the program through Visual Studio.

Screenshot 4 - Debug Session is Green err Blue

Now we still have our other window open with our running application in it. All we have to do next is start checking it out and see what we can inspect.

This next part isn't required, but it should help you familiarize yourself with what we're going to do. Let's hit the 'Break All' button (CTRL + ALT + Break with default shortcuts).

Screenshot 5 - Break mode

As of this moment the program is paused. Since it's a console application, you can still type into it, but your typing will not be processed by the program at this point.

Screenshot 6 - Text not handled by program

Next we'll hit 'Show Diagnostic Tools' and then select the 'Memory Usage' tab. Once we have done that, we'll hit 'Take Snapshot'.

Screenshot 7 - Taking our first memory snapshot

So now we're at the point we can start inspecting objects in our program. The first thing we'll want to do is click the blue 429 (your number may vary) link to the list of objects.

We'll then sort them by name since we're not concerned about the count, we just want to look through them.

I'm going to inspect our ConsolePrompt as an example, which in this case is listed as Evbpc.Framework.Utilities.Prompting.ConsolePrompt. When you find an object you want to inspect, hover over it and you should see an icon that looks like a square grid with a circular shape on the top-left corner, click that and a new page should open.

Screenshot 8 - Selecting an object to inspect

We'll then see a new page with all the instances of that object listed. If you hover over the Value, you should get a tool-tip that has a breakdown of the object itself, which you can explore just like normal. We'll see that the Logger is in fact null like we wanted.

Screenshot 9 - Exploring our object

Now that we've played with our explorer, we can go ahead and close that breakdown and continue with our program. We'll hit 'Continue' and resume execution. If you typed a server host into the console, you'll see as soon as we hit continue that the program continues to the next step. We'll fill out all our requirements and then break our program again when it starts connecting, and take another memory snapshot.

Screenshot 10 - Connecting to our server

We see that the new snapshot has 3,825 objects allocated, and the difference is an increase of 3,396. Our graph shows that we allocated a lot more memory (relatively speaking) and we can now go ahead and inspect our snapshot to try to find our password. We'll be looking for a string type with a value of pass.

We know it'll be part of the SqlConnection, so we'll sort that by name and then go down to SqlConnection and explore it like before.

Screenshot 11 - Find our SqlConnection

Upon exploring it we'll just a different method of extracting our string. Click 'Referenced Objects' at the bottom of our window, and hover over the middle String object. (Mine is 0x2FB0BD8)

Screenshot 12 - Extracting our Connection String

And there we have it. We have successfully extracted our password from a separate Visual Studio instance while the original application was running completely separately.

Debug Symbols and why they are important

Of course, our demonstration was made slightly easier by the inclusion of the .pdb files (debug symbols), usually you won't have access to these for the running application, so you'll have to look a little harder sometimes to find what you're looking for.

If you don't know what Debug Symbols are, Wikipedia has a nice description. Essentially, the pdb file (stands for 'Program Database') is the symbol map for .NET programs. It contains each generated instruction header and what the generated name of it was.

Finding our String without SqlConnection

The last thing we'll do is find our string value without exploring the SqlConnection object. We're only going to look with the Diff list, and run from there.

So, we'll restart our application, then attach the debugger, then enter our host and user, then take a memory snapshot like we did earlier.

Screenshot 13 - Round 2 First Snapshot

Then we'll hit 'Continue', enter our password, and take another snapshot.

Screenshot 14 - Round 2 Second Snapshot

The next step is to disable 'Just My Code' in the filter. If we don't do this it becomes much more difficult to locate what we changed.

Screenshot 15 - Round 2 Disable Just My Code

So we see that it created one string, by the Count Diff. being +1 on the String type, this helps us narrow down what we're looking for. If click once into it, and view our 'Paths to Root', it helps us discover that we have +1 in String [Local Variable]. So we're in the right place.

Screenshot 16 - Round 2 String Local Variable

We'll inspect the String like before (Square icon with Round outset) and we'll see that by default it sorts the list by `'Inclusive Size (Bytes)', we'll sort it by 'Instance'. Theorhetically our password should be the last instance listed. If we scroll to the bottom of the list we see that, indeed, it is.

We also see that our user id is right above it.

Screenshot 17 - Round 2 Find our Password


And there we have it! We learned how to inspect objects in our program when it was launched outside Visual Studio by attaching a debug instance of Visual Studio to it.