Privacy test: Apple Maps on iOS

February 10th, 2011

Let’s know have a look at network geolocation on iOS. I’ve done the test using an iPad 3G running iOS 4.2.1

The way iOS geolocates the mobile is much different from Android. As you’ll see hereunder, the Apple Maps application downloads a subset of the Wifi and Cellular databases around the mobile’s actual position and calculates the mobile location locally ; whereas, on Android, Google calculates the mobile location on their servers and sends it back to the Android device.

Here’s an Apple POST request to https://iphone-services.apple.com/clls/wloc which downloads a subset of the Wifi location database from Apple servers :

00000000  50 4f 53 54 20 68 74 74  70 73 3a 2f 2f 69 70 68  |POST https://iph|
00000010  6f 6e 65 2d 73 65 72 76  69 63 65 73 2e 61 70 70  |one-services.app|
00000020  6c 65 2e 63 6f 6d 2f 63  6c 6c 73 2f 77 6c 6f 63  |le.com/clls/wloc|
00000030  20 48 54 54 50 2f 31 2e  31 0a 0a 50 4f 53 54 20  | HTTP/1.1..POST |
00000040  68 74 74 70 73 3a 2f 2f  69 70 68 6f 6e 65 2d 73  |https://iphone-s|
00000050  65 72 76 69 63 65 73 2e  61 70 70 6c 65 2e 63 6f  |ervices.apple.co|
00000060  6d 2f 63 6c 6c 73 2f 77  6c 6f 63 20 48 54 54 50  |m/clls/wloc HTTP|
00000070  2f 31 2e 31 0a 48 6f 73  74 3a 20 69 70 68 6f 6e  |/1.1.Host: iphon|
00000080  65 2d 73 65 72 76 69 63  65 73 2e 61 70 70 6c 65  |e-services.apple|
00000090  2e 63 6f 6d 0a 55 73 65  72 2d 41 67 65 6e 74 3a  |.com.User-Agent:|
000000a0  20 6c 6f 63 61 74 69 6f  6e 64 20 28 75 6e 6b 6e  | locationd (unkn|
000000b0  6f 77 6e 20 76 65 72 73  69 6f 6e 29 20 43 46 4e  |own version) CFN|
000000c0  65 74 77 6f 72 6b 2f 34  38 35 2e 31 32 2e 37 20  |etwork/485.12.7 |
000000d0  44 61 72 77 69 6e 2f 31  30 2e 34 2e 30 0a 58 2d  |Darwin/10.4.0.X-|
000000e0  41 70 70 6c 65 2d 42 75  6e 64 6c 65 69 64 3a 20  |Apple-Bundleid: |
000000f0  63 6f 6d 2e 61 70 70 6c  65 2e 4d 61 70 73 0a 41  |com.apple.Maps.A|
00000100  63 63 65 70 74 3a 20 2a  2f 2a 0a 41 63 63 65 70  |ccept: */*.Accep|
00000110  74 2d 4c 61 6e 67 75 61  67 65 3a 20 65 6e 2d 75  |t-Language: en-u|
00000120  73 0a 41 63 63 65 70 74  2d 45 6e 63 6f 64 69 6e  |s.Accept-Encodin|
00000130  67 3a 20 67 7a 69 70 2c  20 64 65 66 6c 61 74 65  |g: gzip, deflate|
00000140  0a 43 6f 6e 74 65 6e 74  2d 54 79 70 65 3a 20 61  |.Content-Type: a|
00000150  70 70 6c 69 63 61 74 69  6f 6e 2f 78 2d 77 77 77  |pplication/x-www|
00000160  2d 66 6f 72 6d 2d 75 72  6c 65 6e 63 6f 64 65 64  |-form-urlencoded|
00000170  0a 43 6f 6e 74 65 6e 74  2d 4c 65 6e 67 74 68 3a  |.Content-Length:|
00000180  20 31 35 32 0a 0a 00 01  00 05 65 6e 5f 55 53 00  | 152......en_US.|
00000190  00 00 0b 34 2e 32 2e 31  2e 38 43 31 34 38 00 00  |...4.2.1.8C148..|
000001a0  00 01 00 00 00 78 12 12  0a 10 30 3a 32 35 3a 31  |.....x....0:25:1|
000001b0  35 3a 61 39 3a 34 63 3a  66 38 12 12 0a 10 32 3a  |5:a9:4c:f8....2:|
000001c0  32 35 3a 31 35 3a 61 39  3a 34 63 3a 66 61 12 12  |25:15:a9:4c:fa..|
000001d0  0a 10 32 3a 32 35 3a 31  35 3a 61 39 3a 34 63 3a  |..2:25:15:a9:4c:|
000001e0  66 39 12 11 0a 0f 35 63  3a 33 33 3a 38 65 3a 61  |f9....5c:33:8e:a|
000001f0  3a 31 36 3a 62 12 13 0a  11 33 36 3a 66 66 3a 38  |:16:b....36:ff:8|
00000200  38 3a 65 65 3a 36 34 3a  62 38 18 00 20 00 2a 0e  |8:ee:64:b8.. .*.|
00000210  63 6f 6d 2e 61 70 70 6c  65 2e 4d 61 70 73        |com.apple.Maps|

Different things can be highlighted :

  • Most part of the request is encoded the Google “Protocol Buffers” ; does it mean that Apple’s geolocation service is run by some Google technologies ?
  • The request is short and contains only mandatory information (the WIFI Mac adresses)

The “Protocol Buffers” part is decoded this way :

2 {
  1: "0:25:15:a9:4c:f8"
}

2 {
  1: "2:25:15:a9:4c:fa"
}

2 {
  1: "2:25:15:a9:4c:f9"
}

2 {
  1: "5c:33:8e:a:16:b"
}

2 {
  1: "36:ff:88:ee:64:b8"
}

3: 0

4: 0

5: "com.apple.Maps"

The response is quite long because it contains not less that 1542 entries containing the WIFI Mac adress and the position of the hotspot ; here’s the beginning of the response :

00000000  50 4f 53 54 20 68 74 74  70 73 3a 2f 2f 69 70 68  |POST https://iph|
00000010  6f 6e 65 2d 73 65 72 76  69 63 65 73 2e 61 70 70  |one-services.app|
00000020  6c 65 2e 63 6f 6d 2f 63  6c 6c 73 2f 77 6c 6f 63  |le.com/clls/wloc|
00000030  20 48 54 54 50 2f 31 2e  31 0a 0a 48 54 54 50 2f  | HTTP/1.1..HTTP/|
00000040  31 2e 31 20 32 30 30 20  4f 4b 0a 44 61 74 65 3a  |1.1 200 OK.Date:|
00000050  20 57 65 64 2c 20 30 32  20 46 65 62 20 32 30 31  | Wed, 02 Feb 201|
00000060  31 20 31 33 3a 34 34 3a  35 31 20 47 4d 54 0a 43  |1 13:44:51 GMT.C|
00000070  6f 6e 74 65 6e 74 2d 4c  65 6e 67 74 68 3a 20 35  |ontent-Length: 5|
00000080  37 38 38 37 0a 0a 00 01  00 00 00 01 00 00 e2 15  |7887............|
00000090  12 22 0a 10 30 3a 31 64  3a 36 61 3a 61 39 3a 62  |."..0:1d:6a:a9:b|
000000a0  31 3a 65 32 12 0e 08 bc  a6 a6 89 11 10 99 ee ec  |1:e2............|
000000b0  eb 01 18 45 12 21 0a 0f  30 3a 32 35 3a 31 35 3a  |...E.!..0:25:15:|
000000c0  34 61 3a 61 65 3a 34 12  0e 08 85 c3 a8 89 11 10  |4a:ae:4.........|
000000d0  9d c6 eb eb 01 18 3d 12  21 0a 0f 30 3a 31 34 3a  |......=.!..0:14:|
000000e0  61 34 3a 35 65 3a 65 34  3a 37 12 0e 08 f6 c1 a8  |a4:5e:e4:7......|
000000f0  89 11 10 e3 a3 eb eb 01  18 5e 12 22 0a 10 30 3a  |.........^."..0:|
00000100  31 65 3a 33 37 3a 61 63  3a 38 34 3a 39 61 12 0e  |1e:37:ac:84:9a..|
00000110  08 c0 bf a4 89 11 10 d4  8e e5 eb 01 18 32 12 20  |.............2. |
00000120  0a 0e 30 3a 33 3a 63 39  3a 37 30 3a 63 35 3a 39  |..0:3:c9:70:c5:9|
00000130  12 0e 08 e4 a8 a4 89 11  10 f4 f2 e4 eb 01 18 32  |...............2|
00000140  12 21 0a 0f 30 3a 31 66  3a 39 66 3a 65 34 3a 35  |.!..0:1f:9f:e4:5|
00000150  31 3a 35 12 0e 08 cc 9f  ac 89 11 10 b0 e8 f1 eb  |1:5.............|
00000160  01 18 32 12 23 0a 11 34  36 3a 36 63 3a 39 34 3a  |..2.#..46:6c:94:|
...

Here again, it’s encoded in Google “Protocol Buffers” format and is decoded this way :

2 {
  1: "0:1d:6a:a9:b1:e2"
  2 {
    1: 4582904636
    2: 494614297
    3: 69
  }
}

2 {
  1: "0:25:15:4a:ae:4"
  2 {
    1: 4582941061
    2: 494592797
    3: 61
  }
}

2 {
  1: "0:14:a4:5e:e4:7"
  2 {
    1: 4582940918
    2: 494588387
    3: 94
  }
  2 {
    1: "0:1e:37:ac:84:9a"
    2 {
      1: 4582875072
      2: 494487380
      3: 50
    }
  }
  2 {
    1: "0:3:c9:70:c5:9"
    2 {
      1: 4582872164
      2: 494483828
      3: 50
    }
  }
  2 {
    1: "0:1f:9f:e4:51:5"
    2 {
      1: 4583002060
      2: 494695472
      3: 50
    }
  }
…

So, for every WIFI hotspot known by Apple servers around my location, I get the corresponding location (latitude is the first number, longitude is the second) ; I don’t know exactly what’s the third number.

And, it’s the same kind of request/response for Cellular geolocation : a request is sent with cellular information (MCC, MNC, CellID, LAC) and the responses contains the list of cells around with corresponding latitude/longitude.

Once this information received, the Apple Maps application calculates the exact position of the device and then get the tiles needed to display the map with the location. Where does it get this tiles from ?

Here’s the request :

00000000  50 4f 53 54 20 68 74 74  70 3a 2f 2f 77 77 77 2e  |POST http://www.|
00000010  67 6f 6f 67 6c 65 2e 63  6f 6d 2f 67 6c 6d 2f 6d  |google.com/glm/m|
00000020  6d 61 70 20 48 54 54 50  2f 31 2e 31 0a 0a 50 4f  |map HTTP/1.1..PO|
00000030  53 54 20 68 74 74 70 3a  2f 2f 77 77 77 2e 67 6f  |ST http://www.go|
00000040  6f 67 6c 65 2e 63 6f 6d  2f 67 6c 6d 2f 6d 6d 61  |ogle.com/glm/mma|
00000050  70 20 48 54 54 50 2f 31  2e 31 0a 48 6f 73 74 3a  |p HTTP/1.1.Host:|
00000060  20 77 77 77 2e 67 6f 6f  67 6c 65 2e 63 6f 6d 0a  | www.google.com.|
00000070  55 73 65 72 2d 41 67 65  6e 74 3a 20 41 70 70 6c  |User-Agent: Appl|
00000080  65 20 69 50 68 6f 6e 65  20 76 38 43 31 34 38 20  |e iPhone v8C148 |
00000090  4d 61 70 73 20 76 34 2e  32 2e 31 0a 41 63 63 65  |Maps v4.2.1.Acce|
000000a0  70 74 3a 20 2a 2f 2a 0a  41 63 63 65 70 74 2d 4c  |pt: */*.Accept-L|
000000b0  61 6e 67 75 61 67 65 3a  20 66 72 2d 66 72 0a 41  |anguage: fr-fr.A|
000000c0  63 63 65 70 74 2d 45 6e  63 6f 64 69 6e 67 3a 20  |ccept-Encoding: |
000000d0  67 7a 69 70 2c 20 64 65  66 6c 61 74 65 0a 43 6f  |gzip, deflate.Co|
000000e0  6e 74 65 6e 74 2d 54 79  70 65 3a 20 61 70 70 6c  |ntent-Type: appl|
000000f0  69 63 61 74 69 6f 6e 2f  78 2d 77 77 77 2d 66 6f  |ication/x-www-fo|
00000100  72 6d 2d 75 72 6c 65 6e  63 6f 64 65 64 0a 43 6f  |rm-urlencoded.Co|
00000110  6e 74 65 6e 74 2d 4c 65  6e 67 74 68 3a 20 31 37  |ntent-Length: 17|
00000120  36 0a 0a 00 0e c0 b0 91  8b f6 07 30 fb 00 05 66  |6..........0...f|
00000130  72 5f 46 52 00 1d 63 6f  6d 2e 61 70 70 6c 65 2e  |r_FR..com.apple.|
00000140  69 70 61 64 2d 63 6f 6d  2e 61 70 70 6c 65 2e 4d  |ipad-com.apple.M|
00000150  61 70 73 00 0b 34 2e 32  2e 31 2e 38 43 31 34 38  |aps..4.2.1.8C148|
00000160  3e 00 00 00 0f 0a 03 34  31 37 10 01 20 00 a8 01  |>......417.. ...|
00000170  00 c0 01 02 1a 00 08 00  02 01 00 00 00 00 00 00  |................|
00000180  00 80 3f 02 00 00 41 c5  00 00 2d a0 10 02 00 00  |..?...A...-.....|
00000190  41 c5 00 00 2d a1 10 02  00 00 41 c5 00 00 2d 9f  |A...-.....A...-.|
000001a0  10 02 00 00 41 c5 00 00  2d 9e 10 02 00 00 41 c5  |....A...-.....A.|
000001b0  00 00 2d a2 10 02 00 00  41 c5 00 00 2d a3 10 02  |..-.....A...-...|
000001c0  00 00 41 c5 00 00 2d 9d  10 02 00 00 41 c5 00 00  |..A...-.....A...|
000001d0  2d 9c 10                                          |-..|

