The hacker, the lover and the cheater: Geolocation

Let me introduce this post by asking you a question: is it possible to obtain someone’s location by simply asking him/her to send you a picture?

You may think this is another of my nonsense questions, maybe it is, but before drawing any conclusion, you should read this story, it is a story of love, betrayal and…Computer science of course.

The story of the hacker, the lover and the cheater

undefinedBob is a young university student and, as many other students of his age, he enjoys spending his thoughtless nights between pubs and bars, drinking all kinds of cocktails such as Spritz and Martini. This is a good way to enjoy his own life and, at the same time, it is also a good chance to meet new friends and why not, even getting in touch with some girls.

undefined One evening, the long waited day finally arrives, Bob meets Alice, a very nice, smart and beautiful girl. She seems having a lot of experience in attracting naive boys like Bob, thus, it’s not hard for her to get close to him and steal his heart.

Bob’s love

After some flirts and drinks, immediately bursts out the love between them. Since that day, they spent happy and joyful days together, they often went to the cinema without missing any of the latest international movies and had fantastic dinners at various typical restaurants tasting all sort of delicious dishes their city could offer. They also enjoyed keeping in touch with the nature, having relax in the most amazing green areas and occasionally spending a visit to many of the romantic places hidden within the districts of their city.

But their adventure continued even abroad, they spent remarkable holidays travelling to the most romantic european cities such as Venice and Paris, tasting all kinds of local foods such as delicious italian ice creams and french baguette while enjoying the most beautiful landscapes and architectures like the romantic Rialto Bridge in Venice and the enchanting Eiffel Tower in Paris.

Alice’s mystery

One day, after his exam session, Bob messages Alice to invite her to some local party. After a while, she replies back but responds saying she will be very busy in the following days and will not have enough time to spend with Bob in the future. Then Bob waits, waits and waits. It already passed many weeks since the last time he had an appointment with his girlfriend but still nothing, Alice always finds and excuse not to meet with him. Hence, Bob is very sad, he doesn’t know what to do. Might have Alice betrayed him, or is she really busy?

Bob is very disappointed, although their relationship had just begun, her girlfriend already seems not caring about him anymore. Will this be the end? Could Alice have really betrayed Bob?

Heike’s plan

undefined Bob, not having any other choice, remembers he has a friend, Heike, who has always been able to solve many of his problems taking advantage of his advanced computer science skills. Heike is an expert of computer science and hacking, moreover, social engineering is one of his favorite skills. Social engineering, in the context of information security, is the psychological manipulation of people into performing actions or divulging confidential informations.

Bob explains his problem to his trusted friend, Heike. What he wants to know is where exactly is Alice and whether she is really so busy for her work as she says or she is just lying to him. Heike, after thinking over for a while, immediately comes up with a solution. He claims to be able to locate Alice’s position just by asking her to send a picture to Bob. The only two requirements are that the picture must be sent by Wechat and must be taken with her own phone’s camera.

You may belive this is impossible, how can Heike find out someone’s location just by asking to the other side to send him a picture?

Here is Heike’s solution:

Locating position through image metadata

Before beginning, we need to import two essentiel libraries:

  • geopy: it is an useful library which makes easy to locate the coordinates of addresses, cities, countries, and landmarks across the globe using third-party geocoders and other data sources.
  • PIL: or Pillow is Python library used to handle and visualize images, in particular, we are going to use it to extract from the metadata from an image.
from PIL.ExifTags import GPSTAGS
from PIL.ExifTags import TAGS
from PIL import Image
from geopy.geocoders import Nominatim

First of all, we are going to load ad image from its directory and extract its metadata or exif (exchangeable image file format).

# load image and extracts its metadata
filename = "images/my_image.jpg"
image =
exif = image._getexif()

Exif tags comprend several informations about the image itself, the phone from which it had been taken, the time of shooting, additional details about the type of the camera…And the GPS coordinates of the location where the picture had been taken. The problem is that these raw tags are unreadable from a programmer, they would just consists in a series of meaningless numbers.

We are then exploting the TAGS dictionary offered by the PIL library to map the various EXIF tags into constants and clear-text names understandable by humans.

# identify metadata attributes and make them human readable
labeled = {}
for (key, val) in exif.items():
    labeled[TAGS.get(key)] = val

By this point, we are already able to extract some useful informations from the input image such as the phone used to take it and even more important: what time that picture has been taken. Thus, if Alice would send Bob an old picture, we would immediately recognize it and, game over, we could even stop here.

print("Phone: {}".format(labeled['Make']))
print("Version: {}".format(labeled['Model']))
print("Time: {}".format(labeled['DateTimeOriginal']))

Anyway, Alice is not aware about Heike’s plan, so has no reason to cheat Bob by sending him a picture taken long time ago.

