More Background On SUPL, A-GPS, the Almanac and Ephemeris Data

After my previous posts on how to trace and analyze A-GPS SUPL requests (see here and here) I thought I'd also write a quick post with some references to more details on the parameters that are contained in an A-GPS SUPL message. When discussing GPS, two terms are regularly mentioned, The 'Almanac' and the 'Ephemeris data'. Here's a link to some background information on those terms and here's my abbreviated version:

Almanac: This information is broadcast by each GPS satellite and contains rough orbital parameters of each satellite. This information helps a GPS receiver to find other satellites during its startup procedure once it has decoded this information from a downlink signal. Note that this information is NOT contained in a SUPL response as it only gives long term rough orbital parameters that can only be used for satellite search but not for navigation.

Ephemeris: These are the precise orbital parameters of a satellite which is only valid for a short amount of time. While each satellite broadcasts the Almanac of all satellites, a satellite only broadcasts its own Ephemeris data. SUPL responses contain the Epehemeris data of all satellites the SUPL server thinks might be visible at the rough location a mobile device is currently located, perhaps, I'm not sure, in order of certainty, as the satellite IDs in the list were not ordered. I've also run a SUPL request with a cell-id that the SUPL server did not know and as a result the server returned a very long list of Ephemeris data with ordered satellite ID numbers, probably of all the satellites it knew.

And finally, here's a link to additional background information on the individual Epehemeris parameters.

How To Block Software Updates While Traveling On My VPN Access Point

In a previous post I've described how today's smartphones and tablets take Wi-Fi connectivity as an invitation for downloading large amounts of data for software updates and other things without user interaction. This is particularly problematic in Wi-Fi tethering scenarios and when using slow hotel Wi-Fi networks when traveling. But at least in the later case I can fix things by adding banned URLs in the 'hosts' file on my Raspberry Pi based VPN Wi-Fi Travel Router. After changing the hosts file, a quick restart of the DNS server on the router via 'sudo service dnsmasq restart' is required.

Over time, my hosts file has grown quite a bit since I first started to use it as a line of defense against unwanted advertising, privacy invasions and software downloads. Here's my current list:

127.0.0.1   localhost

#Prevent the device to contact Google all the time
127.0.0.1   mtalk.google.com
127.0.0.1   reports.crashlytics.com
127.0.0.1   settings.crashlytics.com
127.0.0.1   android.clients.google.com
127.0.0.1   www.googleapis.com
127.0.0.1   www.googleadservices.com
127.0.0.1   clients3.google.com
127.0.0.1   play.googleapis.com
127.0.0.1   www.gstatic.com
127.0.0.1   ssl.google-analytics.com
127.0.0.1   id.google.com
127.0.0.1   clients1.google.com
127.0.0.1   clients2.google.com

#Amazon is really nosy, too…
127.0.0.1   www.amazon.com
127.0.0.1   s.amazon-adsystem.com
127.0.0.1   api.amazon.com
127.0.0.1   device-metrics-us.amazon.com
127.0.0.1   device-metrics-us-1.amazon.com
127.0.0.1   device-metrics-us-2.amazon.com
127.0.0.1   device-metrics-us-3.amazon.com
127.0.0.1   device-metrics-us-4.amazon.com
127.0.0.1   device-metrics-us-5.amazon.com
127.0.0.1   device-metrics-us-6.amazon.com
127.0.0.1   device-metrics-us-7.amazon.com
127.0.0.1   device-metrics-us-8.amazon.com
127.0.0.1   device-metrics-us-9.amazon.com
127.0.0.1   device-metrics-us-10.amazon.com
127.0.0.1   device-metrics-us-11.amazon.com
127.0.0.1   device-metrics-us-12.amazon.com
127.0.0.1   mads.amazon.com
127.0.0.1   aax-us-east.amazon-adsystem.com
127.0.0.1   aax-us-west.amazon-adsystem.com
127.0.0.1   aax-eu.amazon-adsystem.com

#No need for Opera to call home all the time
127.0.0.1   mini5-1.opera-mini.net
127.0.0.1   sitecheck1.opera.com
127.0.0.1   sitecheck2.opera.com
127.0.0.1   thumbnails.opera.com

#Some more 'services' I don't need
127.0.0.1   audioscrobbler.com
127.0.0.1   weather.yahooapis.com
127.0.0.1   query.yahooapis.com
127.0.0.1   platform.twitter.com
127.0.0.1   linkedin.com

#Prevent automatic OS updates for a number of vendors
127.0.0.1   fota.cyngn.com
127.0.0.1   account.cyanogenmod.org
127.0.0.1   mdm.asus.com
127.0.0.1   mdmnotify1.asus.com
127.0.0.1   updatesec.sonymobile.com

