Telemetry, Spyware, list of privacy threats on FP3 Android 9

There is already a thread on how to uninstall or deactivate most google apps (gapps)
from the FP3 stock Android9.

(Also relevant: ✏ How to live without Google on a Fairphone 3 (FP3) )

Unfortunately the google apps are not the only preinstalled components on the FP3 that have undocumented telemetry capabilities and regularly or sporadically talk home.

Some of these connections are rare (once a week, once a month, once after each reboot) so it becomes a community effort to itentify components that are potential snitches and share unknown amount of data about your phone and its usage with undisclosed third parties.

Regardless of whether or how one should get rid of those or not, I think its important to document this behavior, as it potentially impairs your privacy, data and device security.

If you have a firewall app or a Third party firewall on a router running and find that any preinstalled or auto-installed software component or app makes outgoing or accepts incoming connections without your explicit request, please add to this thread so we can document.

What app it is
What kind of communication it is
Whats the official purpose
and maybe
What is the data being communicated
and also maybe
What are potential alternatives if the app is required for the phone.

Don’t hesitate to include the obvious (google) apps here as well. I disabled most of them, so I start with the more exotic ones that popped up later.



System app “Phone” (com.google.android.dialer)

System app “Qualcomm Mobile Security” com.qualcomm.qti.qms.service.telemetry

Unnamed System app “” (com.qualcomm.qti.qms.service.connectionsecurity)

  • Reason: Unexpected Background-Connection attempt to tls.telemetry.swe.quicinc.com port 443 (Host/Domain belongs to Qualcomm)
  • More Info: -
  • Identified via NetGuard app
  • Required for normal operation: Unknown
  • Alternative: Unknown

System app: “GPS daemon” (android.gps)

