Apple lagrar GPS-data samt BSSID (accesspunkter) på ipad/iphone med GPS-mottagare
Lets face it. Data är idag en handelsvara och i vårt mobila samhälle innebär geolokaliseringsdata guld inte bara för marknadsförare utan även för allehanda marknadsintressen eftersom man ur geolokaliseringsdata kan dra slutsatser om beteenden etc.
De flesta webbläsare stöder exempelvis Googles API för att geolokalisera dig med hjälp av omgärdande BSSID (hårdvaruadresser för trådlösa accesspunkter). Googlebilen som åkte runt och fotade byggnader, gator osv samlade även in BSSID och korresponderande GPS-data (longitud och latitud).
Webbläsartillverkarna vill ofta få det till att man nu "implementerat skydd" mot att ofrivilligt bli geolokaliserad när man inför denna funktionalitet i webbläsarna. I själva verket har man infört stöd för geolokaliseringsmetoden som behöver access till bl a ditt trådlösa nätverkskort.
Jag själv har inget emot att bli tillfrågad om jag vill dela med mig av min geografiska position för att t ex få riktade annonser, men det är viktigt att konsumenten känner till vad för slags data som faktiskt samlas in.
I forensikerkretsar (även podcasts med inriktningen forensics) har pratat om dessa databaser ett tag (drygt ett år) och det är egentligen inga konstiga data det handlar om. När GPS-mottagaren är påslagen, har mottagning och tar emot data så loggas detta i en SQLitedatabas (consolidated.db) innehållande flertalet tabeller vilka innehåller GPS-data. De GPS-data som lagras i databasen lagras med en tidsstämpel i float-format (antal sekunder sedan 1 januari 2001) som inte riktigt överensstämmer med när dessa lästes från GPS-mottagaren. Verkar vara någon form av cache som efter en tid "flushas" till consolidated.db.
sqlite> .TABLES Cell CellLocationLocalBoxes_rowid CellLocation CellLocationLocalCounts CellLocationBoxes CompassCalibration CellLocationBoxes_node Fences CellLocationBoxes_parent Location CellLocationBoxes_rowid LocationHarvest CellLocationCounts LocationHarvestCounts CellLocationHarvest TableInfo CellLocationHarvestCounts Wifi CellLocationLocal WifiLocation CellLocationLocalBoxes WifiLocationCounts CellLocationLocalBoxes_node WifiLocationHarvest CellLocationLocalBoxes_parent WifiLocationHarvestCounts
De tabellnamn som är intressanta i sammanhanget är CellLocation, WifiLocation men också de *Harvest och *HarvestCounts tabeller som finns i databasen.
*Harvest-tabellerna skulle kunna vara en indikation på att viss data skickas till Apple. Det skulle kunna förklara varför CellLocationHarvest* tabellerna är tomma och innehåller räknevärdet 0. Denna information snor i dagsläget inte Apple från databasen (detta kan dock komma att ändras, man har väl inte skapat
dessa tabeller utan ett syfte?).
1 2 3 4 5 6 |
sqlite> SELECT * FROM CellLocationHarvest; sqlite> SELECT * FROM CellLocationHarvestCounts; 0 sqlite> SELECT * FROM WifiLocationHarvest; sqlite> SELECT * FROM WifiLocationHarvestCounts; 0 |
Lite grävande i SQLitetabellernas uppbyggnad:
1 2 3 4 5 |
sqlite> .schema CellLocation CREATE TABLE CellLocation (MCC INTEGER, MNC INTEGER, LAC INTEGER, CI INTEGER, Timestamp FLOAT, Latitude FLOAT, Longitude FLOAT, HorizontalAccuracy FLOAT, Altitude FLOAT, VerticalAccuracy FLOAT, Speed FLOAT, Course FLOAT, Confidence INTEGER, PRIMARY KEY (MCC, MNC, LAC, CI)); CREATE TRIGGER CellLocationDecrementRowCount AFTER DELETE ON CellLocation FOR EACH ROW BEGIN UPDATE CellLocationCounts SET Count=Count-1 WHERE rowid=1; END; CREATE TRIGGER CellLocationIncrementRowCount AFTER INSERT ON CellLocation FOR EACH ROW BEGIN UPDATE CellLocationCounts SET Count=Count+1 WHERE rowid=1; END; |
1 2 3 4 |
sqlite> .schema WifiLocation CREATE TABLE WifiLocation (MAC TEXT, Timestamp FLOAT, Latitude FLOAT, Longitude FLOAT, HorizontalAccuracy FLOAT, Altitude FLOAT, VerticalAccuracy FLOAT, Speed FLOAT, Course FLOAT, Confidence INTEGER, PRIMARY KEY (MAC)); CREATE TRIGGER WifiLocationDecrementRowCount AFTER DELETE ON WifiLocation FOR EACH ROW BEGIN UPDATE WifiLocationCounts SET Count=Count-1 WHERE rowid=1; END; CREATE TRIGGER WifiLocationIncrementRowCount AFTER INSERT ON WifiLocation FOR EACH ROW BEGIN UPDATE WifiLocationCounts SET Count=Count+1 WHERE rowid=1; END; |
Slutligen en pythonmodul för att skriva ut data. Kan användas direkt på devicen om den är jailbreakad och har python installerad eller på extraherad databasfil som t ex kommer från en iphone-backup.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
#!/usr/bin/env python # -*- coding: utf-8 -*- # get_location.py - Part of Jonathan James's forensic toolkit for iPhone. http://jonathanj.com - This e-mail address is being protected from spambots. You need JavaScript enabled to view it # Standalone usage: get_location.py [file] [limit] or get_location.py to set the standard values. import time import sys from sqlite3 import dbapi2 as sql class location_info: location_db = "" def __init__(self,dbfile): self.location_db = dbfile def list_gps(self,limit): rows = 0 self.dbconnect() self.c.execute("select Timestamp, Latitude, Longitude from CellLocation limit %s;" % (limit)) print "Row:\tTimestamp:\t\t\tLatitude:\tLongitude:" for row in self.c: if len(row)==3: rows += 1 floattime = float(row[0]) ctime = time.ctime(floattime + 978328800) print "%s\t%s\t%s\t%s" % (rows,ctime,row[1],row[2]) def list_gpswlan(self,limit): rows = 0 self.dbconnect() self.c.execute("select MAC, Timestamp, Latitude, Longitude from WifiLocation limit %s;" % (limit)) print "Row:\tBSSID:\t\tTimestamp:\t\t\tLatitude:\tLongitude:" for row in self.c: if len(row)==4: rows += 1 floattime = float(row[1]) ctime = time.ctime(floattime + 978328800) print "%s\t%s\t%s\t%s\t%s" % (rows, row[0], ctime, row[2], row[3]) def dbconnect(self): self.db = sql.connect(self.location_db) self.c = self.db.cursor() if __name__ == '__main__': # Build our location_info object if (len(sys.argv) > 1): f=location_info(sys.argv[1]) else: f=location_info('/var/root/Library/Caches/locationd/consolidated.db') if (len(sys.argv) > 2): limit = int(sys.argv[2]) else: limit = 100 #List data from CellLocation table f.list_gps(limit) #List data from WifiLocation table f.list_gpswlan(limit) |