Hence, we continue with the next part. We are going to use another dictionary always offered by the PIL library to create an additional dictionary, which we will call geotags storing the some informations about the location where the picture has been taken.

# get a dictionary of some key geographic attributes
if not exif:
    raise ValueError("No EXIF metadata found")
geotags = {}  # dictionary of some key geographic attributes
for (idx, tag) in TAGS.items():
    if tag == 'GPSInfo':
        if idx not in exif:
            raise ValueError("No EXIF geotagging found")
        for (key, val) in GPSTAGS.items():
            if key in exif[idx]:
                geotagging[val] = exif[idx][key]

Among the extracted tags, 4 of the are particulary useful to track Alice’s position:

  • GPSLatitude: specifies the North–South position of a point on the Earth’s surface.
  • GPSLatitudeRef: specifies if the point is situated at the North or Sud respect to the Equator.
  • GPSLongitude: specifies the east–west position of a point on the Earth’s surface.
  • GPSLongitudeRef: specifies if the point is situated at the East or West respect to the prime meridian (Greenwitch).

An example of geographic coordinates is: (39°54’15.1272″N 116°24’26.6184″E) where the first value is the latitude and the second one is the longitude.

Beside the coordinates, we can also print the altitude of the location. What if Alice is having a relaxing holiday on the mountains?

print("Altitude: {}m".format(int(geotags['GPSAltitude'][0]/geotags['GPSAltitude'][1])))

Before we can track Alice’s position, we have to convert our coordinates system from the degrees°minutes’seconds” (dms) notation to the decimal notation (dd). For example, if we try to convert the previous dms format coordinates into dd ones we obtain: (39.904202, 116.407394). To perform this step, we can just use the get_decimal_from_dms function which return the input dms coordinate as dd format. We apply it to convert both latitude and longitude and print them.

# convert dms coordinates to dd
def get_decimal_from_dms(dms, ref):
    degrees = dms[0][0] / dms[0][1]
    minutes = dms[1][0] / dms[1][1] / 60.0
    seconds = dms[2][0] / dms[2][1] / 3600.0
    if ref in ['S', 'W']:
        degrees = -degrees
        minutes = -minutes
        seconds = -seconds
    return round(degrees + minutes + seconds, 5)

# get coordinates as dd type
lat = get_decimal_from_dms(geotags['GPSLatitude'], geotags['GPSLatitudeRef'])
lon = get_decimal_from_dms(geotags['GPSLongitude'], geotags['GPSLongitudeRef'])
coordinates = (lat, long)
print("Coordinates: {}".format(coordinates))

Now the game has almost finished. If we are geography experts we could even directly interpret these coordinates to have an initial vague idea about Alice’s location. Neverthelss, for us these are still meaningless numbers and have no idea how to interpret them. Then, we exploit the reverse method from the Nominatim class to send our coordinates to a web server and get back the corresponding address. That’s all, with less than 50 lines of code we are able to track Alice’s current position.

geolocator = Nominatim(user_agent="user", timeout=10)
location = geolocator.reverse(coordinates)
print("Address: {}".format(location.address))

Game over

Following Heike’s suggestion, Bob begins a new conversation with Alice, finding a smart and very natural way to convince her to send a picture to him while she remaining unaware of the trick which lies behind.

Not bad, it seems Alice is having a delicious dish of italian pasta. Now, Heike simply let’s his code finishing the job.

Phone: Xiaomi
Version: Red Note 5
Time: 2019:11:06 13:34:18
Altitude: 0m
Coordinates: (40.78448 17.23618)
Address: Via Tinelli, Alberobello, Bari, Puglia, 70011, Italia

And the cat is out of the bag! Alice is enjoying her holidays at Alberobello in Puglia, a beautiful coast region in the south of Italy famous for its healty but delicious food, its wonderful (but often crowded) coasts and its peculiar small cities which give to the tourist the feeling of living in a well preserved medieval village.

Typical buildings in Alberobello called “Trulli”, Puglia.

In conclusion, instead of working in her office as she lied to Bob, Alice seems having a thoughless and relaxing time in Italy. She really betrayed Bob!

At this point, for the poor Bob there is really nothing more he can do but giving up with Alice and continue with his monotonous student life.

How to fix it

The explained trick works only if the picture has been sent and downloaded as “Full image” using Wechat by selecting the appropriate option when downloading it. Otherwise, it would be downloaded a compressed version of the image which would lead in a loss of part of its metedata, GPS coordinates included. Of couse, if the picture has been taken with deactivated GPS function or for any other reasons the coordinates of the location where the picture has been taken are not available, the trick won’t work as well.


Leave a Reply

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

You are commenting using your 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