Monday, February 3, 2020

Impossible Traveler

Use Case

An impossible traveler, at least in the case of this article, is defined as the occurrence of a user interacting with the same resource from two different locations, but, given the time delta and distance between the sources, could not possibly have made that trip in a reasonable amount of time.

For instance, let's assume that we have a user log in to a web resource from an IP address in San Francisco, CA at 20:00 UTC and then submit a POST to the site from an IP address located in New York, NY at 20:30 UTC. There is no method of transportation (at least until Elon Musk figures this out) that a human can take to travel over 4,100km in 30 minutes.

Caveats

We are basing the location of the user on a source IP address. As you probably know, Virtual Private Network (VPN) connections can easily allow a user to log in to the resource from one location, connect their VPN client to a VPN endpoint in another country within seconds, and log into (or simply interact with) the resource again.

This will give the appearance of an impossible traveler. This could still warrant investigation depending on your corporate security policy. For example, if VPNs are required, they broke policy by connecting to the resource without using the VPN. Or, if VPN clients are not allowed, this would help highlight that violation as well.

Existing Tools

There are plenty of tools, most specifically supporting cloud services, that can pinpoint impossible traveler situations. Some vendors may also categorize this activity as a part of user anomaly detection. Some vendors I'm familiar with (there are many more):

These services do work pretty well, but what if we are generating our own logs that need to be analyzed? Don't worry, I wrote a Python script for that...

get-travel-time.py

Located on my GitHub, there is a script that I... mostly wrote myself (thanks Stack Overflow) that you give a few parameters:

$ python get-travel-time.py -h

usage: get-travel-time.py [-h] [-k KMPH] firstIP secondIP

positional arguments:

firstIP

secondIP

optional arguments:

-h, --helpshow this help message and exit

-k KMPH, --kmph KMPHSpeed (in kmph)

What the script is essentially doing is taking your IP addresses, doing a GeoIP lookup to get their coordinates, then determining, based on the average speed you give it, how long it would take to get from the first IP to the second IP. By default, I chose the speed to default to 900kmph since, according to Wikipedia, the average cruising speed is between 880 and 926kmph.

To use this script, simply add the first IP in question, then the secondIP to get a rough time of how long it would take a commercial flight, at average cruising speed, to get from the first source to the second. If the time different between the two events is less than that, you have an anomaly. Let's take a look at the following log:

2020-02-03T20:02:17Z 13.14.15.16 "Login successful for ryanic"2020-02-03T21:13:11Z 15.16.17.18 "Login successful for ryanic"
If we were to do a GeoIP lookup (which the get-travel-time.py script is essentially doing), we would find that 13.14.15.16 is located in Norwalk, CT (IBM) and 15.16.17.18 is located in Houston, TX (HP). We would also find that these two locations are roughly 1,821km apart*.

* Assuming the GeoIP records are correct

In this situation, the user logged in just 1 hour, 10 minutes, and 54 seconds apart from these two locations. Let's use our script to see if this is possible given today's air travel:

$ python get-travel-time.py 13.14.15.16 15.16.17.18

Time to travel 1821.0 kilometers (Hours:Minutes)

-> 1:57

There you have it: Looks like that's a no. If you've traveled via commercial flights, you know we did not account for taxing to/from gates as well as getting up to cruising speed. This flight more realistically would take 3+ hours gate-to-gate.

This script is also flexible in that you can give it a different speed for commuters. Let's say average speed in your local commuting area is 60kmph. You can give the -k (or . --kmph) flag to the script and indicate the speed of your choice.

So, if you find your vendor does not support all "impossible traveler" situations, feel free to use my script!