As you can see, the map tiles are retrieved directly from Google servers using a POST request to http://www.google.com/glm/mmap – that’s an other clue showing that Apple uses Google technology to power its Maps application.

I couldn’t really decode the request but we can find 8 times the quite-same numbers :

  • 02 00 00 41 c5 00 00 2d a0 10
  • 02 00 00 41 c5 00 00 2d a1 10
  • 02 00 00 41 c5 00 00 2d 9f 10
  • 02 00 00 41 c5 00 00 2d 9e 10
  • 02 00 00 41 c5 00 00 2d a2 10
  • 02 00 00 41 c5 00 00 2d a3 10
  • 02 00 00 41 c5 00 00 2d 9d 10
  • 02 00 00 41 c5 00 00 2d 9c 10

It appears that this is the position of the different tiles that are downloaded.

This is the beginning of the response (as you understand, it’s quite long) :

00000000  50 4f 53 54 20 68 74 74  70 3a 2f 2f 77 77 77 2e  |POST http://www.|
00000010  67 6f 6f 67 6c 65 2e 63  6f 6d 2f 67 6c 6d 2f 6d  |google.com/glm/m|
00000020  6d 61 70 20 48 54 54 50  2f 31 2e 31 0a 0a 48 54  |map HTTP/1.1..HT|
00000030  54 50 2f 31 2e 31 20 32  30 30 20 4f 4b 0a 43 6f  |TP/1.1 200 OK.Co|
00000040  6e 74 65 6e 74 2d 54 79  70 65 3a 20 61 70 70 6c  |ntent-Type: appl|
00000050  69 63 61 74 69 6f 6e 2f  62 69 6e 61 72 79 0a 43  |ication/binary.C|
00000060  6f 6e 74 65 6e 74 2d 4c  65 6e 67 74 68 3a 20 34  |ontent-Length: 4|
00000070  33 30 38 35 0a 44 61 74  65 3a 20 57 65 64 2c 20  |3085.Date: Wed, |
00000080  30 32 20 46 65 62 20 32  30 31 31 20 31 33 3a 34  |02 Feb 2011 13:4|
00000090  34 3a 35 35 20 47 4d 54  0a 45 78 70 69 72 65 73  |4:55 GMT.Expires|
000000a0  3a 20 57 65 64 2c 20 30  32 20 46 65 62 20 32 30  |: Wed, 02 Feb 20|
000000b0  31 31 20 31 33 3a 34 34  3a 35 35 20 47 4d 54 0a  |11 13:44:55 GMT.|
000000c0  43 61 63 68 65 2d 43 6f  6e 74 72 6f 6c 3a 20 70  |Cache-Control: p|
000000d0  72 69 76 61 74 65 2c 20  6d 61 78 2d 61 67 65 3d  |rivate, max-age=|
000000e0  30 0a 58 2d 43 6f 6e 74  65 6e 74 2d 54 79 70 65  |0.X-Content-Type|
000000f0  2d 4f 70 74 69 6f 6e 73  3a 20 6e 6f 73 6e 69 66  |-Options: nosnif|
00000100  66 0a 58 2d 46 72 61 6d  65 2d 4f 70 74 69 6f 6e  |f.X-Frame-Option|
00000110  73 3a 20 53 41 4d 45 4f  52 49 47 49 4e 0a 58 2d  |s: SAMEORIGIN.X-|
00000120  58 53 53 2d 50 72 6f 74  65 63 74 69 6f 6e 3a 20  |XSS-Protection: |
00000130  31 3b 20 6d 6f 64 65 3d  62 6c 6f 63 6b 0a 53 65  |1; mode=block.Se|
00000140  72 76 65 72 3a 20 47 53  45 0a 0a 00 0e 3e 00 00  |rver: GSE....>..|
00000150  00 00 1a 00 18 00 00 08  02 00 00 41 c5 00 00 2d  |...........A...-|
00000160  a0 10 1d bf 4c 54 49 50  0a 00 00 00 11 22 0f 0a  |....LTIP....."..|
00000170  0a 54 65 6c 65 20 41 74  6c 61 73 18 db 0f 89 50  |.Tele Atlas....P|
00000180  4e 47 0d 0a 1a 0a 00 00  00 0d 49 48 44 52 00 00  |NG........IHDR..|
00000190  01 00 00 00 01 00 08 03  00 00 00 6b ac 58 54 00  |...........k.XT.|
000001a0  00 00 09 70 48 59 73 00  00 00 1c 00 00 00 1c 00  |...pHYs.........|
000001b0  0f 01 b9 8f 00 00 00 54  50 4c 54 45 eb e6 dc f2  |.......TPLTE....|
000001c0  ef e9 ff ff ff d1 d0 cd  e0 d8 d0 ef eb e6 e0 e0  |................|
000001d0  e0 e6 e0 d5 dc d5 c9 bd  bd bd d1 cd bd c9 c1 ad  |................|
000001e0  f7 f7 f2 fb fb f7 d0 c5  b5 ad ad ad d8 d0 c1 3d  |...............=|
000001f0  3d 3d 2d 2d 2d 7d 7d 7d  8d 8d 8d a1 a1 a1 cd c9  |==---}}}........|
00000200  c1 5d 5d 5d c5 b9 a9 c9  c1 b5 6d 6d 6d 4d 4d 4d  |.]]]......mmmMMM|
…