#Ad blocking
127.0.0.1   ad8.adfarm1.adition.com
127.0.0.1   googleads.g.doubleclick.net
127.0.0.1   stats.g.doubleclick.net
127.0.0.1   mobile.smartadserver.com
127.0.0.1   www.google-analytics.com
127.0.0.1   pagead2.googlesyndication.com
127.0.0.1   ads.stickyadstv.com
127.0.0.1   pixel.rubiconproject.com
127.0.0.1   t1.visualrevenue.com
127.0.0.1   beacon.krxd.net
127.0.0.1   rtb.metrigo.com
127.0.0.1   c.metrigo.com
127.0.0.1   ad.zanox.com
127.0.0.1   cm.g.doubleclick.net
127.0.0.1   ib.adnxs.com
127.0.0.1   ih.adscale.de
127.0.0.1   ad.360yield.com
127.0.0.1   ssp-csynch.smartadserver.com
127.0.0.1   ad.yieldlab.net
127.0.0.1   dis.crieto.com
127.0.0.1   rtb.eanalyzer.de
127.0.0.1   connect.facebook.net
127.0.0.1   b.scorecardresearch.com
127.0.0.1   sb.scorecardresearch.com
127.0.0.1   ads.newtentionassets.net
127.0.0.1   ak.sascdn.com
127.0.0.1   fastly.bench.cedexis.com
127.0.0.1   probes.cedexis.com
127.0.0.1   x.ligatus.com
127.0.0.1   d.ligatus.com
127.0.0.1   a.visualrevenue.com
127.0.0.1   radar.cedexis.com
127.0.0.1   www.googletagservices.com
127.0.0.1   pubads.g.doubleclick.net
127.0.0.1   prophet.heise.de
127.0.0.1   farm.plista.com
127.0.0.1   static.plista.com
127.0.0.1   video.plista.com
127.0.0.1   tag.yoc-adserver.com

How To Trace An A-GPS SUPL Request

In a previous post I've described my results of tracing an A-GPS SUPL request from my mobile device to the Google GPS location service and the issues I've discovered. In this follow-up post I thought I'd give an overview of how to setup up an environment that allows to trace and decode the conversation.

Does Your Device Send SUPL Requests Over Wi-Fi?

Supl-requestThe first thing to find out before proceeding is whether a device sends SUPL requests over Wi-Fi at all. It seems that some devices don't and only use a celluar connection as SUPL requests are sent directly from the cellular baseband chip.

To trace SUPL on Wi-Fi there must be a point between the mobile device and the backhaul router to the Internet on which Wireshark or Tcpdump can be run to record the traffic. I've used my Raspberry Pi based VPN Wi-Fi Travel Router for the purpose. If you have an Android based device that is rooted it's also possible to run tcpdump directly on the device. The first screenshot on the left shows a DNS query for supl.google.com followed by an encrypted SUPL request to TCP port 7275 that you should see before proceeding. Note that a SUPL request is only done if the device thinks that the GPS receiver requires the information. A reliable way to trigger a SUPL request on my device was to reboot if I didn't see a SUPL request after starting an application that requests GPS information such as Osmand.

The Challenge

As the name suggests, the Secure User Plane Location (SUPL) protocol does not send plain text messages. Instead, a Secure Socket Layer (SSL) connection is used to encrypt the information exchange. The challenge therefore is to figure out a way to decrypt the messages. If you are not the NSA, the only chance to do this is to put a proxy between the SUPL client on the mobile device and the SUPL server on the Internet. This splits the single direct SSL Connection between client and server into two SSL connections which then allows to decrypt and re-encrypt all messages on the proxy. At first, I hoped I could do this with MitmProxy but this tool focuses on web protocols such as https and would not not proxy SUPL connections.

Compiling and Running SUPL-PROXY

After some research I came across SUPL-PROXY by Tatu Mannisto, a piece of open source software that does exactly what I wanted. Written in C it has to be compiled on the target system and it does so without too much trouble on a Raspberry Pi. The only thing I had to do in addition to what is described in the readme file is to set a path variable after compiling so the executable can find a self compiled library that is copied to a library directory. In essence the commands to compile supl-proxy, a couple of other binaries and to set the command variables are as follows:

#untar/zip and compile
mkdir supl
cd supl
tar xvzf ../supl_1.0.6.tar.gz
cd trunk
./configure –precompiled-asn1
make
sudo make install

#now set LD_LIBRARY_PATH. It does not seem to be used onthe PI as it is empty
echo $LD_LIBRARY_PATH
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib
echo $LD_LIBRARY_PATH
export LD_LIBRARY_PATH

First Test with SUPL-CLIENT

Before proceeding, it's a good idea to check if the supl package is working. This can be done by using SUPL-CLIENT which will send a SUPL request to a SUPL server. The command below uses a network and cell id in Finland:

supl-client –cell=gsm:244,5:0x59e2,0x31b0 –format human

If the request was successful the output will look as follows:

Reference Location:
  Lat: 61.469997
  Lon: 23.807695
  Uncertainty: 59 (2758.0 m)
Reference Time:
  GPS Week: 782
  GPS TOW:  5879974 470397.920000
  ~ UTC:    Fri Aug 22 10:39:58 2014