System app: “Android System” ()

  • Reason: Background-Connection attempt to port 123 via UDP
  • Frequency: After each reboot
  • More Info: UDP Port 123 is Network Time protocol. Android retrieves its system time from various time servers all over the world belonging to various organisations (most likely NTP pool servers
  • Identified via NetGuard app
  • Required for normal operation: Yes
  • Alternative: None - time servers are not configurable in Android 9
16 Likes

System app: “GPS daemon” (android.gps)
Reason: Unexpected Background-Connection attempt to xtrapath1.izatcloud.net port 80 (belongs to Qualcomm) (and others)
Frequency: Often (Hourly? Ish…) - happens with GPS off and all location services disabled!
More Info: -
Identified via NetGuard app
Required for normal operation: Unknown
Alternative: Unknown

The exact file is likely http://xtrapath1.izatcloud.net/xtra.bin, which contains the gps almanac. Turns out that aGPS implementations differ per vendor, which is why the domain is qualcomm owned.
Required? Only if you want fast GPS fixes / aGPS.

Edit: File may also be http://xtrapath1.izatcloud.net/xtra2.bin or similar; My point was that the connection is likely to do with downloading data to speed up GPS. Different files exist for different combinations of nav networks, e.g. xtra2.bin is GPS+Glonass. The file format is proprietary. More background in this security advisory.

5 Likes

In my opinion it would be a good idea, if the further postings by @corvuscorax would be copied into the wiki.
And, just a question of “design”; wouldn’t it be a good idea, to make just the APP a boldfaced entry and the reasons etc. standard faced.
This would - in my opinion - seperate the entries more clearly.
(To achive this even more, bullet-points could be used as well.)
It’s just, that all the fat letters are a bit tough on my eyes; which might of course be just my personal experience. So feel free to disregard it. :slight_smile:

4 Likes

Plaintext? Has anyone investigated how difficult it is to mangle the data of android.gps connection? Do you have a pcap?

Not yet. I have a deny rule in Netguard, so beyond the initial SYN packets (which were dropped) no data was exchanged. But it should be easy enough to capture that, either with Netguard or any other VVPN firewall app that can make pcaps, or an external sniffer. If you get a capture, feel free to share. Even if it’s a simple HTTP GET for the almanach binary, there might be leaked information in the HTTP header.

Edit: There are many ways to skin a cat. One is an app that intercepts the traffic similar to how NetGuard does (provide a virtual VPN network device that effectively just forwards the data to the previous gateway, but allows the app to inspect, drop, or modify the traffic. NetGuard is open source, look at https://github.com/M66B/NetGuard for how they do it.
The second is to setup a wifi gateway using a raspberry or similar and intercept/modify the traffic at the router level.
The third is to setup a proxy server, either using SOCKS or HTTP which can also intercept and modify the traffic. Privoxy might be a good (open source) starting point. https://www.privoxy.org/. Then configure the proxy in your android wifi network settings advanced settings (I think you need to manually add a new wifi connection to get that option, don’t just click on the network, you might have to forget the network first)
I don’t think one can set a proxy to be used for mobile data manually.

Edit2: Unlike android.gps most telemetry connections are encrypted using HTTPS. it might be possible to intercept these as well, with a custom root certificate authority and a well crafted man in the middle attack (aka raspberry pi router with a transparent proxy on it), unless the app in question does certificate pinning or stuff like that. I don’t know how to install custom root certificates in Android though.

Edit3: Wherever I wrote Raspberry above, you can of course use any device which can act as a wifi access point, for example a laptop or even desktop with a wifi USB stick put into AP/station mode and Linux on it :wink:

Edit4: Privoxy can proxy intercepted traffic https://www.privoxy.org/user-manual/config.html#ACCEPT-INTERCEPTED-REQUESTS - so all you need is that program running on your intercepting router (laptop, raspberry, …) and a set of matching firewall rules.
there’s a mini-howto here: http://www.tldp.org/HOWTO/TransparentProxy-6.html

Edit5: above howtos don’t cover the HTTPS part, only HTTP. For HTTPS you need to have privoxy listening on port 443 using TLS. For this you need a TLS frontend, which could be Apache2 or Stunnel, and a nice catchall certificate signed by a root certificate agency that you somehow import into android (dunno if this is even possible? )
that way the client app sees a genuine TLS encrypted server, while Privoxy sees a non-encrypted plain HTTP request. after that you’d need stunnel again to force privoxy to make outgoing HTTPS connections to the original target host… not completely trivial, might require code changes, but is definitely possible

3 Likes

I already tunnel through my VPN at home 24/7 over WireGuard, so I could have a look at the logs there, but I won’t have time for that cause deadlines.

For MITM proxy this is the default used in the infosec/pentest community

Java, and a license costs 365 EUR per year, but it does work quite well with a lot of advanced features. The free version has some annoyances (such as having to manually verify every dictionary attack entry). They also have a trial.

Else, there is e.g.

https://mitmproxy.org

PS: File magic reports the following

$ file xtra.bin
xtra.bin: SVr2 curses screen image, big-endian

I think that designation is by chance. To me looks like they are using a proprietary binary format for the GPS trajectory almanac, non-compressed (lots of zeroes in there) that by chance hits the magic ID for SVr2 binary terminal data, but that’s most likely a misidentification.

what would be more interesting are the HTTP headers that are sent by the app during the GET request and wether or not that reveals info about the phone, serial numbers, etc… what browser version, if any does it claim to be? If the server uses any information to track users, then it’d be in there.

1 Like

They can track you based on UserAgent headers alone, even with source IP address. The UserAgent headers I expect to show Android WebView or whatever it was called, but I didn’t verify.

It would be indeed probably be easiest to implement through the Android Web API in which case I would assume that, too. But of course an app could use its own HTTP implementation, and code any sorts of information into that header - both to prevent information from leaking or to leak additional information such as IMEI/serials/… no way to tell without reverse engineering it to some degree or looking at the pcap :wink:

I am pretty sure the GPS does not use a WebView for background network access.

More info, Official purpose:
https://www.qualcomm.com/site/privacy/services
https://www.qualcomm.com/site/privacy
via
http://izatcloud.net/

2 Likes

The relevant sections:

Qualcomm Location periodically sends us a unique software ID, the location of your device (longitude, latitude and altitude, and its uncertainty) and nearby cellular towers and Wi-Fi hotspots, signal strength, and time (collectively, “Location Data”). As with any Internet communication, we also receive the IP address your device uses. We use Location Data, software IDs and IP addresses, and the other data we collect to help us protect, evaluate, and improve the performance of our systems.

To enhance system performance your software ID and IP address are associated with your Location Data for thirty days from receipt after which time it is permanently deleted. After removing IP addresses and software IDs, we aggregate the Location Data to create an anonymous database regarding the locations of cellular towers and WiFi access points.

So in short, Qualcomm tracks where every single Fairphone user (Or other user with Qualcomm hardware) has been in the last 30 days. They also record the location of all Wifi networks and Cellphone towers encountered within radio range to make a detailed map. And they log all IP addresses one had during that timespan.

Although Qualcomm does not “identify” these users, identification would be trivial for any 3rd party who either knows

  • Who owned any of the involved IP address during any moment in the last 30 days that has been logged
  • The location of the involved person during a sufficient subset of the location history to profile and statistically match (for example both home and work location, both of which might be public)

Assuming I do not agree to this data collection and storage, who do I need to send a DSGVO letter? I don’t remember agreeing to Qualcomm’s privacy policy directly. I think the phone only showed me Google’s privacy policy on first boot/setup.

Where’s the mandatory opt-in / opt-out? The Quallcomm page only mentiones opt-in/out for the QTR Statistics, not Location.

5 Likes
$  host xtrapath1.izatcloud.net
xtrapath1.izatcloud.net is an alias for xtrapath1.qcomgeo2.com.
xtrapath1.qcomgeo2.com is an alias for xp1.gpsonextra.net.
xp1.gpsonextra.net is an alias for d3w2id5zlqvvik.cloudfront.net.
d3w2id5zlqvvik.cloudfront.net has address 13.35.253.48
d3w2id5zlqvvik.cloudfront.net has address 13.35.253.85
d3w2id5zlqvvik.cloudfront.net has address 13.35.253.81
d3w2id5zlqvvik.cloudfront.net has address 13.35.253.126

I don’t see any traffic to any of these hosts or IP addresses from my FP3. (I have disabled some services via ADB though.)

Cloudfront, like many content delivery networks, resolves to different random IPs depending on your ISP and carrier you use and where in the world you ask, as well as the time of day, moon phase, and number of other users in your area. When I just did the same check on my cable ISP, I got

d3w2id5zlqvvik.cloudfront.net. 45 IN A 143.204.101.22
d3w2id5zlqvvik.cloudfront.net. 45 IN A 143.204.101.49
d3w2id5zlqvvik.cloudfront.net. 45 IN A 143.204.101.101
d3w2id5zlqvvik.cloudfront.net. 45 IN A 143.204.101.102

I did the same again on my Fairphone, connected to mobile data and got instead

d3w2id5zlqvvik.cloudfront.net. 45 IN A 99.86.243.102
d3w2id5zlqvvik.cloudfront.net. 45 IN A 99.86.243.57
d3w2id5zlqvvik.cloudfront.net. 45 IN A 99.86.243.128
d3w2id5zlqvvik.cloudfront.net. 45 IN A 99.86.243.32

The GPS daemon service on my Fairphone tried to connect to yet another set of IPs, which are

13.224.196.116
52.222.169.135
52.222.169.178
13.224.196.35
13.224.196.125
13.224.196.68
13.224.196.83

and several dozen more, all of which have in common that they belong to amazon registered IP ranges and reverse resolve to server-[IP]-[location].cloudfront.net

An IP based blocklist wouldn’t cut it here, you’d have to block all IP blocks assigned to cloudflare. Aside from the problem of finding all of those, it would also break any other services and webpages which use cloudfront for content delivery - which as Russia found out the hard way when they tried to block Telegram - breaks a good portion of the Internet as all major webpages use content delivery networks these days, either to speed up the service or as DDOS mitigation, and Cloudflare is one of the biggest of those.

To inhibit these accesses, you can’t block traffic by destination IP, you’d have to instead block DNS requests that resolve the target domain to the cloudflare IP, or block based on the APP/userID (which unfortunately only works locally on the device). Unfortunately Fairphone, like all Android phones, are hardcoded to use 8.8.8.8 as a DNS server instead of your own, and with the advent of DoT (DNS over TLS), it becomes exceedingly difficult to interecept these.

1 Like

You can put “private DNS” off.

DoT generally runs on 853, making it easy to contain. A bigger issue is DoH, but that is also the purpose.

The box I use to sniff the traffic, is using the same resolver as the FP3.

I’ve used several regexp to ensure I was catching the traffic, including src IP and port 80, and then checking the headers.

Since it is HTTP it is plaintext. The only HTTP requests coming from my FP3 are weather API requests. I’m not yet sure which application is sending those over HTTP instead of HTTPS but ultimately it does not matter, as regardless of connectivity the connection between my FP3 is secured with a VPN to my home network.

I checked my logs. The last two times I had “GPS service” attempt a connection was on Dec. 2 between 1:01 and 1:04 am and then on Dec. 3 between 1:40 to 2:42 am with roughly 1 attempt every 10 minutes. No attempts since.

app is called “GPS daemon” (android.gps) - user ID 1021
Clicking on the “app info” button opens the system settings app which then - crashes

the app does not show up in the app list in settings

it also does not show up in adb shell with “pm list packages”

it seems to be installed in a hidden way and only active sporadically. so far I haven’t been able to get a pcap from it, since it simply didn’t attempt any connections since I enabled the logging :frowning:

I finally managed to get a packet capture. The enigmatic GPS daemon finally decided to contact its masters again last night at 01:52 am. It looks like tries to indeed get binary (Almanach?) data roughly once every 24 hours, preferably past midnight.

capture.pcap (26.6 KB)

Over a time of 10 minutes, it retrieved the same file from multiple servers
GET /xtra3grc.bin HTTP/1.1
from
Host: xtrapath3.izatcloud.net ( binary size 32232 )
Host: xtrapath2.izatcloud.net ( binary size 23498 )
Host: xtrapath3.izatcloud.net ( binary size 32232 ) (same file again?)
Host: xtrapath1.izatcloud.net ( binary size 24347 )

The full request looks like this:

GET /xtra3grc.bin HTTP/1.1
Host: xtrapath3.izatcloud.net 
Accept: */*, application/vnd.wap.mms-message, application/vnd.wap.sic
x-wap-profile: http://www.openmobilealliance.org/tech/profiles/UAPROF/ccppschema-20021212#
User-Agent: A/9/Fairphone/FP3/FP3/unknown/QCX3/l3557659004810866045/35781109/+111575957/-+262|01+262|03/Fairphone/36966/36953/-/3.0/1/W/0

with slight changes in user agent on the 2nd to 4th request:

User-Agent: A/9/Fairphone/FP3/FP3/unknown/QCX3/l3557659004810866045/35781109/+111575957/-+262|01+262|03/Fairphone/36969/36956/-/3.0/1/W/0
User-Agent: A/9/Fairphone/FP3/FP3/unknown/QCX3/l3557659004810866045/35781109/+111575957/-+262|01+262|03/Fairphone/37287/37274/-/3.0/1/W/0
User-Agent: A/9/Fairphone/FP3/FP3/unknown/QCX3/l3557659004810866045/35781109/+111575957/-+262|01+262|03/Fairphone/37287/37274/-/3.0/1/W/0

Interesting is the data revealed in the user agent. A/9 is obviously the OS, Android 9 Pie. Fairphone/FP3/FP3 seems to be manufacturer, model number and board. 35781109 I identified as the first 8 digits of the IMEI - also known as TAC (type allocation code) (this is identical for both SIM card slots)

I could not identify the long number, it is likely some sort of serial number.
It’s safe to assume that Qualcomm deliberately packed a lot of detailed identification data into this user agent string - probably more than enough to identify and track individual users, especially since some of the information is run time information changing between every request.

It’s possible that the 2 changing fields indicate what state information the phone is in. This is speculation, but since the phone did not learn new information by re-downloading the binary from xtrapath3.izatcloud.net, it sent the next GET request with the same identifiers.

I managed to get that pcap on the phone itself by letting WireGuard run over night with packet capturing enabled:


It’s interesting to note that GPS daemon cannot be disabled or uninstalled without rooting the device, since it does not even show in the list of installed applications (pm list packages) or running system services. The only way to prevent this data exchange is to leave wifi and data turned off during the night (or whenever GPS daemon tries to retrieve it) OR to install a firewall on the device that prevents this based on App/UserID.

4 Likes

While we’re on a roll, the elusive “GPS daemon” app runs with user id 1021. So if its running we might get some info on the adb shell via:

ps -u 1021 -f
UID            PID  PPID C STIME TTY          TIME CMD
gps            605     1 0 15:36:39 ?     00:00:01 vendor.qti.gnss@1.0-service
gps            728     1 0 15:36:40 ?     00:00:00 mlid
gps            736     1 0 15:36:40 ?     00:00:00 loc_launcher
gps            803   736 0 15:36:40 ?     00:00:01 lowi-server
gps            804   736 0 15:36:40 ?     00:00:00 xtwifi-inet-agent --gtp-wifi BASIC --gtp-modem-cell BASIC --gtp-ap-cell DISABLED --gtp-waa DISABLED
gps            805   736 0 15:36:40 ?     00:00:01 xtwifi-client --gtp-wifi BASIC --gtp-modem-cell BASIC --gtp-ap-cell DISABLED --gtp-waa DISABLED
gps            811   736 0 15:36:40 ?     00:00:00 slim_daemon --sap BASIC
gps            812   736 0 15:36:40 ?     00:00:00 xtra-daemon

user gps has user id 1021. We can get more info via

cat /proc/605/cmdline
/vendor/bin/hw/vendor.qti.gnss@1.0-service

the same reveals
/vendor/bin/mlid
/system/vendor/bin/loc_launcher

the rest is more elusive since no full paths are in /proc/…/cmdline given and a “find /” does not find any of the executables due to restrictive permissions
however one can find them indirectly
ls -la /vendor/bin/

ls: /vendor/bin//xtwifi-client: Permission denied
ls: /vendor/bin//xtwifi-inet-agent: Permission denied
ls: /vendor/bin//slim_daemon: Permission denied
ls: /vendor/bin//xtra-daemon: Permission denied
and
ls: /system/vendor/bin//lowi-server: Permission denied

It’s hard to tell which one of those is making the HTTP connection. Normally on Android each App runs with its own UID, which allows the firewall to filter and log traffic based on the app. However some UIDs are hardcoded

https://android.googlesource.com/platform/system/core.git/+/master/libcutils/include/private/android_filesystem_config.h

and “GPS daemon” is one of those hardcoded users (user gps) - so this is no app, this is indeed a “daemon” in the linux/unix sense of the word, running native code with elevated privileges. There is no “apk”. This is no “system app”, it’s part of the system.

It’s possible that one of the processes listed is doing these http connections. It’s also possible that this “loc_launcher” - which is obviously capable of launching additional processes is calling yet another program to do it once a night.

Due to the restrictive permissions of all the vendor tools, further reverse engineering would require rooting the device, since:

adb pull /vendor/bin/xtra-daemon
adb: error: failed to stat remote object '/vendor/bin/xtra-daemon': Permission denied

What could be done is hacking NetGuard (or another VPN based firewall app), to insert a trigger function when process 1021 makes any network connection that in turn calls “netstat” to figure out which process is responsible for it (And at the same time run “ps” in a loop from adb shell to get a list of running processes to match to the PID)

But one would still need “root” to access the executable and look into its disassembly to figure out what it does.

3 Likes

You could set in WireGuard to block all connections, except when it is enabled. This ensures you always use WireGuard as VPN. Then on the endpoint, you block port 80 outgoing, or these specific hosts.

People can also block network connection in android.gps, as the only GPS related which needs networking is AGPS. Which is optional, and just allows a quicker fix.

In long term, UnifedNlp is just better and more versatile than Google’s proprietary choice. The amount of backends alone is worth it.