You can see in the response a ‘PNG’ header and we can find this header 8 times in the whole response – so this is the 8 tiles in PNG format that are sent to the iOS device.

To conclude :

  • This test shows that Apple is much more ‘privacy-friendly’ with its network geolocation feature in the Maps application when compared to Google ones on Android : whereas Google Maps sends to Google servers identified location data (linked to your gmail account), the Apple Maps application only sends the mandatory information to do the network geolocation
  • The Apple network geolocation service seems to heavily rely on Google technology (Google “protocol buffers” encoding, Google servers to retrieve map tiles) – we can wonder if the network geolocation databases are also shared with Google
  • By the way the Apple network geolocation feature works (downloading subset of the network geolocation databases and probably caching the results on the device), we can assume that it’s more performant than Google one (where the device has to issue a request to Google for every network geolocation)

Dan.

Android Network Location Provider

February 8th, 2011

So, I’ve studied the information flow when using the ‘Network location provider’ supplied with my Galaxy Tab (it’s certainly the same provider from Google which is included in every Android device). I would have assumed that Google Maps use this provider to get the location and so that I find the same information flow. I was wrong…

In fact, the network location provider uses HTTPS request to  https://www.google.com/loc/m/api (do you remember ? this is the same URL to which location data is sent in background – see this post). For test purpose, and as I’m too lazy to write an app, I’ve used this sample.

The ‘protocol buffers’ part of the request is pretty much the same of the one described in my previous post ; there is still some binary protocol I don’t understand but there’s no chance the data can be used to identify people.

The response was a little bit more complex to decode. Here’s the binary :

00000000  50 4f 53 54 20 68 74 74  70 73 3a 2f 2f 77 77 77  |POST https://www|
00000010  2e 67 6f 6f 67 6c 65 2e  63 6f 6d 2f 6c 6f 63 2f  |.google.com/loc/|
00000020  6d 2f 61 70 69 20 48 54  54 50 2f 31 2e 31 0a 0a  |m/api HTTP/1.1..|
00000030  48 54 54 50 2f 31 2e 31  20 32 30 30 20 4f 4b 0a  |HTTP/1.1 200 OK.|
00000040  43 6f 6e 74 65 6e 74 2d  54 79 70 65 3a 20 61 70  |Content-Type: ap|
00000050  70 6c 69 63 61 74 69 6f  6e 2f 62 69 6e 61 72 79  |plication/binary|
00000060  0a 43 6f 6e 74 65 6e 74  2d 44 69 73 70 6f 73 69  |.Content-Disposi|
00000070  74 69 6f 6e 3a 20 61 74  74 61 63 68 6d 65 6e 74  |tion: attachment|
00000080  0a 43 61 63 68 65 2d 43  6f 6e 74 72 6f 6c 3a 20  |.Cache-Control: |
00000090  6e 6f 2d 63 61 63 68 65  2c 20 6e 6f 2d 73 74 6f  |no-cache, no-sto|
000000a0  72 65 2c 20 6d 61 78 2d  61 67 65 3d 30 2c 20 6d  |re, max-age=0, m|
000000b0  75 73 74 2d 72 65 76 61  6c 69 64 61 74 65 0a 50  |ust-revalidate.P|
000000c0  72 61 67 6d 61 3a 20 6e  6f 2d 63 61 63 68 65 0a  |ragma: no-cache.|
000000d0  45 78 70 69 72 65 73 3a  20 46 72 69 2c 20 30 31  |Expires: Fri, 01|
000000e0  20 4a 61 6e 20 31 39 39  30 20 30 30 3a 30 30 3a  | Jan 1990 00:00:|
000000f0  30 30 20 47 4d 54 0a 44  61 74 65 3a 20 54 75 65  |00 GMT.Date: Tue|
00000100  2c 20 30 38 20 46 65 62  20 32 30 31 31 20 31 36  |, 08 Feb 2011 16|
00000110  3a 33 32 3a 34 38 20 47  4d 54 0a 58 2d 43 6f 6e  |:32:48 GMT.X-Con|
00000120  74 65 6e 74 2d 54 79 70  65 2d 4f 70 74 69 6f 6e  |tent-Type-Option|
00000130  73 3a 20 6e 6f 73 6e 69  66 66 0a 58 2d 46 72 61  |s: nosniff.X-Fra|
00000140  6d 65 2d 4f 70 74 69 6f  6e 73 3a 20 53 41 4d 45  |me-Options: SAME|
00000150  4f 52 49 47 49 4e 0a 58  2d 58 53 53 2d 50 72 6f  |ORIGIN.X-XSS-Pro|
00000160  74 65 63 74 69 6f 6e 3a  20 31 3b 20 6d 6f 64 65  |tection: 1; mode|
00000170  3d 62 6c 6f 63 6b 0a 43  6f 6e 74 65 6e 74 2d 4c  |=block.Content-L|
00000180  65 6e 67 74 68 3a 20 38  39 0a 53 65 72 76 65 72  |ength: 89.Server|
00000190  3a 20 47 53 45 0a 0a 00  02 00 00 00 51 81 00 00  |: GSE.......Q...|
000001a0  03 00 c8 00 01 67 00 00  00 48 1f 8b 08 00 00 00  |.....g...H......|
000001b0  00 00 00 00 e3 60 10 72  e1 60 10 92 e0 e2 e2 f5  |.....`.r.`......|
000001c0  b0 f7 93 16 3d f7 ed 23  93 c4 75 76 05 6f 83 33  |....=..#..uv.o.3|
000001d0  bf 7e 6c 78 a0 2a a5 c6  85 53 4e 88 8b e3 26 8b  |.~lx.*...SN...&.|
000001e0  40 ad 04 97 c2 05 46 00  dd cf f3 f3 48 00 00 00  |@.....F.....H...|

The hard thing is that only a port of the response is gzip-compressed (beginning with the bytes ‘1f 8b’). Once uncompressed, the data is encoded in ‘protocol buffers’ :

1: 0
2 {
  1: 0
  2 {
    1 {
      1: 0x1b4e3f48
      2: 0x02f1f6ce
    }
    3: 983
    4: 75
    6: 1297182768460
  }
  3 {
    1 {
      1 {
        1: 0x1b4e3f48
        2: 0x02f1f6ce
      }
      3: 983
      4: 75
      6: 1297182768460
    }
    2 {
      1: 601
      2: 125
      3: 10
      4: 208
    }
  }
}

Among the different numbers, we can find the latitude and longitude (1b4e… and 02f1…).

That leads me to different conclusion :

  • It seems that the ‘network location provider’ component is much more privacy-friendly than Google Maps as it doesn’t send personal information ; thus, a ‘Google maps’ like app which uses this provider is safe.
  • It also shows that Google absolutely don’t have to send personal information back to their servers in order to run the service and they certainly have other idea in their head