Ephemeris: 30 satellites
  # prn delta_n M0 A_sqrt OMEGA_0 i0 w OMEGA_dot i_dot Cuc Cus Crc Crs Cic Cis toe IODC toc AF0 AF1 AF2 bits ura health tgd OADA
[…]

Creating A SUPL-PROXY SSL Certificate

One more thing that needs to be done before SUPL-PROXY will run is to create an SSL certificate that it will send to a supl client during the connection establishment procedure. This is necessary as the proxy terminates the SSL connection to the client and creates a second SSL connection to the 'real' SUPL server on the Internet. This is done with a single command which creates a 'false' certificate for supl.google.com:

supl-cert supl.google.com

A Copy SSL Of The Server Certificate For The Client Device

The command above will create four files and one of them, srv-cert.pem, has to be compied to the mobile device and imported into the certificate store. For details, have a look at the description of how this is done for mitmproxy, a piece of software not used here, but which also requires this step.

What I noticed when I used SUPL-PROXY with my Android device was that the supl client did not check the validity of the server certificate and thus this step was not necessary. This is a serious security issue so if you want to know if your device properly checks the validity of the certificate don't copy the certificate to the mobile device and see if the SUPL request is aborted during the SSL connection establishment. Another approach is to first install it to be able to trace the SUPL request and later on remove the certificate again from the mobile device to see if SUPL requests are then properly aborted during the connection establishment phase.

Starting SUPL-PROXY

Once done, SUPL-PROXY can be started with the follwoing command:

supl-proxy supl.nokia.com

This will start the proxy which will then wait for an incoming SUPL request and forward it to supl.nokia.com.  Note that the incoming request from the client is for supl.google.com and the outgoing request will be to supl.nokia.com. This is not strictly necessary but makes the redirection of supl.google.com in the next step easier and also shows that Google's and Nokia's SUPL servers use the same protocol.

Redirecting SUPL Requests To The Proxxy

At this point all SUPL requests will still go directly to Google's server and not the local supl proxy so we need to redirect the request. If you have a rooted Android device you can modify the /etc/hosts file on the device and point supl.google.com to the IP address of the device on which SUPL-PROXY waits for an incoming request (e.g. 192.168.55.17 in the example below). Another option is to make the DNS server return the IP address of the device that runs SUPL-PROXY. In my setup with the Raspberry Pi VPN Wi-Fi Router this can be done by editing /etc/hosts on the Raspberry Pi router and then restarting the DNS server. Here are the commands:

sudo nano /etc/hosts
–> insert the follwoing line: 192.168.55.17   supl.google.com

sudo service dnsmasq restart

Tracing And Decoding A SUPL Request with SUPL-PROXY

At this point everything is in place for the SUPL request to go to SUPL-PROXY on the lcoal device. After rebooting the mobile device and starting an app that requests GPS information, the request is now sent to SUPL-PROXY which in turn will open a connection to the real SUPL server and display the decoded request and response. Here's how the output looks like:

pi@mitm-pi ~ $ supl-proxy supl.nokia.com
Connection from 192.168.55.16:48642
SSL connection using RC4-MD5
Client does not have certificate.
mobile => server
<ULP-PDU>
    <length>43</length>
    <version>
        <maj>1</maj>
        <min>0</min>
        <servind>0</servind>
    </version>
    <sessionID>
        <setSessionID>
            <sessionId>5</sessionId>
            <setId>
                <imsi>00 00 00 00 00 00 00 00</imsi>
            </setId>
        </setSessionID>
    </sessionID>
    <message>
        <msSUPLSTART>
            <sETCapabilities>
                <posTechnology>
                    <agpsSETassisted><true/></agpsSETassisted>
                    <agpsSETBased><true/></agpsSETBased>
                    <autonomousGPS><true/></autonomousGPS>
                    <aFLT><false/></aFLT>
[…]

The output is rather lengthy so I've only copy/pasted a part of it into this post to give you a basic idea of the level of detail that is shown.

Tracing And Decoding A SUPL Request with Wireshark

The SUPL-PROXY output contains all request and response details in great detail so one could stop right here and now. However, if you prefer to analyze the SUPL request / response details in Wireshark, here's how that can be done: While a SUPL request that goes to the 'real' SUPL server directly can't be decoded due to the use of SSL and the unavailability of the server's SSL key, it's possible to decode the SUPL request between the SUPL client and SUPL-PROXY as the server's SSL key is available. The SSL key was created during the certificate creation process described above. 'srv-priv.pem' contains the private key and can be imported in Wireshark as follows:

  • In Wireshark select "follow TCP stream" of a supl conversation. The TCP destination port is 7275
  • In the stream select "decode as –> SSL". The cipher suite exchange then becomes visible
  • Right-click on a certificate exchange packet and select "Protocl Preferneces –> RSA Key List"
  • Enter a new RSA key as shown in the first screenshot below. Important: The protocol is called "ulp", all in LOWERCASE (uppercase won't work!!!)

The second screenshot below shows how the output looks like once the SSL layer can be decrypted.

Have fun tracing!

Wireshark-supl-configuration Wireshark-supl-configuration-2