Dan.

Google Maps on Android = Google geolocates you

February 4th, 2011

Hi,

following my previous post about privacy issues using Google Maps geolocation on Android, I’ve made some other tests by disabling the “poor man gps” feature (geolocation using wireless networks) to check if, then, Google was more friendly with our privacy… The answer is NO !!!

Indeed, even if you only enable GPS for geolocation, Maps will still send all wireless networks information (Wifi hotspots, cellular information) to Google Server. What’s shocking is that Google absolutely don’t need these wireless networks information, as Maps uses your GPS for geolocation… And, last but not least, all this information is not anonymized and linked to your gmail account.

So, every time you open Google Maps, Google geolocates you !!!

Dan.

iPad, iOS 4.2.1 – Activation

February 1st, 2011

So, let’s have some fun with an iPad. My test iPad has 16GB RAM, is a 3G-enabled version (but I don’t yet have the micro-SIM card) and runs iOS 4.2.1 ; I’ll have to rerun some tests when I have this micro-SIM card because I could have missed some information leakage.

When you buy an iPad (or an iPhone), the first step is the activation ; you have to go through this process to be able to use you new toy. In this pots, I’ll analyze which information are sent to Apple servers when you activate your product.

As the activation is done from a workstation running iTunes, we won’t capture the traffic from the iPad but from the iTunes workstation.

The most interesting request is a POST request sent to albert.apple.com (using SSL) ; the content of the request is quite easily understandable. Here’s the request :

POST https://albert.apple.com/WebObjects/ALUnbrick.woa/wa/deviceActivation HTTP/1.1
Host: albert.apple.com
Content-Length: 8037
Content-Type: multipart/form-data; boundary=CB8F39A9DDFB294C760CA7E9D7874560
X-Dsid: 22399XXXX
X-Apple-Store-Front: 143442-3,12
X-Apple-Tz: 3600
User-Agent: iTunes/10.1.1 (Macintosh; Intel Mac OS X 10.6.6) AppleWebKit/533.19.4
Accept-Language: fr-fr, fr;q=0.75, en-us;q=0.50, en;q=0.25
Cookie: X-Dsid=22399XXXX; ...
Accept-Encoding: gzip
--CB8F39A9DDFB294C760CA7E9D7874560
Content-Disposition: form-data; name="machineName"
MacBook Air de Daniel FAGES
--CB8F39A9DDFB294C760CA7E9D7874560
Content-Disposition: form-data; name="ECID"
2344532XXXXXX
--CB8F39A9DDFB294C760CA7E9D7874560
Content-Disposition: form-data; name="activation-info"
<dict>
<key>ActivationInfoComplete</key>
<true/>
<key>ActivationInfoXML</key>
<data>
PD94bWwgdmVyc2l...
</data>
<key>FairPlayCertChain</key>
<data>
MIICwjCCAiug...
</data>
<key>FairPlaySignature</key>
<data>
UG8R8b5W...
</data>
</dict>
--CB8F39A9DDFB294C760CA7E9D7874560
Content-Disposition: form-data; name="guid"
001F5BD4XXXX
--CB8F39A9DDFB294C760CA7E9D7874560
Content-Disposition: form-data; name="InStoreActivation"
false
--CB8F39A9DDFB294C760CA7E9D7874560
Content-Disposition: form-data; name="AppleSerialNumber"
J3049NDXXXX
--CB8F39A9DDFB294C760CA7E9D7874560
Content-Disposition: form-data; name="IMEI"
012436009XXXXXX
--CB8F39A9DDFB294C760CA7E9D7874560--

The following private information can be found in the request :

  • My workstation’s machine name (on which iTunes is running)
  • The ECID of the iPad (this is on of the ID)
  • The MAC adress of my workstation !!! (under the ‘guid’ variable name)
  • The serial number of the iPad
  • The IMEI of the iPad

Then, I can also decode the ‘ActivationInfoXML’ part (which is only encoded in base64) and I get the following information :

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>ActivationRandomness</key>
<string>2A1D70EA-42D8-...</string>
<key>ActivationRequiresActivationTicket</key>
<true/>
<key>ActivationState</key>
<string>Unactivated</string>
<key>BasebandMasterKeyHash</key>
<string>E93B43F3EF6...</string>
<key>BasebandThumbprint</key>
<string>553120E443A3...</string>
<key>BuildVersion</key>
<string>8C148</string>
<key>DeviceCertRequest</key>
<data>
LS0tLS1CR...
</data>
<key>DeviceClass</key>
<string>iPad</string>
<key>InternationalMobileEquipmentIdentity</key>
<string>012436009XXXXXX</string>
<key>ModelNumber</key>
<string>MC349</string>
<key>ProductType</key>
<string>iPad1,1</string>
<key>ProductVersion</key>
<string>4.2.1</string>
<key>SIMStatus</key>
<string>kCTSIMSupportSIMStatusNotInserted</string>
<key>SerialNumber</key>
<string>J3049NDXXXX</string>
<key>SupportsPostponement</key>
<true/>
<key>UniqueChipID</key>
<integer>234453299XXXX</integer>
<key>UniqueDeviceID</key>
<string>a83c0c6ca990...</string>
</dict>
</plist>

We can find again the IMEI, the Serial Number but also the UDID (Unique Device ID) which is an ID often used by Apple, and a ‘UniqueChipID’ which I don’t know exactly what it is… The SIM status is also sent to Apple but, as you can read, there was no SIM inserted  ; that’s why I’ll have to make an other test with a SIM to check if SIM-related information are also sent.

Bye,

Dan.

Don’t launch the Gameloft Nova game !!!

January 28th, 2011

Just a quick post : I’ve just made a quick privacy test with the applications provided with my Samsung Galaxy Tab. I realized that one of this application – the famous (?) Nova game from Gameloft – send not only your IMEI but also your PHONE NUMBER to a gameloft server without any user acceptance.

Here’s the GET request :

GET http://confirmation.gameloft.com/sms/unlock_profiles.phpgame=H002&network_country_ISO=fr&
network_operator=20810&network_operator_name=F%SFR&sim_country_iso=fr&sim_operator=20810&
sim_operator_name=&line_number=+3368986XXXX&is_network_roaming=false&
android_build_device=GTP1000&android_build_model=GTP1000 HTTP/1.1

User-Agent: Mozilla/5.0 (Linux; U; Android 2.2; fr-fr; GT-P1000 Build/FROYO) AppleWebKit/533.1
(KHTML, like Gecko) Version/4.0 Mobile Safari/533.1
x-android-os-build-model: GT-P1000
x-up-gl-subno: +3368986XXXX
x-up-gl-imei: 35296XXXXXXXXXX
Host: confirmation.gameloft.com
You can see the following information sent to the confirmation.gameloft.com server :
- my country (France)
- my network operator (20810 == SFR)
- my network operator name (‘F SFR’)
- my PHONE NUMBER (+3368986XXXX) both in the URL and in the ‘x-up-gl-subno’ header
- my IMEI (in the ‘x-up-gl-imei’ header)

If you ever launched this game and now receive some SMS SPAM, don’t be surprised !!!
Dan.

First privacy test : Android/Samsung Galaxy Tab (part 4)

January 25th, 2011

As promised, here’s more information about the https://www.google.com/loc/m/api requests that are sent to Google servers.

It appears that these requests are automatically issued in background, without any user intervention – they are related to the use of the “poor-man GPS” feature and to the acceptance of the “Allow Google’s location service to collect anonymous location data. Collection will occur even when no applications are running” popup.

So, let’s have a look at the decrypted POST request :

00000000  50 4f 53 54 20 68 74 74  70 73 3a 2f 2f 77 77 77  |POST https://www|
00000010  2e 67 6f 6f 67 6c 65 2e  63 6f 6d 2f 6c 6f 63 2f  |.google.com/loc/|
00000020  6d 2f 61 70 69 20 48 54  54 50 2f 31 2e 31 0a 0a  |m/api HTTP/1.1..|
00000030  50 4f 53 54 20 68 74 74  70 73 3a 2f 2f 77 77 77  |POST https://www|
00000040  2e 67 6f 6f 67 6c 65 2e  63 6f 6d 2f 6c 6f 63 2f  |.google.com/loc/|
00000050  6d 2f 61 70 69 20 48 54  54 50 2f 31 2e 31 0a 43  |m/api HTTP/1.1.C|
00000060  6f 6e 74 65 6e 74 2d 54  79 70 65 3a 20 61 70 70  |ontent-Type: app|
00000070  6c 69 63 61 74 69 6f 6e  2f 62 69 6e 61 72 79 0a  |lication/binary.|
00000080  43 6f 6e 74 65 6e 74 2d  4c 65 6e 67 74 68 3a 20  |Content-Length: |
00000090  31 30 34 32 0a 48 6f 73  74 3a 20 77 77 77 2e 67  |1042.Host: www.g|
000000a0  6f 6f 67 6c 65 2e 63 6f  6d 0a 55 73 65 72 2d 41  |oogle.com.User-A|
000000b0  67 65 6e 74 3a 20 47 4d  4d 2f 33 2e 30 20 28 47  |gent: GMM/3.0 (G|
000000c0  54 2d 50 31 30 30 30 20  46 52 4f 59 4f 29 3b 20  |T-P1000 FROYO); |
000000d0  67 7a 69 70 0a 0a 00 02  00 00 22 6c 6f 63 61 74  |gzip......"locat|
000000e0  69 6f 6e 2c 31 2e 30 2c  61 6e 64 72 6f 69 64 2c  |ion,1.0,android,|
000000f0  61 6e 64 72 6f 69 64 2c  65 6e 5f 55 53 db e7 8a  |android,en_US...|
00000100  d2 2c 06 8c b5 00 01 67  00 00 03 d9 00 01 00 00  |.,.....g........|
00000110  02 00 08 67 3a 6c 6f 63  2f 71 6c 00 00 00 00 03  |...g:loc/ql.....|
00000120  c7 0a 8f 01 0a 03 31 2e  30 12 4c 61 6e 64 72 6f  |......1.0.Landro|
00000130  69 64 2f 73 61 6d 73 75  6e 67 2f 47 54 2d 50 31  |id/samsung/GT-P1|
00000140  30 30 30 2f 47 54 2d 50  31 30 30 30 2f 47 54 2d  |000/GT-P1000/GT-|
00000150  50 31 30 30 30 3a 32 2e  32 2f 46 52 4f 59 4f 2f  |P1000:2.2/FROYO/|
00000160  42 55 4a 49 34 3a 75 73  65 72 2f 72 65 6c 65 61  |BUJI4:user/relea|
00000170  73 65 2d 6b 65 79 73 1a  23 32 3a 41 44 44 59 5f  |se-keys.#2:ADDY_|
00000180  68 34 68 65 74 79 47 6b  49 33 66 3a 4d 32 4d 56  |h4hetyGkI3f:M2MV|
00000190  34 4c 6d 77 54 6e 34 44  50 43 6f 6c 2a 05 65 6e  |4LmwTn4DPCol*.en|
000001a0  5f 55 53 32 0e 08 03 12  05 46 20 53 46 52 20 0a  |_US2.....F SFR .|
000001b0  28 d0 01 12 0f 0a 0d 62  6c 75 65 74 6f 6f 74 68  |(......bluetooth|
000001c0  74 65 73 74 12 09 0a 07  61 6e 64 72 6f 69 64 12  |test....android.|
000001d0  0a 0a 08 6c 6f 63 61 74  69 6f 6e 12 0a 0a 08 73  |...location....s|
000001e0  65 74 74 69 6e 67 73 12  24 0a 22 63 6f 6d 2e 73  |ettings.$."com.s|
000001f0  65 63 2e 61 6e 64 72 6f  69 64 2e 61 70 70 2e 73  |ec.android.app.s|
00000200  65 72 76 69 63 65 6d 6f  64 65 61 70 70 12 21 0a  |ervicemodeapp.!.|
00000210  1f 63 6f 6d 2e 73 65 63  2e 61 6e 64 72 6f 69 64  |.com.sec.android|
00000220  2e 61 70 70 2e 66 61 63  74 6f 72 79 74 65 73 74  |.app.factorytest|
00000230  12 0b 0a 09 50 72 65 63  6f 6e 66 69 67 12 1e 0a  |....Preconfig...|
00000240  1c 63 6f 6d 2e 73 61 6d  73 75 6e 67 2e 6d 6f 62  |.com.samsung.mob|
00000250  69 6c 65 54 72 61 63 6b  65 72 2e 75 69 12 25 0a  |ileTracker.ui.%.|
00000260  23 63 6f 6d 2e 73 65 63  2e 61 6e 64 72 6f 69 64  |#com.sec.android|
00000270  2e 61 70 70 2e 70 65 72  73 6f 6e 61 6c 69 7a 61  |.app.personaliza|
00000280  74 69 6f 6e 12 0d 0a 0b  73 65 74 74 69 6e 67 73  |tion....settings|
00000290  2e 6d 74 12 08 0a 06 62  61 63 6b 75 70 12 1e 0a  |.mt....backup...|
000002a0  1c 63 6f 6d 2e 73 65 63  2e 61 70 70 2e 52 69 6c  |.com.sec.app.Ril|
000002b0  45 72 72 6f 72 4e 6f 74  69 66 69 65 72 12 10 0a  |ErrorNotifier...|
000002c0  0e 63 6f 6d 2e 77 73 73  79 6e 63 6d 6c 64 6d 12  |.com.wssyncmldm.|
000002d0  1e 0a 1c 63 6f 6d 2e 73  65 63 2e 61 6e 64 72 6f  |...com.sec.andro|
000002e0  69 64 2e 61 70 70 2e 77  6c 61 6e 74 65 73 74 12  |id.app.wlantest.|
000002f0  1c 0a 1a 63 6f 6d 2e 62  72 6f 61 64 63 6f 6d 2e  |...com.broadcom.|
00000300  62 74 2e 61 70 70 2e 73  79 73 74 65 6d 12 1b 0a  |bt.app.system...|
00000310  19 70 72 6f 76 69 64 65  72 73 2e 73 75 62 73 63  |.providers.subsc|
00000320  72 69 62 65 64 66 65 65  64 73 12 0c 0a 0a 73 65  |ribedfeeds....se|
00000330  72 76 65 72 2e 76 70 6e  12 14 0a 12 70 72 6f 76  |rver.vpn....prov|
00000340  69 64 65 72 73 2e 73 65  63 75 72 69 74 79 12 13  |iders.security..|
00000350  0a 11 63 6f 6d 2e 73 65  63 2e 61 70 70 2e 4f 6d  |..com.sec.app.Om|
00000360  61 43 50 12 1d 0a 1b 63  6f 6d 2e 73 65 63 2e 61  |aCP....com.sec.a|
00000370  6e 64 72 6f 69 64 2e 61  70 70 2e 6c 63 64 74 65  |ndroid.app.lcdte|
00000380  73 74 12 1b 0a 19 63 6f  6d 2e 73 61 6d 73 75 6e  |st....com.samsun|
00000390  67 2e 49 6e 70 75 74 45  76 65 6e 74 41 70 70 12  |g.InputEventApp.|
000003a0  0f 0a 0d 52 69 6c 46 61  63 74 6f 72 79 41 70 70  |...RilFactoryApp|
000003b0  12 14 0a 12 70 72 6f 76  69 64 65 72 73 2e 73 65  |....providers.se|
000003c0  74 74 69 6e 67 73 12 22  0a 20 63 6f 6d 2e 73 65  |ttings.". com.se|
000003d0  63 2e 61 6e 64 72 6f 69  64 2e 61 70 70 2e 63 6f  |c.android.app.co|
000003e0  6e 74 72 6f 6c 70 61 6e  65 6c 12 0c 0a 0a 63 6f  |ntrolpanel....co|
000003f0  6d 2e 77 73 73 6e 70 73  12 0b 0a 09 61 70 70 73  |m.wssnps....apps|
00000400  2e 6d 61 70 73 22 e0 01  0a 69 0a 0e 08 f1 15 10  |.maps"...i......|
00000410  c4 fe 01 18 0a 20 d0 01  28 09 10 90 c5 f0 e8 db  |..... ..(.......|
00000420  25 22 0f 08 00 10 00 18  14 20 d0 01 28 01 30 a4  |%"....... ..(.0.|
00000430  c1 19 22 13 08 c9 9c 01  10 88 a1 10 18 14 20 d0  |.."........... .|
00000440  01 28 0b 30 bc af 19 22  14 08 de 82 03 10 ea cf  |.(.0..."........|
00000450  d2 06 18 0a 20 d0 01 28  08 30 86 e3 18 22 12 08  |.... ..(.0..."..|
00000460  f1 15 10 d7 bc 03 18 0a  20 d0 01 28 0b 30 8b aa  |........ ..(.0..|
00000470  03 28 02 12 6e 08 ca 81  ef e8 db 25 12 2c 0a 11  |.(..n......%.,..|
00000480  35 63 3a 33 33 3a 38 65  3a 30 61 3a 31 36 3a 30  |5c:33:8e:0a:16:0|
00000490  62 12 0c 4c 69 76 65 62  6f 78 2d 31 33 64 38 20  |b..Livebox-13d8 |
000004a0  b3 ff ff ff ff ff ff ff  ff 01 12 35 0a 11 36 36  |...........5..66|
000004b0  3a 39 35 3a 65 37 3a 35  38 3a 65 38 3a 61 35 12  |:95:e7:58:e8:a5.|
000004c0  15 44 61 6e 57 69 66 69  2d 41 64 68 6f 63 20 28  |.DanWifi-Adhoc (|
000004d0  61 64 68 6f 63 29 20 f2  ff ff ff ff ff ff ff ff  |adhoc) .........|
000004e0  01 18 02 9a 06 02 08 03                           |........|
The beginning of the POST request content is some obscure binary protocol but afterwards we find some “protocol buffers” encoding which, once decoded, can be read this way :
1: "1.0"
2: "android/samsung/GT-P1000/GT-P1000/GT-P1000:2.2/FROYO/BUJI4:user/release-keys"
3: "2:ADDY_h4hetyGkI3f:M2MV4LmwTn4DPCol" ('Platform key' which can be found in /data/data/com.google.android.location/files/gls.platform.key)
5 {
  12: "fr_FR"
}
6 {
  1: 3
  2: "F SFR"
  4: 10
  5: 208
}
2 {
  1: "bluetoothtest"
}
2 {
  1: "android"
}
2 {
  1: "location"
}
2 {
  1: "settings"
}
2 {
  1: "com.sec.android.app.servicemodeapp"
}
2 {
  1: "com.sec.android.app.factorytest"
}
2 {
  1: "Preconfig"
}
2 {
  1: "com.samsung.mobileTracker.ui"
}
2 {
  1: "com.sec.android.app.personalization"
}
2 {
  1: "settings.mt"
}
2 {
  1: "backup"
}
2 {
  1: "com.sec.app.RilErrorNotifier"
}
2 {
  1: "com.wssyncmldm"
}
2 {
  1: "com.sec.android.app.wlantest"
}
2 {
  1: "com.broadcom.bt.app.system"
}
2 {
  1: "providers.subscribedfeeds"
}
2 {
  1: "server.vpn"
}
2 {
  1: "providers.security"
}
2 {
  1: "com.sec.app.OmaCP"
}
2 {
  1: "com.sec.android.app.lcdtest"
}
2 {
  1: "com.samsung.InputEventApp"
}
2 {
  1: "RilFactoryApp"
}
2 {
  1: "providers.settings"
}
2 {
  1: "com.sec.android.app.controlpanel"
}
2 {
  1: "com.wssnps"
}
2 {
  1 {
    12: 0x7370616d2e737070
  }
}
4 {
  1 {
    1 {
      1: 2801
      2: 32580
      3: 10
      4: 208
      5: 9
    }
    2: 1295957893776
    4 {
      1: 0
      2: 0
      3: 20
      4: 208
      5: 1
      6: 417956
    }
    4 {
      1: 20041
      2: 266376
      3: 20
      4: 208
      5: 11
      6: 415676
    }
    4 {
      1: 49502
      2: 13936618
      3: 10
      4: 208
      5: 8
      6: 405894
    }
    4 {
      1: 2801
      2: 56919
      3: 10
      4: 208
      5: 11
      6: 54539
    }
    5: 2
  }
  2 {
    1: 1295957868746
    2 {
      1: "5c:33:8e:0a:16:0b"
      2: "Livebox-13d8"
      4: 18446744073709551539
    }
    2 {
      1: "66:95:e7:58:e8:a5"
      2: "DanWifi-Adhoc (adhoc)"
      4: 18446744073709551602
    }
    3: 2
  }
  99 {
    1: 3
  }
}
To summarize, here are the main information automatically sent to Google :
- Platform key (unique to the device and sent which every request to https://www.google.com/loc/m/api)
- Network operator
- List of applications used since last request
- Cellular location (LAC, CellID, …)
- WIFI location (SSID, Mac address ?)
All these data seem to be anonymized when sent to Google. But, with the “platform key”, Google can link the different requests made by one device.

I wonder :
- What’s the goal of the “platform key” ?
- I think I understand why cellular and WIFI locations are sent to Google (in order to update Google’s poor man GPS database) but why do we also find the list of used applications in this request ?

It would be interesting to see what kind of information is used for the “poor man GPS” function on other devices – testing iOS (iPhone/iPad) will be my next task.

Dan.

First privacy test : Android/Samsung Galaxy Tab (part 3)

January 20th, 2011

OK, let’s go to the (very) interesting part of the test : GEOLOCATION !

What would you expect from privacy on this ? When you activate use of wireless networks for geolocation (poor-man GPS), you have to agree some popup which says “Allow Google’s location service to collect anonymous location data. Collection will occur even when no applications are running”. When I read this, I thought that Google doesn’t collect identified location data. As you’ll see know, I was wrong…

First, what’s going on when you open “Google Maps” ?
A POST request is sent to a Google maps server – http://mobilemaps.clients.google.com/glm/mmap

Here’s the content of the request :
00000000  50 4f 53 54 20 68 74 74  70 3a 2f 2f 6d 6f 62 69  |POST http://mobi|
00000010  6c 65 6d 61 70 73 2e 63  6c 69 65 6e 74 73 2e 67  |lemaps.clients.g|
00000020  6f 6f 67 6c 65 2e 63 6f  6d 2f 67 6c 6d 2f 6d 6d  |oogle.com/glm/mm|
00000030  61 70 20 48 54 54 50 2f  31 2e 31 0a 43 6f 6e 74  |ap HTTP/1.1.Cont|
00000040  65 6e 74 2d 54 79 70 65  3a 20 61 70 70 6c 69 63  |ent-Type: applic|
00000050  61 74 69 6f 6e 2f 62 69  6e 61 72 79 0a 43 6f 6e  |ation/binary.Con|
00000060  74 65 6e 74 2d 4c 65 6e  67 74 68 3a 20 31 32 32  |tent-Length: 122|
00000070  35 0a 48 6f 73 74 3a 20  6d 6f 62 69 6c 65 6d 61  |5.Host: mobilema|
00000080  70 73 2e 63 6c 69 65 6e  74 73 2e 67 6f 6f 67 6c  |ps.clients.googl|
00000090  65 2e 63 6f 6d 0a 55 73  65 72 2d 41 67 65 6e 74  |e.com.User-Agent|
000000a0  3a 20 47 6f 6f 67 6c 65  4d 6f 62 69 6c 65 2f 31  |: GoogleMobile/1|
000000b0  2e 30 20 28 47 54 2d 50  31 30 30 30 20 46 52 4f  |.0 (GT-P1000 FRO|
000000c0  59 4f 29 3b 20 67 7a 69  70 0a 0a 00 17 51 49 90  |YO); gzip....QI.|
000000d0  30 3a 40 fb 75 00 02 66  72 00 21 61 6e 64 72 6f  |0:@.u..fr.!andro|
000000e0  69 64 3a 73 61 6d 73 75  6e 67 2d 47 54 5f 50 31  |id:samsung-GT_P1|
000000f0  30 30 30 2d 47 54 5f 50  31 30 30 30 00 08 34 2e  |000-GT_P1000..4.|
00000100  34 2e 30 2e 31 34 00 13  67 6d 6d 2d 61 6e 64 72  |4.0.14..gmm-andr|
00000110  6f 69 64 2d 73 61 6d 73  75 6e 67 3e 00 00 01 1b  |oid-samsung>....|
00000120  0a 03 34 31 32 10 01 18  d0 01 20 01 2a 03 47 4d  |..412..... .*.GM|
00000130  4d 92 01 06 53 59 53 54  45 4d 9a 01 10 35 39 66  |M...SYSTEM...59f|
00000140  35 63 30 30 62 30 33 35  61 64 61 63 64 a2 01 e0  |5c00b035adacd...|
00000150  01 44 51 41 41 41 4a 49  41 41 41 44 53 6c 53 55  |.DQAAAJIAAADSlSU|
00000160  39 76 47 57 45 73 51 55  33 5f 61 36 44 4d 6a 62  |9vGWEsQU3_a6DMjb|
00000170  32 7a 76 41 36 4d 62 79  4c 6b 61 4b 4f 4c 7a 76  |2zvA6MbyLkaKOLzv|
00000180  37 68 68 5a 66 79 5f 33  75 7a 38 47 79 4d 67 31  |7hhZfy_3uz8GyMg1|
00000190  4f 56 59 52 30 64 79 36  51 72 63 69 30 72 36 2d  |OVYR0dy6Qrci0r6-|
000001a0  7a 77 6b 47 51 55 42 70  6a 4f 33 37 50 59 36 4f  |zwkGQUBpjO37PY6O|
000001b0  38 6c 71 4f 39 66 64 32  76 34 39 52 6b 66 61 5a  |8lqO9fd2v49RkfaZ|
000001c0  68 70 78 72 53 67 6d 31  76 42 44 56 41 4d 4d 49  |hpxrSgm1vBDVAMMI|
000001d0  37 30 7a 76 69 70 6d 34  56 64 73 65 48 48 32 44  |70zvipm4VdseHH2D|
000001e0  38 50 65 61 41 5f 61 64  7a 70 78 78 6f 7a 62 70  |8PeaA_adzpxxozbp|
000001f0  4a 61 5a 37 63 33 43 6e  71 6a 6a 5a 55 6e 66 6e  |JaZ7c3CnqjjZUnfn|
00000200  6c 53 4e 35 5f 38 6b 71  58 41 44 41 7a 37 76 65  |lSN5_8kqXADAz7ve|
00000210  42 38 63 6c 42 57 5a 2d  62 63 78 55 74 31 58 54  |B8clBWZ-bcxUt1XT|
00000220  58 6c 39 41 57 67 78 58  32 66 72 73 67 70 73 6d  |Xl9AWgxX2frsgpsm|
00000230  39 b0 01 03 c8 01 01 da  01 01 38 07 02 ba 52 d1  |9.........8...R.|
00000240  00 4b 51 ff 02 ba c3 fb  00 4b 6d 32 00 0f 00 00  |.KQ......Km2....|
00000250  e6 80 00 00 c9 2a 01 01  29 00 00 00 c9 08 01 12  |.....*..).......|
00000260  c4 01 0a 46 1a 23 32 3a  56 55 72 59 31 59 6c 41  |...F.#2:VUrY1YlA|
00000270  70 5a 79 56 4e 63 50 46  3a 79 34 63 76 6e 4a 4a  |pZyVNcPF:y4cvnJJ|
00000280  46 35 65 6c 66 2d 34 50  57 32 0e 08 05 12 05 46  |F5elf-4PW2.....F|
00000290  20 53 46 52 20 0a 28 d0  01 3a 0f 12 0b 39 39 2e  | SFR .(..:...99.|
000002a0  34 33 2e 34 32 2e 31 30  18 02 12 04 18 07 30 0f  |43.42.10......0.|
000002b0  22 74 0a 22 0a 19 08 b5  8d 01 10 b2 d5 be 06 18  |"t."............|
000002c0  0a 20 d0 01 28 ff ff ff  ff ff ff ff ff ff 01 10  |. ..(...........|
000002d0  d6 cc b5 90 d3 25 12 3e  08 f1 cc b5 90 d3 25 12  |.....%.>......%.|
000002e0  35 0a 11 34 61 3a 32 66  3a 66 33 3a 31 34 3a 33  |5..4a:2f:f3:14:3|
000002f0  63 3a 65 33 12 15 44 61  6e 57 69 66 69 2d 41 64  |c:e3..DanWifi-Ad|
00000300  68 6f 63 20 28 61 64 68  6f 63 29 20 f7 ff ff ff  |hoc (adhoc) ....|
00000310  ff ff ff ff ff 01 1a 0e  0a 0a 0d ce a7 4b 1b 15  |.............K..|
00000320  f4 43 f2 02 40 01 0a 00  29 00 00 01 2d 32 0d 18  |.C..@...)...-2..|
00000330  96 00 0b 00 00 00 00 00  00 00 43 00 01 00 01 73  |..........C....s|
00000340  00 01 63 00 43 00 00 00  01 76 00 01 63 00 43 00  |..c.C....v..c.C.|
00000350  00 00 01 73 00 01 71 00  43 00 00 00 01 76 00 02  |...s..q.C....v..|
00000360  63 71 00 16 00 04 00 02  66 62 00 03 34 39 30 00  |cq......fb..490.|
00000370  16 00 00 00 02 6c 62 00  03 35 36 37 00 16 00 04  |.....lb..567....|
00000380  00 02 66 62 00 03 33 38  36 00 16 00 00 00 02 6c  |..fb..386......l|
00000390  62 00 03 34 32 36 00 43  00 01 00 01 73 00 01 63  |b..426.C....s..c|
000003a0  00 43 00 00 00 01 76 00  01 63 00 43 00 00 00 01  |.C....v..c.C....|
000003b0  73 00 01 71 00 43 00 00  00 01 76 00 02 63 71 00  |s..q.C....v..cq.|
000003c0  16 00 02 00 04 67 75 69  66 00 04 31 34 35 37 00  |.....guif..1457.|
000003d0  43 00 04 00 01 72 00 00  00 43 00 00 00 01 73 00  |C....r...C....s.|
000003e0  01 6e 00 43 00 00 00 01  76 00 03 63 71 6e 00 16  |.n.C....v..cqn..|
000003f0  00 03 00 02 66 62 00 03  33 34 30 00 16 00 00 00  |....fb..340.....|
00000400  02 6c 62 00 03 33 37 30  00 16 00 03 00 01 74 00  |.lb..370......t.|
00000410  04 31 32 34 38 00 16 00  00 00 02 54 4c 00 29 7c  |.1248......TL.)||
00000420  74 3d 6d 7c 74 77 3d 34  34 7c 74 66 3d 31 31 30  |t=m|tw=44|tf=110|
00000430  30 7c 74 6c 3d 31 32 34  38 7c 6e 3d 32 30 7c 62  |0|tl=1248|n=20|b|
00000440  3d 31 34 34 38 34 33 7c  00 16 00 00 00 02 66 62  |=144843|......fb|
00000450  00 04 31 30 35 32 00 16  00 00 00 02 6c 62 00 04  |..1052......lb..|
00000460  31 32 30 32 00 16 00 03  00 02 66 62 00 03 39 32  |1202......fb..92|
00000470  35 00 16 00 00 00 02 6c  62 00 04 31 30 32 39 00  |5......lb..1029.|
00000480  16 00 04 00 02 66 62 00  04 31 33 38 35 00 16 00  |.....fb..1385...|
00000490  00 00 02 6c 62 00 04 31  34 35 36 00 16 00 08 00  |...lb..1456.....|
000004a0  02 66 62 00 04 31 37 37  34 00 16 00 00 00 02 6c  |.fb..1774......l|
000004b0  62 00 04 31 39 34 38 00  16 00 02 00 03 74 66 6d  |b..1948......tfm|
000004c0  00 04 32 35 34 35 00 09  00 00 00 01 73 00 08 7c  |..2545......s..||
000004d0  74 3d 30 7c 76 3d 7c 00  16 00 00 00 02 61 70 00  |t=0|v=|......ap.|
000004e0  02 32 30 00 16 00 01 00  01 74 00 04 32 31 34 32  |.20......t..2142|
000004f0  00 16 00 00 00 02 54 4c  00 29 7c 74 3d 6d 7c 74  |......TL.)|t=m|t|
00000500  77 3d 32 37 7c 74 66 3d  31 37 39 32 7c 74 6c 3d  |w=27|tf=1792|tl=|
00000510  32 31 34 32 7c 6e 3d 32  30 7c 62 3d 31 31 33 30  |2142|n=20|b=1130|
00000520  35 33 7c 00 16 00 00 00  02 66 62 00 04 31 37 36  |53|......fb..176|
00000530  34 00 16 00 00 00 02 6c  62 00 04 32 31 31 35 00  |4......lb..2115.|
00000540  09 00 4a 00 01 69 00 09  7c 6e 3d 30 7c 65 3d 31  |..J..i..|n=0|e=1|
00000550  7c 00 16 00 05 00 02 66  62 00 03 34 39 30 00 16  ||......fb..490..|
00000560  00 00 00 02 6c 62 00 03  35 30 37 00 16 00 42 00  |....lb..507...B.|
00000570  01 63 00 06 7c 6d 3d 35  31 7c 00 16 00 0a 00 01  |.c..|m=51|......|
00000580  74 00 04 31 30 30 30 4d  00 00 00 08 0a 04 08 01  |t..1000M........|
00000590  10 00 10 01                                       |....|
This request is more complicated to decode as only part of it is encoded using ‘protocol buffers’, other parts seem to be a proprietary binary protocol. But we can easily find the following information :
Once decoded, the ‘protocol buffers’ part is :
1 {
3: “2:VUrY1YlApZyVNcPF:y4cvnJJF5elf-4PW” (“platform key” that can be found in the /data/data/com.google.android.apps.maps/files/DATA_Preferences file)
6 {
1: 5
2: “F SFR” (Telco)
4: 10 (MNC – Mobile Network Code)
5: 208 (MCC – Mobile Country Code)
}
7 {
2: “99.43.42.10″ (The tablet’s WIFI IP address)
3: 2
}
}
2 {
3: 7
6: 15
}
4 {
1 { // Cellular information
1 {
1: 18101 (LAC : Location Area Code)
2: 13609650 (CellID : GSM cell ID)
3: 10 (MNC)
4: 208 (MCC)
5: 18446744073709551615 (Signal strength)
}
2: 1293624895062
}
2 { // WIFI information
1: 1293624895089
2 {
1: “4a:2f:f3:14:3c:e3″ (WIFI BSSID/Hotspot MAC address)
2: “DanWifi-Adhoc (adhoc)” (WIFI network)
4: 18446744073709551607 (Signal strength)
}
}
3 {
1 {
1: 0×1b4ba7ce (“previous” latitude : 45.7942990)
2: 0×02f243f4 (“previous” longitude : 4.9431540)
}
8: 1
}
}

All that means that, despite what Google seems to say (when you ”Allow Google’s location service to collect anonymous location data. Collection will occur even when no applications are running”), identified location data are sent to Google servers when you use Google maps – we can find in the same request to Google servers personal IDs and location data (network cell, WIFI hotspots, latitude/longitude,…). I understand that cellular and WIFI information have to be sent to Google servers to “convert” them in latitude/longitude (the famous “poor man GPS”) but personal IDs are absolutely not needed for this “conversion”…  And, before you ask, you have to know I’ve never launch nor activate ‘Google Latitude’ (which is used to share your location with friends) with this account.

The above Google assertion (about anonymous location data) might concern an other type of request which is sent in background to the https://www.google.com/loc/m/api (I’ll decode this request in my next post) but, to me, this assertion is very confusing and let us think Google never collect identified location data.

Dan.

First privacy test : Android/Samsung Galaxy Tab (part 2)

January 18th, 2011

So, let’s see what’s leaving my Galaxy Tab when I start it…
When the tablet starts and/or after the Google account configuration, a POST request is sent to  https://android.clients.google.com/checkin
The POST request content (sent to Google servers) is encoded in “protocol buffers” and gzip compressed (before being SSL encrypted).
After uncompressing (gzip -d) and decoding (using the ‘protoc‘ tool), we get the following content – I’ve added some XXX to protect my private information :-)  :
1: "352XXXX4131XXXX" (IMEI : my tablet 'phone ID')
2: 352XXXX992470XXXX65 (Android ID : unique Android terminal ID)
3: "KfblIp3D9a3TzIxvjI4Ncw==" (value of 'digest' in table 'main' of
    /data/databases/com.google.android.gsf/services.db)
4 {
  1 {
    1: "samsung/GT-P1000/GT-P1000/GT-P1000:2.2/FROYO/BUJI4:user/release-keys"
    2: "GT-P1000" (device model)
    3: "samsung" (device manufacturer)
    4: "unknown"
    5: "unknown"
    6: "android-hms-vf-fr"
    7: 1285664195 (date : Tue, 28 Sep 2010 08:56:35 GMT)
    8: 8
    9: "GT-P1000" (device model)
  }
  2: 1293573920130 (seems to be a date followed by ‘130’ : Tue, 28 Dec 2010 22:05:20 GMT)
  6: "20810" (MNC that identifies the telco - here SFR)
  7: "20810" (MNC that identifies the telco - SFR)
  8: "mobile-notroaming"
}
6: "fr_FR"
7: 6482298392203156173 (in Hexa : 59F5C00C6DC0F - value of 'logging_id2' of table 'partner' in
    /data/databases/com.google.android.gsf/googlesettings.db)
9: "BC4760XXXX2B" (WIFI adapter MAC address)
11: "[dv0XXXX@gmail.com]" (the Google account I've configured on the tablet)
11: "DQAAAHwAAADfx4A26--_sWF8..." (SID linked to the Google account)
12: "Europe/Paris" (Timezone)
13: 0x2fXXXX7XXXXbc3b1 (“securityToken”)
14: 2
15: "1Z5kM2XXXXX4hPRXXXX/Roh/A8E="

With this request, Google is able to link different private information :

  • The google account or accounts you have (it’s not shown here but I’ve made the test and if you have 2 different Google accounts they both appear in this request – that means that if, for example, you have a private Gmail account and a professional Gapps account, Google will know it’s the same person who owns both accounts)
  • Different unique ids of your device : IMEI number, Wifi MAC address, AndroidID
  • Your telco
  • Your exact device model
  • Not so much interesting information in the response (also encoded in ‘protocol buffers’) :

    1: 1
    2 {
      1: "android.server.checkin.FOTA_CANCEL"
    }
    3: 1293574461564
    6: 0
    7: 0x30ebe5f95a355989
    8: 0x2fa80f714b7bc3b1 (we find again the “securityToken”)

    We can also trace an other HTTPS request going to  https://android.clients.google.com/auth

    The POST request content is encoded as a standard HTML form and we can read the following elements :

    accountType=HOSTED_OR_GOOGLE
    flags=49
    Email=dv0XXXX%40gmail.com
    EncryptedPasswd=AFcb4KTDyC2k8qONp-xnxy-CcS96bldNQhA1s2kBzlLT0g-qSCj0B6....
    service=gaia
    source=android
    androidId=30XXXXf95XXXX989
    securityToken=2fa80f714b7bc3b1
    RefreshServices=1

    And the answer contains “tokens” that are used by the Google services :

    SID=DQAAAJEAAAAJPPPNGD-kkT...
    LSID=DQAAAJMAAADSlSU9vGWEsQU...
    Auth=DQAAAJIAAADSlSU9vGWEsQU3...

    What should I say to conclude this second part ?
    Well, it may not surprise you but Google gathers a lot of private information concerning you and your mobile device(s). That’s interesting because some weeks ago there was some buzz around apps accessing private information on smartphones, like this post from Lookout or the study based on TaintDroid but no one seems to worry about already-installed Google apps accessing and sending out private information. To me, this is even more serious because Google is able to link a lot of different private information on us… By the way, is this coherent with Google’s privacy policy ? Maybe, maybe not… if you have any idea on that, please feel free to comment this post.
    Next part of the study will focus on geolocation…

    Dan.

    First privacy test : Android/Samsung Galaxy Tab (part 1)

    January 18th, 2011

    So, for the first privacy test, I’ve used my brand new Samsung Galaxy Tab running Froyo (Android 2.2).

    The goal of this test is to check what type of information leave my tablet when I use it (with no additional application). As a number of connections are SSL encrypted, I had to build an architecture which enables to me to decrypt these communications. For this first post, I’ll detail this architecture.

    I used an old Asus eeePC running Ubuntu 10.10 and configure it to be a “Wifi hotspot” for my Galaxy Tab (ok, I’ve only configured an adhoc connection). The role of the eeePC is to capture all traffic, including HTTPS to decrypt its content and store it on the local hard disk. Thus, it will be possible to analyze information exchange between the tablet and outside services (including SSL traffic).

    I used the following software component :

    • Squid proxy version 3.2.0.4 (beta version – the 3.2 version is a must car previous ones don’t include the DynamicSslCert function) configured with transparent proxy mode, SSL decrypting option (sslBump) and dynamic SSL certificate generation (DynamicSslCert)
    • c-icap version 0.1.3 (which is an ICAP server) connected to the Squid proxy. I’ve developed a new c-icap module (named srv_dump) which just dump all traffic to the local hard disk (including POST requests content)
    As explained here  http://wiki.squid-cache.org/Features/DynamicSslCert Squid doesn’t support dynamic SSL certificate generation and transparent proxy (which is required because even if Android support proxy configuration, it seems to be mainly used by the web browser and we still see direct HTTPS connections even with a configured proxy). To solve this issue, I had to manually generate the SSL certificates for the different HTTPS servers concerned by these direct connections and configure the eeePC iptables nat table to redirect connections to specific squid ports (1 squid port = 1 ‘manual’ SSL certificate).
    I’ve configured the Galaxy Tab this way :
    • Data network mode deactivated (only Wifi)
    • Wifi configured to be connected in Adhoc mode with the eeePC (I had to root and modify the wpa_supplicant file to support adhoc mode)
    • Configure the Wifi proxy with the IP adress of the eeePC and the main port of Squid
    • Add the self-signed certificate used to sign fake SSL certificates as a root certificate, following the procedure detailed here  http://wiki.cacert.org/ImportRootCert#Android_Phones (you need to be root)
    Now, everything is ready for the first traffic capture and analysis…
    Stay tuned to have the first results – you won’t have to wait a long time, first info expected to be online by tonight or tomorrow…
    Dan.

    Bonjour

    January 14th, 2011

    I’ve decided to create this blog to address specific privacy issues when using mobile devices, like smartphones and tablets. This decision came after some research I’ve done that showed me the amount of private information that are sent from these devices. My personal experience is mainly in the computer security field.

    With this blog, I’d like to explain which information are sent by different mobile OS and applications, so that users can make an informed decision. I  hope this will help some of you to better understand what’s going on with our mobile devices.

    See you soon on this blog,

    Daniel.