Quantcast
Channel: mac4n6.com
Viewing all 113 articles
Browse latest View live

Knowledge is Power II – A Day in the Life of My iPhone using knowledgeC.db

$
0
0

iOS devices may potentially have more personal information and user patterns than their macOS counterparts. People tend to go about their daily lives with their mobile devices rarely being separated from them. In this post I will present to you a day in the life of my iPhoneX – Monday September 10, 2018.

My previous post on the knowledgeC.db database focused more on macOS devices versus iOS, with a few scattered iOS examples. This post will focus entirely on iOS analysis of this database. This database is located on physical dumps of devices in /private/var/mobile/Library/CoreDuet/Knowledge/knowledgeC.db. It is not captured by an iTunes backup.

The first query I would like to do execute for iOS analysis is a simple SQL query to show which “Stream Names” I have. These can provide an idea of what kind of data is potentially available.

SELECT
DISTINCT ZOBJECT.ZSTREAMNAME
FROM ZOBJECT
ORDER BY ZSTREAMNAME

This query outputted the following streams. Some of these I’ve already covered in my previous post. Reading through some of these it is likely you can guess what some of them may contain.

  • /app/activity

  • /app/inFocus

  • /app/install

  • /app/intents

  • /app/locationActivity

  • /audio/inputRoute

  • /audio/outputRoute

  • /bluetooth/isConnected

  • /carplay/isConnected

  • /device/batteryPercentage

  • /device/isLocked

  • /device/isPluggedIn

  • /display/isBacklit

  • /display/orientation

  • /inferred/motion

  • /media/nowPlaying

  • /portrait/entity

  • /portrait/topic

  • /safari/history

  • /search/feedback

  • /siri/ui

  • /user/isFirstBacklightOnAfterWakeup

  • /watch/nearby

  • /widgets/viewed

Application Usage

Let’s start with what apps did I use on that day. I may have hundreds of apps on my phone but in reality, I use only a fraction. I used the following query from my previous post to capture all the “/app/inFocus” entries. I’ve screenshotted the majority of my day to give you a good idea of what this data looks like. My apologies in advance for the lengthiness of this post – but hey, everyone loves pictures! This is just one day’s worth of data, imagine having the same data for up to four weeks! I will never complain about too much data, queries and analysis can help you digest this information.

SELECT
datetime(ZOBJECT.ZCREATIONDATE+978307200,'UNIXEPOCH', 'LOCALTIME') as "ENTRY CREATION", 
CASE ZOBJECT.ZSTARTDAYOFWEEK 
    WHEN "1" THEN "Sunday"
    WHEN "2" THEN "Monday"
    WHEN "3" THEN "Tuesday"
    WHEN "4" THEN "Wednesday"
    WHEN "5" THEN "Thursday"
    WHEN "6" THEN "Friday"
    WHEN "7" THEN "Saturday"
END "DAY OF WEEK",
ZOBJECT.ZSECONDSFROMGMT/3600 AS "GMT OFFSET",
datetime(ZOBJECT.ZSTARTDATE+978307200,'UNIXEPOCH', 'LOCALTIME') as "START", 
datetime(ZOBJECT.ZENDDATE+978307200,'UNIXEPOCH', 'LOCALTIME') as "END", 
(ZOBJECT.ZENDDATE-ZOBJECT.ZSTARTDATE) as "USAGE IN SECONDS",
ZOBJECT.ZSTREAMNAME, 
ZOBJECT.ZVALUESTRING
FROM ZOBJECT
WHERE ZSTREAMNAME IS "/app/inFocus" 
ORDER BY "START"

I started my “day” for this post on 09/09/2018 at 22:04:58, you will notice that all timestamps are recorded in local time (Eastern) as per my SQL query. Note the column ‘GMT OFFSET’ where it shows what time zone this data was recorded in. The following queries may not show some of these columns due to screenshot readability.

app_focus1.png

Around 22:04 on 09/09/2018 I checked my email (com.apple.mobilemail), Messages (com.apple.MobileSMS), and Twitter (com.atebits.Tweetie2). In fact, I spend a TON of time checking Twitter, I’m always on Twitter.

Next at 22:38:34 I check my Orangetheory app (com.shufflecloud.orangetheoryfitness) to see what time I need to head to the gym in the morning. I opened the app a couple of times trying to convince myself to keep my reservation. I actually cancel my class, I’m too sore from the previous day to go - don’t you judge me! If I’m not going to the gym in the morning – I can sleep in! I access the Clock app (com.apple.mobiletimer) to change my morning alarm.

Around 04:25 on Monday I wake up and can’t sleep fall back asleep so I put in my fancy shmancy Bose Sleepbuds and use the app (com.bose.corporation.bosesleep) to provide me some dreamy white noise. I proceed to wake up a couple times to adjust the white noise type and to change my alarm again (definitely sleeping in, I require lots of sleep to function as a human.) I finally wake at 7:55am to turn off the Sleepbuds and to check Messages and Slack (com.tinyspeck.chatlyio).

At 07:58 in the morning, I turn my alarm off (was set to go off at 08:00) and proceed to check email, Twitter, Weather, and Messages.

While getting ready for work I check Messages, send a Bitmoji using the Bitmoji keyboard (com.bitstrips.imoji.BitmojiKeyboard) in Messages and again check weather (Hurricane Florence is making her way in!)

At 09:49 at work, my coworker asks how my SANS Fantasy Football (com.espn.fantasyFootball) team did. I check my scores - I got destroyed by Alissa’s team. This is going to be a rough season.

Check email again and my calendar.

At 10:42, a quick check of Facebook (com.facebook.Facebook) and check a setting in the iOS Settings (com.apple.Preferences) application.

I got a phone call (com.apple.InCallService) at 11:25 but was unable to pick up as I was eating lunch. I called them back at 11:56 using the Phone app (com.apple.mobilephone), it was a 10 minute call that ended at 12:06. Notice the artifacts of app usage when you leave an app and come back to it 40 minutes later. I was using the Phone app for all of 2 seconds before switching to Facebook to gaze at photos of Stacy’s super cute puppy, Piper.

In the afternoon, I check some Slack, screw around with Settings, email, and of course check Twitter.

Finally commuting home, I need some Apple Music (com.apple.Music) to listen too! I have my phone hooked up to my car with CarPlay and I’m getting directions using Apple Maps (something about that makes the com.ubercab.UberClient.intentsextension go nuts!). I also use Siri in my car to create a Note (com.apple.mobilenotes.IntentsExtension) just after 18:00. (Hands free of course!)

app_focus6.png

I get home and proceed to listen to Apple Music, check Slack, email, Twitter, etc. I also check to see if I have an Orangetheory class scheduled – sure do! I set my alarm for zero dark thirty, I’m not canceling this one. I also edit a Note and check my calendar before I settle in to write this post.

The ‘app/inFocus’ gives a good rundown of what apps the user uses and when, however it is missing quite a bit of detail that can provide an investigator more context to what exactly the user was doing during these events.

Application Activity

The streams for ‘app/activity’ provide more details on what exactly the app is doing. I used the following query for this data. NOTE: For the sake of getting a readable screenshot, I’ve commented out a few columns (--) in my query below. When running you will just want to uncomment those lines or customize as necessary.

SELECT
datetime(ZOBJECT.ZCREATIONDATE+978307200,'UNIXEPOCH', 'LOCALTIME') as "ENTRY CREATION", 
--CASE ZOBJECT.ZSTARTDAYOFWEEK 
--  WHEN "1" THEN "Sunday"
--  WHEN "2" THEN "Monday"
--  WHEN "3" THEN "Tuesday"
--  WHEN "4" THEN "Wednesday"
--  WHEN "5" THEN "Thursday"
--  WHEN "6" THEN "Friday"
--  WHEN "7" THEN "Saturday"
--END "DAY OF WEEK",
--datetime(ZOBJECT.ZSTARTDATE+978307200,'UNIXEPOCH', 'LOCALTIME') as "START", 
--datetime(ZOBJECT.ZENDDATE+978307200,'UNIXEPOCH', 'LOCALTIME') as "END", 
--ZOBJECT.ZSTREAMNAME, 
ZOBJECT.ZVALUESTRING,
ZSTRUCTUREDMETADATA.Z_DKAPPLICATIONACTIVITYMETADATAKEY__ACTIVITYTYPE AS "ACTIVITY TYPE",  
ZSTRUCTUREDMETADATA.Z_DKAPPLICATIONACTIVITYMETADATAKEY__TITLE as "TITLE", 
datetime(ZSTRUCTUREDMETADATA.Z_DKAPPLICATIONACTIVITYMETADATAKEY__EXPIRATIONDATE+978307200,'UNIXEPOCH', 'LOCALTIME') as "EXPIRATION DATE",
ZSTRUCTUREDMETADATA.Z_DKAPPLICATIONACTIVITYMETADATAKEY__ITEMRELATEDCONTENTURL as "CONTENT URL",
datetime(ZSTRUCTUREDMETADATA.ZCOM_APPLE_CALENDARUIKIT_USERACTIVITY_DATE+978307200,'UNIXEPOCH', 'LOCALTIME')  as "CALENDAR DATE",
datetime(ZSTRUCTUREDMETADATA.ZCOM_APPLE_CALENDARUIKIT_USERACTIVITY_ENDDATE+978307200,'UNIXEPOCH', 'LOCALTIME')  as "CALENDAR END DATE"
FROM ZOBJECT
left join ZSTRUCTUREDMETADATA on ZOBJECT.ZSTRUCTUREDMETADATA = ZSTRUCTUREDMETADATA.Z_PK
left join ZSOURCE on ZOBJECT.ZSOURCE = ZSOURCE.Z_PK
WHERE ZSTREAMNAME is "/app/activity" 
ORDER BY "ENTRY CREATION"
app_activity1.png

Sunday evening, I checked my email around 22:04:58. What emails was I actually reading? My Inbox - reading a message that I had just been added from the waitlist (hence the canceling of it later! (#DFIRFIT? More like #DFIRSore!)

app_activity2.png

Next, I changed my alarm to sleep in at 05:52 and to turn it off at 07:58. The activity type of com.apple.clock.alarm is a good way to tell what “screen” a certain app is using. For instance, I was not viewing the “World Clock”, “Stopwatch”, or “Timer” screens.

app_activity3.png

Around 17:54pm, I start to drive home. I used Maps (com.apple.Maps) through CarPlay to get directions. This is something that is nearly missed if you only look at /app/inFocus entries. The blurred section is my home address which is assigned to “Home” when I ask Siri to take me there.

app_activity4.png

When I got home at 18:42, I started browsing Twitter. Some apps yield more detailed information than others (other examples in my data include RedFin, Zappos, and Yelp). Each time I clicked though to a particular tweet (versus just aimlessly scrolling), it would record it as an activity type of “com.atebits.Tweetie2.spotlight”, complete with full URL to the tweet.

Piper is a good #DFIRpup.

app_activity5.png

Finally, I do a few more tasks before sitting down to write this. Set an alarm to get up, check a few days in my calendar and make sure I have the Apple Event in there – I need a new Apple Watch!

Application Intents

You can never have enough context when doing data analysis. We can use the “app/intents” entries for even more detail. I provided the query I used below with some items commented out for screenshot purposes.

SELECT
datetime(ZOBJECT.ZCREATIONDATE+978307200,'UNIXEPOCH', 'LOCALTIME') as "ENTRY CREATION", 
--CASE ZOBJECT.ZSTARTDAYOFWEEK 
--  WHEN "1" THEN "Sunday"
--  WHEN "2" THEN "Monday"
--  WHEN "3" THEN "Tuesday"
--  WHEN "4" THEN "Wednesday"
--  WHEN "5" THEN "Thursday"
--  WHEN "6" THEN "Friday"
--  WHEN "7" THEN "Saturday"
--END "DAY OF WEEK",
datetime(ZOBJECT.ZSTARTDATE+978307200,'UNIXEPOCH', 'LOCALTIME') as "START", 
datetime(ZOBJECT.ZENDDATE+978307200,'UNIXEPOCH', 'LOCALTIME') as "END", 
--ZOBJECT.ZSTREAMNAME, 
ZOBJECT.ZVALUESTRING,
ZSTRUCTUREDMETADATA.Z_DKINTENTMETADATAKEY__INTENTCLASS as "INTENT CLASS", 
ZSTRUCTUREDMETADATA.Z_DKINTENTMETADATAKEY__INTENTVERB as "INTENT VERB", 
ZSTRUCTUREDMETADATA.Z_DKINTENTMETADATAKEY__SERIALIZEDINTERACTION as "SERIALIZED INTERACTION",
ZSOURCE.ZBUNDLEID,
ZSOURCE.ZGROUPID,
ZSOURCE.ZITEMID,
ZSOURCE.ZSOURCEID
FROM ZOBJECT
left join ZSTRUCTUREDMETADATA on ZOBJECT.ZSTRUCTUREDMETADATA = ZSTRUCTUREDMETADATA.Z_PK
left join ZSOURCE on ZOBJECT.ZSOURCE = ZSOURCE.Z_PK
WHERE ZSTREAMNAME is "/app/intents" 
ORDER BY "START"
app_intents1.png

Far more detail is provided in the “app/intents” entries. Messages sent, the “Serialized Interaction” provides message details (contact/message info) that can be correlated with the sms.db. If the Alarms were enabled or disabled, the “Serialized Interaction” BLOB provides the specific alarm GUID info if that is necessary to your investigation. Always look at BLOB data – you never know what you can find. This particular BLOB is an NSKeyedArchiver plist embedded into another NSKeyedArchiver plist – plist inception!

Note the two different Bundle IDs for the Sent Messages:

  • com.apple.MobileSMS – This one is used when I was actually interacting with the Messages application and typing my response.

  • com.apple.assistant_service – This one is used when Siri is “helping”. In my case I was using CarPlay to dictate my messages while on my commute. Siri (w/o CarPlay) looks similar.

Recall that I received a call (but was eating lunch) at 11:25. I called them back at 11:56. The intents are showing a “StartAudioCall” intent when I received the call (but didn’t take it) and when I ended the call at 12:06pm. Without testing, this can be misleading. Always test before making assumptions.

When driving home at 17:59, I created a Note and attempted to append text to that note. I can see the original note creation as well as attempted “Appends”. Sadly, Siri couldn’t understand what I wanted to do when I wanted to append the note, so she just read the title of all bajillion notes that I have (not super helpful Siri!). Some of the text in the “Serialized Interaction” show what Siri interpreted me saying.

When driving home, I asked Siri to take me “Home” and she populated the directions to my place in the Maps application. While you see an “EndNavigation” intent you may not necessarily see a “StartNavigation” intent. It depends on how you initiate the driving directions.

When I got home I also wanted listen to some NPR news through Apple Music app. This shows a Search and various “Selects”. Looking into these BLOBS you can see what I searched for and what I selected to listen to. (More on this in a bit.)

Finally, I append what I wanted to in the Note, manually this time (no thanks to Siri). I also update a calendar entry.

Device Status

The /device/* streams track the device’s status such as whether the device is plugged in, locked, and what the battery level is. This data is tracked in other databases as well (See my iOS of Sauron presentation), but I’ll never complain about data redundancy.

SELECT
datetime(ZOBJECT.ZCREATIONDATE+978307200,'UNIXEPOCH', 'LOCALTIME') as "ENTRY CREATION", 
CASE ZOBJECT.ZSTARTDAYOFWEEK 
    WHEN "1" THEN "Sunday"
    WHEN "2" THEN "Monday"
    WHEN "3" THEN "Tuesday"
    WHEN "4" THEN "Wednesday"
    WHEN "5" THEN "Thursday"
    WHEN "6" THEN "Friday"
    WHEN "7" THEN "Saturday"
END "DAY OF WEEK",
datetime(ZOBJECT.ZSTARTDATE+978307200,'UNIXEPOCH', 'LOCALTIME') as "START", 
datetime(ZOBJECT.ZENDDATE+978307200,'UNIXEPOCH', 'LOCALTIME') as "END", 
(ZOBJECT.ZENDDATE-ZOBJECT.ZSTARTDATE) as "USAGE IN SECONDS",
ZOBJECT.ZSTREAMNAME, 
ZOBJECT.ZVALUEDOUBLE
FROM ZOBJECT
left join ZSTRUCTUREDMETADATA on ZOBJECT.ZSTRUCTUREDMETADATA = ZSTRUCTUREDMETADATA.Z_PK
left join ZSOURCE on ZOBJECT.ZSOURCE = ZSOURCE.Z_PK
WHERE ZSTREAMNAME like "/device/%"  
ORDER BY "START"
device_status1.png

The example shows when the device is locked (0), unlocked (1), unplugged (0), and plugged in (1) in the ZVALUEDOUBLE column. You can also see the battery charging and discharging in line with the plugged-in status.

device_status2.png

Extracting just the /device/isPluggedIn events I can distill when this device was plugged into something. Sunday evening, I plugged the device in before going to sleep and unplugged it at 07:55 in the morning. At 08:42 in the morning, I plugged it into my car for my morning commute and unplugged it at 9:15 when I got to work.

In the afternoon I plugged it into my car again at 15:34-16:06 to drive to a different site and then finally plugged it in from 17:47-18:15 for my commute home.

This output doesn’t provide any detail into what the device was plugged into, but other streams can provide some hints.

Audio & Media

This database keeps track of what is playing (depending on the app) and how. The SQL query below is a good “all in one” query to use for all the audio and media events. The query examples I provide in screenshots have been edited down to be viewable.

SELECT
datetime(ZOBJECT.ZCREATIONDATE+978307200,'UNIXEPOCH', 'LOCALTIME') as "ENTRY CREATION", 
CASE ZOBJECT.ZSTARTDAYOFWEEK 
    WHEN "1" THEN "Sunday"
    WHEN "2" THEN "Monday"
    WHEN "3" THEN "Tuesday"
    WHEN "4" THEN "Wednesday"
    WHEN "5" THEN "Thursday"
    WHEN "6" THEN "Friday"
    WHEN "7" THEN "Saturday"
END "DAY OF WEEK",
datetime(ZOBJECT.ZSTARTDATE+978307200,'UNIXEPOCH', 'LOCALTIME') as "START", 
datetime(ZOBJECT.ZENDDATE+978307200,'UNIXEPOCH', 'LOCALTIME') as "END", 
(ZOBJECT.ZENDDATE-ZOBJECT.ZSTARTDATE) as "USAGE IN SECONDS",
ZOBJECT.ZSTREAMNAME, 
ZOBJECT.ZVALUESTRING,
ZSTRUCTUREDMETADATA.Z_DKAUDIOMETADATAKEY__IDENTIFIER as "AUDIO IDENTIFIER",
ZSTRUCTUREDMETADATA.Z_DKAUDIOMETADATAKEY__PORTNAME as "AUDIO PORT NAME",
ZSTRUCTUREDMETADATA.Z_DKAUDIOMETADATAKEY__PORTTYPE as "AUDIO PORT TYPE",
ZSTRUCTUREDMETADATA.Z_DKBLUETOOTHMETADATAKEY__ADDRESS as "BLUETOOTH ADDRESS",
ZSTRUCTUREDMETADATA.Z_DKBLUETOOTHMETADATAKEY__NAME as "BLUETOOTH NAME",
ZSTRUCTUREDMETADATA.Z_DKNOWPLAYINGMETADATAKEY__ALBUM as "NOW PLAYING ALBUM",
ZSTRUCTUREDMETADATA.Z_DKNOWPLAYINGMETADATAKEY__ARTIST as "NOW PLAYING ARTIST",
ZSTRUCTUREDMETADATA.Z_DKNOWPLAYINGMETADATAKEY__GENRE as "NOW PLAYING GENRE",
ZSTRUCTUREDMETADATA.Z_DKNOWPLAYINGMETADATAKEY__TITLE as "NOW PLAYING TITLE",
ZSTRUCTUREDMETADATA.Z_DKNOWPLAYINGMETADATAKEY__DURATION as "NOW PLAYING DURATION"
FROM ZOBJECT
left join ZSTRUCTUREDMETADATA on ZOBJECT.ZSTRUCTUREDMETADATA = ZSTRUCTUREDMETADATA.Z_PK
left join ZSOURCE on ZOBJECT.ZSOURCE = ZSOURCE.Z_PK
WHERE ZSTREAMNAME like "/audio%" or ZSTREAMNAME like "/bluetooth%" or ZSTREAMNAME like "/media%" 
ORDER BY "START"

Starting with audio output and input, where we can get an idea of what type of device this phone was plugged into and how the audio directed.

This is an example of my afternoon commute. I plugged my phone into my car and used CarPlay. You can see indications of CarPlay and the iPhone Microphone. You may see this audio input go back and forth between CarAudio and Microphone in instances where the user is using Siri to do dictation for SMS messages, Maps, Music, Notes, etc. Just after I got home I listed to audio on my iPhone using my AirPods, note the “/Bluetooth/isConnect” connection switch.

It is worth noting here that my Bluetooth Bose QC35s show up in the Bluetooth/Audio events, but my Bose Sleepbuds did not.

Now that we know how the audio is routed, what was I listening to at the time? Everything I listen to gets recorded in (embarrassing) detail. On my commute to work I decided to get my day started with the 90s Radio Station in Apple Music. You can determine if I listened to a song or skipped it by looking at the ‘Usage is Seconds’ column (Sorry Spice Girls, you’re just not my jam). Looking at the data you may think I’m a huge Cher fan for listening to Believe for 22758+ seconds but remember it will record time from last “usage”. When I plugged my phone back into my car and it started playing where it left off.

On my jaunt between work sites, I put a podcast on and listened to the whole thing (~29 minutes). The “Usage in Seconds” column makes it look like I skipped it if you go with the logic that I presented with the Apple Music songs. It appears not all audio apps will store the data the same. This is an important caveat and another reason to test!

After I was done with my podcast, I switched back to music – the 80’s Radio Station this time. After work, I felt like I needed to rock out, so I asked Siri to “Play Muse”. The “Loading…” title gets recorded and a custom Muse playlist started playing.

Installed Apps

As expected this one keeps track of installed apps! Nothing more, nothing less. It does not appear to keep track of app updates.

SELECT
datetime(ZOBJECT.ZCREATIONDATE+978307200,'UNIXEPOCH', 'LOCALTIME') as "ENTRY CREATION", 
CASE ZOBJECT.ZSTARTDAYOFWEEK 
    WHEN "1" THEN "Sunday"
    WHEN "2" THEN "Monday"
    WHEN "3" THEN "Tuesday"
    WHEN "4" THEN "Wednesday"
    WHEN "5" THEN "Thursday"
    WHEN "6" THEN "Friday"
    WHEN "7" THEN "Saturday"
END "DAY OF WEEK",
datetime(ZOBJECT.ZSTARTDATE+978307200,'UNIXEPOCH', 'LOCALTIME') as "START", 
datetime(ZOBJECT.ZENDDATE+978307200,'UNIXEPOCH', 'LOCALTIME') as "END", 
(ZOBJECT.ZENDDATE-ZOBJECT.ZSTARTDATE) as "USAGE IN SECONDS",
ZOBJECT.ZSTREAMNAME, 
ZOBJECT.ZVALUESTRING
FROM ZOBJECT
left join ZSTRUCTUREDMETADATA on ZOBJECT.ZSTRUCTUREDMETADATA = ZSTRUCTUREDMETADATA.Z_PK
left join ZSOURCE on ZOBJECT.ZSOURCE = ZSOURCE.Z_PK
WHERE ZSTREAMNAME is "/app/install" 
ORDER BY "START"
app_install.png

Other Streams

A few other streams of interest:

  • /app/locationActivity – Contains location data, but not exactly what you think. In the examples I’ve seen on my own phone it was Redfin MLS locations – not where I was at a given moment.

  • /display/isBacklit – Was the display on or off?

    • 0 = no

    • 1 = yes

  • /display/orientation – How was the devices being viewed?

    • 0 = landscape

    • 1 = portrait

  • /safari/history – Safari history, same as macOS – see my previous article.

  • /watch/nearby – Determines if watch is within communication distance or not.

    • 0 = no

    • 1 = yes

  • /widgets/viewed – Swipe right to view widgets, it will show how many were “viewed” but not exactly which ones.

Now what?

Correlation! This database holds a serious amount of data and it can be easy to get tunnel vision. Think about correlating this data with the location data I’ve presented in other presentations and blog articles. Where was the user when they were looking at a specific app or browsing to a specific website? Were they driving distracted and watching YouTube when they shouldn’t have? If the user was using a specific app during a time of interest, go to that app’s data and look to see if it may contain data relevant to your investigation.


Video Now Available - #DFIRFIT or BUST: A Forensic Exploration of iOS Health Data

$
0
0

Heather Mahalik and my presentation of the iOS Health Database from the DFIR SANS Summit this past summer is now up. As always you can find the link to all my presentations, videos, and other resources on mac4n6.com/resources.

Slides and Script! From Apple Seeds to Apple Pie & Introducing APOLLO: The Apple Pattern of Life Lazy Output'er

$
0
0

I had the privilege and honor to present at the first ever Objective by the Sea Mac Security Conference yesterday in Maui (hardship, right?). It was only the first day and it was absolutely spectacular, I may have to make this one a regular! I can easily recommend attending this conference.

I presented From Apple Seeds to Apple Pie - an Apple Pattern of Life talk (mostly focused on iOS devices). You can find the slides in my Resources section.

I also just released a (very) beta version of APOLLO (Apple Pattern of Life Lazy Output’er) on my GitHub page. The TL;DR of the script: Take all the creepy databases that Apple writes events to, perform individual SQL queries on them to pull out investigative useful data, and combine them into another SQLite database for easier/quicker analysis and correlation.

This script and its modules are still in the testing phases so please be careful when using this on real cases. Expect more modules and testing to be released, I’m holding some back due to some timestamp issues and other are partially written up.

Do it Live! Dynamic iOS Forensic Testing

$
0
0
fuck-it-bill-fubar-well-do-it-live.jpg

Testing and forensics go hand in hand. You cannot be sure about a certain artifact on what it contains or what certain pieces mean without testing (and not just once, but over and over and on multiple devices and operating systems!) I probably do this more than most forensic investigators but it is something I obsess about. If I’m not absolutely sure, I test – always. Even then I will caveat it to very specific instances of my testing platform. I hope this article will help most investigators and researches up and running with dynamic iOS testing.

Requirements & Prerequisites:

  • Jailbroken iOS Test Device (the newer iOS the better, generally!)

    • iPad, iPhone, iPod Touch – doesn’t matter.

  • Familiarity with your jailbreak, every jailbreak is different and may provide different sets of utilities.

  • Patience – Testing is neither quick nor easy and can be downright infuriating sometimes.

Connecting to Your iOS Device

Most newer jailbreaks will come with some sort of SSH server on them, determine how to connect to it via SSH. All examples in this article will be performed on MacOS (big surprise) however it shouldn’t be impossible to do this on other platforms. I’ve written a couple of articles on accessing jailbroken devices:

To connect to your iOS device, you can use normal access via Wi-Fi, but this may lead to stability issues when copying off large amounts of data or general connection issues. You may want to access the device off the network instead. I like to use a utility from the libimobiledevice suite of tools called iproxy. This allows me to access it via a USB lightning cable and no network. This uses usbmuxd to create a TCP tunnel over USB. More info/similar tools here if you need it.

Run iproxy in a separate terminal window or set it up as a Launch Agent.

Usage: iproxy 4242 22 [UDID]

  • Local Port 4242 – You can use whatever port you like, I like 4242 (It’s the answer to everything.)

  • Device Port 22 – Default SSH port for most jailbreaks, except for Meridian that likes to be fancy and run on 2222 (customize as required).

  • Device ID (UDID) is optional but useful if you are connected to multiple devices at a time.

Nothing will be displayed apart from “waiting for connection” until you connect a device. Once you do, you’ll see the devices UDID and port number in the iproxy output.

iproxy.png

In another terminal window, SSH into it using the local port you setup with iproxy. You can use localhost or 127.0.0.1, whatever your personal preference is. As for the username you have two choices – root or mobile, root is obviously root and mobile is a limited user account. I always choose root but worth knowing about both. Also FWIW, make sure you change the default iOS password of these accounts from ‘alpine’ with passwd if it’s connecting to any network at all.

Executing Non-Native Binaries

Depending on which jailbreak you are using, certain utilities may not be made available to you. With any luck the basics will be provided by the jailbreak using Jonathan Levin’s binpack. If you want to upload your own, you’ll have to sign them and provide entitlements to run them on the device.

One tool that I really like for file monitoring (discussed later) is fsmon by NowSecure. I’ve attempted to build this from source for iOS but once uploaded I get an error that I don’t know how to fix (granted I didn’t research it much). Instead I pulled the binary from the DEB package provided here https://github.com/nowsecure/fsmon/releases.

I can unarchive the DEB archive using The Unarchiver (My favorite unarchive on macOS!). I then unarchive the data.tar.gz using The Unarchiver or native utilities to get the ‘/usr/bin/fsmon’ binary.

unarchive.png

The fsmon binary is Fat or Universal binary meaning it can have multiple architectures stuffed into a single file. This particular binary has arm_v7 (32-bit) and arm64 (64-bit) Mach-O binaries.

fat.png

We will need to thin this binary to a single architecture to get to run on our device. I chose arm64 for this since I have a 64-bit device (iPhone 7). You can thin/sign/entitle on the Mac too using jtool but just in the event you are not working from one (and why not!? I’m sitting here judging you right now.) I’ll upload the binary to the device and run the same commands.

Using scp I can upload this binary. For my particular jailbreak I needed to create a symlink (ln -s) to the scp binary provided by Jonathan’s binpack before I could use it.

scp.png

Using scp with the CAPITAL P argument (why the port flags are not consistent between SCP and SSH is beyond me) and our iproxy port of 4242 to copy fsmon to root’s home directory, /var/root.

scp2.png

Now if we try to run it from root’s home directory, it will fail (“Operation no permitted”) since binaries on newer iOS’s can only run from certain directories. That’s not the only problem, it also needs to be signed and entitled.

First let’s deal with only one binary, in order to sign and entitle we need to extract the 64-bit binary from Fat binary. We can do with a couple tools. If you are on macOS and have lipo (get it? fat binary…lipo…thin…sorry, this makes me giggle every time.) I will output to a file named fsmon64 so I know it is the 64-bit binary and upload it to the device.

lipo fsmon -thin arm64 -output fsmon64

Since I’ve uploaded mine to the device already, I don’t have lipo on the device I will use Jonathan’s jtool instead.

jtool -arch arm64 -e arch fsmon

This will extract the 64-bit binary to a file named fsmon.arch_arm64 into the current directory. You will have to change the permissions to execute it (chmod 700), but we still need to deal with signature and entitlements. As shown below it has an adhoc signature and no entitlements.

To get the signature and entitlements from any binary you can run the following jtool command, example below is from the dd binary. Notice it has a Platform Binary signature and the “platform-applications” entitlement.

jtool --sig --ent <binary>

dd.png

If I tried to execute the fsmon binary in /var/root, I’ll still get the “Operation not permitted” error. If I move it to a directory, I should be able to execute from I’ll get a different error, “Killed: 9”, next step is fixing the signature and entitlements.

error.png

Extract the entitlements from another (working) binary on the device using jtool and save this to a file named ent.xml for use later.

jtool --ent > ~/ent.xml

ent.png

Using jtool again, lets sign fsmon.arch_arm64 as a platform application and provide the binary the entitlements we just extracted. Verify it worked with (--sig/--ent) and execute it. Yay, working binary! (Feel free to rename as necessary, again I use fsmon64 or just fsmon.)

jtool --sign platform --inplace --ent ~/ent.xml /jb/bin/fsmon.arch_arm64

Reviewing Directories and Files

Quick iOS partition review - take a look at the /etc/fstab file. There are two primary partitions (and a baseband one if you’re into that kinda thing.) The first mounted on / is the system partition where the operating system files are contained. It is theoretically read only as noted by the ‘ro’, however recall that we just put the fsmon binary in /jb/bin. When it comes to jailbreaks that ‘ro’ is more of a reminder of what it is on stock devices. The data partition mounted on /private/var is where all the user data is, this is the primary partition that you’ll be using for your forensic analysis. All native and 3rd party application plists, databases, and other files are located there.

fstab.png

In order to find data associated with a particular application I can use the find command and the bundle ID associated with an app.

find /private/var -ipath *net.whatsapp.Whatsapp*

In the example below, I started looking for WhatsApp data. This is a good initial triage of the applications data, this doesn’t get me all the files but it helps direct me to the related directories. You’ll notice that GUID in the file path, this will be different for all applications across all devices and will change.

Going to the following directories and perusing the data will help me determine what type of data a certain application stores and how it stores it.

  • iCloud Artifacts:

    • /private/var/mobile/Library/Caches/CloudKit/com.apple.bird/57T9237FN3.net.whatsapp.WhatsApp

  • /private/var/mobile/Library/Application Support/CloudDocs/session/containers/57T9237FN3.net.whatsapp.WhatsApp

  • The combination of the ‘Shared App Group’ and ‘Data Application’ directories will generally hold most of the user data associated with an application.

    • /private/var/mobile/Containers/Shared/AppGroup/133904F3-EAA0-48E9-905C-90BB93A7DDA2/

    • /private/var/mobile/Containers/Data/Application/97AD4FDE-2089-455A-8B21-06E4E2225626/

  • It is worth mentioning that if you are looking for the Applications bundle the Bundle ID will not get you there, instead look for the name of the App.

    • /private/var/containers/Bundle/Application/6B6D4621-845A-4EE7-AECF-D68CC00E5C4E/WhatsApp.app/

Finding the right directory/directories for the app in question can be time consuming. One of my favorite tools that solves this issue is cda. Using the same method above, I’ll upload this binary to my device.

As shown below, all you need to provide cda is a search term. I provided it the term ‘whatsapp’ and it provided me the same directories (more even) as above. If you’re not quite sure what you are looking for yet, provide it a single period ‘.’ and get a listing by Bundle ID. It is worth noting that this will only provide app data, if you are doing research on native iOS data you won’t get it using this – time to dig in and find it the hard way.

Looking into one of the WhatsApp directories, I start to get a feeling for what data an application is storing. You will normally find SQLite databases, plist files, media, log files and other files related to an application. ~90% of what you’ll be looking at are SQLite databases and plist files, so I’ll focus on those for this part of the article.

Starting with SQLite databases, we can use sqlite3 (provided by the binpack) on the device to triage the database. My process is to look at the database names first and see if anything is obvious. If I’m looking at a chat app, I’ll look for keywords like chat, message, etc. I’ll focus on WhatsApp’s ChatStorage.sqlite database for this example – seems like a reasonable choice for chat messages. Using sqlite3, I’ll dump the table listing and peruse it for anything interesting. Seems to me that ZWAMESSAGE would contain the chat messages!

Using a SQL SELECT statement I can dump the contents of this table; however this is where sqlite3 may not provide the best analytical view. In this case I might use scp to copy it off the device and use a GUI based SQL viewer to create queries and join multiple tables. (FWIW, I like DB Browser for SQLite). Need a SQLite reference guide, check out the one Heather Mahalik and I created for our classes (FOR585 – Advanced Smartphone Forensics, FOR518 – Mac Forensic Analysis and Incident Response).

I will still use sqlite3 for per-message testing to answer different questions.

  • What does xyz flag in this column mean? Are 0 and 1 the only values?

  • If I send a piece of media, what does it look like in the database? Is it stored in a different table?

  • Message direction or contact information which column stores that?

I will run the same query over and over testing different flags in different columns as I populate data manually on the device. Does this take time? Sure does! But it’s the only way to be sure. Applications are known to change database schemas and values as their application updates.

sqlite3 ProTip: Ctrl+D to quit out of the sqlite3 shell

Next let’s dive into those pesky plist files. For third party applications I will usually start in the applications Preferences directory. The Preferences directory will usually contain a configuration plist file containing some useful bits like usernames, servers, usage timestamps, keys, and passwords. Yes, plaintext, non-obfuscated passwords! 🤷🏻‍♀️

The example below is one for Whatsapp (specifically the one located in the Shared App Group directory. There may be multiple for each application.) I’m using jlutil (Jonathan’s interpretation of plutil, the native macOS utility, to view this plist.)

whatapp_jlutil.png

Another option is plconvert which will convert it to a text file representation and show a less-than-helpful representation on standard out. It will also output to an XML file, here named tmpfile by myself. I consider this slightly less “clean” as it will leave these converted files everywhere on the system, but it’s all personal preference. I will say the plconvert is more useful from a timestamp interpretation and data BLOB stance.

plconvert_xml.png

File Monitoring

Say you’re testing a application that has the ability to take photos using the iPhone camera. Where are those photos stored? Or how about if you toggle one of the switches in the Settings application, where is that stored? In a database or a plist file?

An easy way to figure this out is to use a file system monitor, it should at least point you in the right direction. As shown above I prefer to use the fsmon utility from NowSecure, however Jonathan’s binpack includes fs_usage which provides the same data. I prefer the layout of fsmon’s output.

In the example below, I took a picture of my sidekick Elwood with the Camera app on the iPhone while running fsmon. (I’d like to say he helped with this article, but he just slept all day next to me. Cats don’t make the best research assistants.) In the fsmon output you can see that when I took a picture, the “Camera” process saves the picture in a few temp files before it finally saves it in the DCIM directory as an HEIC file (the newer iOS image format) and creates a thumbnail image for the Camera app, PreviewWellImage.tiff.

camera.png

I hope this helps everyone getting started doing their own iOS forensic research!

(In the rare event anyone wants to see my sidekick Elwood…here is the pic I took. Super Lazy.)

AirDrop Analysis of the UDP (Unsolicited Dick Pic)

$
0
0
cultofmac.png

I saw this article “NYC plans to make AirDropping dick pics a crime” on Friday and it got me thinking. What exactly are the cops going to find if they do an analysis of a device, either the sender or the receiver? 

I’ve already done my fair share of analysis when it comes to the Continuity technology with Apple devices with Heather Mahalik at the SANS DFIR Summit in 2017. This article gave me a good reason to do a revisit on how AirDrop artifacts between mobile devices.

Testing Scenario

I’m using the scenario of sending of dick pics in the middle of Times Square as an example. I have two test phones, an iPhone 7 and an iPhone 6. The iPhone 7 belongs to “David Lightman” and the iPhone 6 belongs to “Jen Mack”.  Each device is on iOS 11 for this test. Instead of UDPs, Jen is going to be sending David USP’s instead, or Unsolicited Squirrel Pics – I suppose I need to keep this family friendly right?

AirDrop works over ad-hoc Peer-to-Peer networking over Bluetooth and Wi-Fi. When a user attempts to AirDrop someone a file it will determine who is within range and who is currently receiving AirDrop connections. This may be set to Contacts Only or Everyone (or Receiving Off for those who don’t want UDP’s, smart choice). Poor David has the setting to Everyone, he’ll get some surprises!

IMG_0112.jpg

To send the squirrel photo to David, Jen used the native Photos application’s sharing feature to select a device to AirDrop the USP to. The only device within range that has AirDrop turned on and in a receiving mode is David Lightman’s iPhone.

IMG_0054.jpg

Jen selects his phone and sends the picture. On David’s device he receives a pop-up, he can choose to Decline or Accept. 

IMG_0109.jpg

AirDrop ID

Important to this analysis is an AirDrop ID. On devices this can be found in /private/var/mobile/Library/Preferences/com.apple.sharingd.plist. The keyword ‘sharingd’ is very important in this scenario as much of the Continuity artifacts can be found by searching for that process name. This plist file should be available in an iTunes backup and from any commercial forensic utility. 

Jen’s AirDrop ID is 3DAA769F9F23.

jens_airdropid.png

David’s AirDrop ID is E7D713098E3B, also take note of that the DiscoverableMode is set to Everyone. (Jen does not have this key, hers was set Contacts only.)

Artifacts from the Receiver’s (David Lightman) Device

Assuming that the receiver is the individual who would likely make the complaint to the cops, we will look at this iPhone first to determine what artifacts will persist and if they are show attribution to a certain device and/or owner.

Very few artifacts on the devices will actually show this connection happening. Let’s take a look at some of the main artifacts that I would explore if I had the case.

Unified Logs  

Logs can show lots of data and in great verbose detail. Unfortunately, these Unified Logs do not get backed up on iOS devices. The only way to extract them from the device is to get a physical file dump of the device (Jailbreak/Cellebrite CAS/GrayKey). (UPDATE: 12/04/18 - It has come to my attention from a commentor that these unified log files can be collected using the sysdiagnose process on iOS devices. I’ve tested this and they are in fact there. Funny enough, per Apple Documentation, it wants you to copy this archive off the device using AirDrop. 🤷🏻‍♀️ Not entirely the most forensically sound method but hey, data is data - get it with whatever means your legal team will allow. Thanks ‘G’!)

In this example on David’s iPhone, you can see the sharingd process start to scan, attempting to find peers (Continuity connections). During this process you will also see lots of wirelessproxd and bluetoothd activity as well since AirDrop uses Bluetooth and Wi-Fi services. You will also see references to AWDL or Apple Wireless Direct Link.

Follow the logs down a bit and you’ll start to run into some potentially identifying information. We are now starting to see records containing Jen’s device name “Jen Mack’s iPhone”. Pay close attention to the first record highlighted and you’ll see what looks like a MAC address, however it is neither the Bluetooth nor the Wi-Fi addresses. This address is generated different every time a connection is made, therefore not an ideal data point for attribution. 

Going back to the device’s name. This may lead you in the right direction, however anyone can name their device anything they want. I can call my iPhone X “Samsung S9” for instance, no identifying information and frankly a device that doesn’t even do AirDrop.

The next couple of highlighted sections (in red), show the start of the AirDrop connection. We can see an incoming request and start seeing records that include the AirDrop ID of Jen’s iPhone, 3DAA769F9F23. This is where I think attribution may be possible. This ID seems consistent across connections and different devices in my experience. It may be possible to tie this to an Apple ID or specific device. I have yet to find this connection however – it’s not part of the Serial, UDID, or various MAC addresses that I can tell. More research is needed here.

Next, in purple, is more metadata about the file transfer to include transfer status, media type, originating device name, source application, and associated transfer GUID.

In between these metadata records, it shows that it is transferring a file to /var/mobile/Downloads/com.apple.AirDrop/BA40D8CF-54E6-4B09-8F2F-717FB638174E/Files. Whether the user chooses Accept or Decline, the photo still gets transferred to the device.

Finally, the user receives an alert about the AirDrop’ed photo. Following this record is more details on how the user is alerted to the connection audibly and physically with alert tones and vibrations.

This particular AirDrop connect was “Declined” by David. This can be seen in the records below where the ‘selectedAction’ now shows Decline and a clean-up process has started. Highlighted in teal is the AirDrop connection closing.

airdrop_declined_closed.png

If the user Accepted the AirDrop’ed photo, the logs would look like the following. The file would have been ‘accepted’ in the metadata records. Finally, since it is a photo – the default application Photos wants to import it into its files and databases. The AirDrop connection is also closed at this time.

Photos Database

Since the photo gets transferred into the user’s Photos database we can look there for hints. This is one file that does get backed up by iTunes and commercial forensic utilities. The Photos database is located /private/var/mobile/Media/PhotoData/Photos.sqlite on the physical device. 

The filename on Jen’s device was IMG_0007.JPG before it got renamed to IMG_0110.JPG on David’s phone. The original filename can be found in the ZADDITIONALASSETATTRIBUTES table in the ZORIGINALFILENAME column.

It is worth noting that the imported photo will carry the same EXIF data as the original on Jen’s device, in fact it is exactly the same photo (hashes should match). The file size and some timestamps get carried over into the Photos database. Other metadata items can be used to determine a photo from another device are the Height/Width, assuming it is from a different family of devices the pixels may be different.

In the ZGENERICASSET table, we have the same Height/Width, however some timestamps are updated to match the time of import via AirDrop. The ZDATECREATED timestamp matches the original creation of the photo. The ZCLOUDASSETGUID matches the GUID seen in the last few entries in the logs above. There does not appear to be any attribution data in this database.

Artifacts from the Sender’s (Jen Mack) Device

In the rare event that the Sender’s device was acquired, the related artifacts are below.

Unified Logs

Much of the logs look similar to the receiver. The sample below shows the sharingd process connecting to David’s AirDrop ID, E7D713098E3B and shows his iPhone device name. Again, the MAC address does not appear to be consistent and will change on every connection.

sender_connection.png

A few more lines down we can see some file conversion for the photo, IMG_0007.JPG (which apparently wasn’t needed). This is followed by an AirDrop transaction with the AirDrop ID of David’s iPhone.

Conclusion

The lack of attribution artifacts at this time (additional research pending) is going to make it very difficult to attribute AirDrop misuse. At best, if the cops are provided each device, they can pair the connections up – however this will require access to file system dumping services like Cellebrite CAS, GrayKey from GrayShift or performing a jailbreak to get the most accurate analysis. If the devices are named appropriately (ie: If Jen Mack’s iPhone was actually named ‘Jen Mack’s iPhone’) this may make an analysis easy, however I can see an instance where this can be abused to imitate someone else.

Curious about the USP, here you go. This was an advertisement in the DC Metro system, that for some reason whenever I saw it I giggled. 🤷🏻‍♀️

IMG_0007.jpg

On the First Day of APOLLO, My True Love Gave to Me - A Python Script – An Introduction to the Apple Pattern of Life Lazy Output’er (APOLLO) Blog Series

$
0
0

I originally released APOLLO at the Objective by the Sea conference in early November. Since then I’ve received a surprising amount of positive feedback about various analysts using this tool or the accompanying SQL queries on their file system dumps to help a variety of investigations.  

It now time for a proper introduction. I will present this to you in what I’d like to call “The Twelve Days of APOLLO” a holiday themed (very, very loosely) blog series starting today! 

Why

APOLLO stands for Apple Pattern of Life Lazy Output’er. I wanted to create this tool to be able to easily correlate multiple databases with hundreds of thousands of records into a timeline that would make the analyst (me, mostly) be able to tell what has happened on the device.

iOS (and MacOS) have these absolutely fantastic databases that I’ve been using for years with my own personal collection of SQL queries to do what I need to get done. This is also a way for me to share my own research and queries with the community. Many of these queries have taken hours, even days to research and compile into something useful. 

My goal with this script is to put the analysis function the SQL query itself. Each query will output a different part of the puzzle. The script itself just compiles the data into a CSV or SQLite database for viewing and filtering. While this database/spreadsheet can get very large, it is still more efficient that running queries on multiple databases and compiling the data into a timeline manually.

Because this script is all based on investigator provided queries it is highly customizable. If an investigator only wants health data, they can elect to run only those query modules. Each query can be customized by the investigator relatively easy, if you don’t need that column – remove or comment it out! I’ve uploaded many queries that I think most investigators would find useful. It is my hope that other investigators create their own and share them with the community.

How

The script is a simple Python script that intakes what I’m calling modules. Each module is a single SQL query that pulls out specific data from a database. The module will also have some metadata about what the SQL query

module.png

The module is a text file that contains a few required items:

  • DATABASE – The exact name of the database to perform the SQL query on.

  • ACTIVITY – What this particular record is categorized as.

  • KEY_TIMESTAMP – The timestamp to be used as the key for timelining.

  • SQL Query – The query that is performed on the database. They query should extract one specific type of record from the database, thus a database may have many modules for very specific outputs.

Depending on what the user is looking for they can run one, some, or all the modules and it will output to either a CSV or SQLite database file.

Example Usage

The script is a simple python script that only takes only a few arguments. 

python apollo.py -output {csv, sql} <modules directory> <data directory>

There are two output options, a CSV file or a SQLite database. Please let me know if other outputs are required. Following that, the path to the module’s directory and the path to the data directory. The data directory can be a single directory full of the databases needed to parse or a full file system dump – the script will find the databases by name in the module.

An example of the output is seen below. Each SQL query run will have different output for that particular query and database in the output column. In the example we see everything from health steps/distance, to location, to application usage. The Key column contains the timestamp that each record is organized on, the Activity contains the type of record. The database and module columns contain which database and module parsed that information.

Challenges 

One of the main challenges with these Pattern of Life databases is access. Most of the really good forensically useful POL data is not easily accessible, particularly with iOS devices. With macOS devices we may need to deal with FileVault encryption or database level encryption. This script assumes you have good data to work with. Some databases may be available some may not be.

Feedback

While I primarily created this script for my use (don’t we all), I am open to feedback. If instead of using ConfigParser module files you want something else, let me know. If you need different output formats, let me know. I will consider all feedback.

I would appreciate all the help I can get. I’ve primarily tested these queries with a focus on iOS 11, however I know many will work on older versions and some have been tested with available data from iOS 12 (iOS Health). I’ve also tested running the script on macOS with Python 2.7 installed, it may not run as expected on other platforms. (FWIW: I will upgrade to python3 when macOS does.)

The script was just updated to be more efficient by Sam Alptekin of @sjc_CyberCrimes. Sam made the script much faster when running against full file system dumps. He was able to take it down from hours to run to mere minutes. Thanks Sam!

The Next Eleven Days

Each day will have a different topic that will guide you through the usefulness of the APOLLO framework. I focus primarily on iOS in these articles, but many of the queries can be ported over to macOS as well. I do intend to work on this in the future however I will discuss more on improvements later.

I will cover all sorts of topics in the next couple of weeks.

  • Device State

  • Media

  • Health

  • GUI Artifacts

  • Network and Communications

  • Connections

  • Application Usage

  • So much more!

Get APOLLO here and take it for a spin!

Day 2: On the Second Day of APOLLO, My True Love Gave to Me - Holiday Treats and a Trip to the Gym - A Look at iOS Health Data

Day 3: On the Third Day of APOLLO, My True Love Gave to Me – Application Usage to Determine Who Has Been Naughty or Nice

Day 4: On the Fourth Day of APOLLO, My True Love Gave to Me – Media Analysis to Prove You Listened to “All I Want for Christmas is You” Over and Over Since Before Thanksgiving

Day 5: On the Fifth Day of APOLLO, My True Love Gave to Me – A Stocking Full of Random Junk, Some of Which Might be Useful!

Day 6: On the Sixth Day of APOLLO, My True Love Gave to Me – Blinky Things with Buttons – Device Status Analysis

Day 7: On the Seventh Day of APOLLO, My True Love Gave to Me – A Good Conversation – Analysis of Communications and Data Usage

On the Second Day of APOLLO, My True Love Gave to Me - Holiday Treats and a Trip to the Gym - A Look at iOS Health Data

$
0
0

The iOS Health database may be the easiest database to acquire. While other databases need physical file system dumps of the devices, this database can be accessed with an encrypted iOS backup, or possibly an iCloud acquisition. If you happen to have a file system dump these databases can be found in /private/var/mobile/Library/Health. The database we are going to be looking at for this article is the healthdb_secure.sqlite database. 

Retention of Pattern of Life data is also an issue as well. Some data is kept around for a day, some is kept forever. The data in the health database is by far has the most longevity. Users generally want to keep these records indefinitely. Apple makes it easy to backup and restore Health data to new devices. My own personal health data goes back years! It is worth mentioning that this longevity will also make a very large SQLite database, mine is currently at 820mb, that’s a giant SQLite database! This particular one is from iOS 12.1.1.

NOTE: In the following screenshots I’m not showing the output from the APOLLO script only due to ease of readability, however all data represented in this output is in the script output.

The health_distance module extracts the recorded distance in meters for a specific period of time. The data type of ‘8’ is how the Health database keeps track of this distance. More of these data types will be explored.

health_distance.png

Along the same line is the health_steps (data type = 7) module. 

health_steps.png

We have distance in meters and steps, how about height? The flights climbed (data type = 12) can be extracted using the health_flights_climbed module. It appears I don’t take the stairs as much as I should. #newyearsresolution

health_flights_climbed.png

If the user has a paired Apple Watch, it will record very regular heart rate readings (data type = 12). We can view this with the health_heart_rate module. This is the same datatype that is recording the new ECG heart monitor on watchOS 5.1.2/iOS 12.1.1.

health_heart_rate.png

Time to take a stand, the Watch records this action too! The health_stood_up module will show this (data type = 75). 

Finally, we end with some location information. Each time I record a workout on my watch, its starting location is also recorded. Using the health_workout_locations_start and health_workout_locations_end modules we can see these coordinates. The timestamps record the start and end timestamps of the workout, but only records the start in this particular “metadata key”. Full workout locations are stored elsewhere (still working on this one).

health_workout_locations.png IMG_3635.jpg

The iOS Health database is one of the largest databases on the system. I hope to have many more modules/queries created for many of the metadata entries captured in the health data, there are hundreds of data types! Got a special request, let me know!

If you want more information on iOS Health data, Heather Mahalik and I discussed this database recently at the SANS DFIR Summit in Austin.

Now go eat cookies. I won’t judge you.

Grab APOLLO Here!

Start with Day 1: On the First Day of APOLLO, My True Love Gave to Me - A Python Script – An Introduction to the Apple Pattern of Life Lazy Output’er (APOLLO) Blog Series

On the Third Day of APOLLO, My True Love Gave to Me – Application Usage to Determine Who Has Been Naughty or Nice

$
0
0

On this third day, we will focus on application usage. We will cover three databases:

  • KnowledgeC.db

    • Be sure to check out more detailed information on this database in my two previous articles.

    • Access to this database is limited to a file system dump, it will be located in /private/var/mobile/Library/CoreDuet/Knowledge/KnowledgeC.db

  •  InteractionC.db

    • Access to this database is limited to a file system dump, it will be located in /private/var/mobile/Library/CoreDuet/People/InteractionC.db

  • CurrentPowerlog.PLSQL

    • Access to this database is usually limited to a file system dump, but I recently learned that if you can perform a sysdiagnose on the iOS device you can get this log as well! This method is certainly not forensically sound, but it will get you access to the database. You will have to rename this database to “CurrentPowerlog.PLSQL” from something like “powerlog_YYYY-MM-DD_##-##_########.PLSQL” to parse it with APOLLO. I have plans to update the script to support this naming scheme. 

    • In a file system dump, you can find this database in /private/var/containers/Shared/SystemGroup/<GUID>/Library/BatteryLife/CurrentPowerlog.PLSQL

      • It is worth a mention here that additional historical Gzipped PowerLog databases may be found in the /Archives directory in the path above. (My APOLLO script does not handle auto unarchiving of these yet, but it is planned for the future.)

Application Information, Installation, & Deletion

Let’s start by getting some basic app information. The Powerlog has a nice listing of iOS applications with their App name, executable name, bundle ID, and version and app type. These entries are not exactly an ongoing log file, but it does get updated frequently. The app type column can provide information on what type of application it is.

  •  1 – Background iOS Service

  • 3 – iOS Native App

  • 4 – 3rdParty App

These entries will also have information on if the app has been deleted. This listing can be extracted by using the powerlog_app_info module.

I have a very similar module called powerlog_app_deletion that uses the application deletion time as its key to get just the recently deleted applications.

To get a listing of recent application installs, we need to go to the KnowledgeC.db database. You will see in this blog series that you cannot rely on one database for all the answers. The module knowledge_app_install will extract the time of install and Bundle ID for the newly installed app. 

knowledge_app_install.png

Application Play by Play 

Knowing what application was being used at any given moment, down to the second, can be a huge forensic win. Fortunately, we have a couple of options, each a little different.

The first is the KnowledgeC.db database. The knowledge_app_inFocus module shows the app Bundle ID, day of the week, GMT offset, start/end of the usage time from which I calculate usage time in seconds.

knowledge_app_inFocus.png

Another option is the powerlog_app_usage module which uses the CurrentPowerlog.PLSQL database. The output contains the app Bundle ID and a few other metadata items.

You will notice a few additional columns in the output:

  • ORIGINAL_SCREEN_STATE_TIMESTAMP

  • OFFSET_TIMESTAMP

  • TIME_OFFSET

These additional columns are needed because the timestamps need to be normalized. The original timestamp is stored with an offset, sometimes in the future, sometimes in the past. This offset is stored in PLSTORAGEOPERATOR_EVENTFORWARD_TIMEOFFSET table in the CurrentPowerlog.PLSQL database. This offset gets used in many of the Powerlog tables. I want to provide a warning to other investigators to not always believe the timestamp provided in a database. You MUST test this, I’ve seen offsets from as little as a few seconds to as much as 15 minutes. In my queries I’ve done my best to test what I can, but I’m sure I’ve missed some and they may change per iOS version (we will see an instance of this in the next module). Noticed I missed one? Please let me know!

The modules powerlog_app_usage_by_hour and powerlog_app_usage_by_hour_iOS12 extract data usage on a per hour basis. During the research for this blog article, I was using my own iOS 12 Powerlog output from sysdiagnose to test differences with iOS 12. I came across one issue with this particular module, I determined in iOS 12 that the timestamp in this table now implements the same time offset that we saw above, however on iOS 11 (and older) it did not. Soon I will implement a function in the script to determine which iOS to perform which queries, however now it will run both so please be aware of this.

Below is an example from iOS 11.

powerlog_app_usage_by_hour_ios11.png

Below is an example from iOS 12 with the time offset applied (offset columns are hidden from view). Not shown in the screenshot is a bug where the applied time offset may show the ADJUSTED_TIMESTAMP off by a single second for earlier records. If anyone has recommendations on a better SQLite query to perform this offset adjustment, drop me a line!

These modules extract an applications usage on a per hour basis. The query will extract the app bundle ID, screen and background time, and additional background usage with audio and location.

Context Providers 

The next step is to provide more context to each application being used. We have quite a few modules for this.

The InteractionC.db database contains lots of information to correlate contact information with application activity. The screenshot below only shows a portion of the contact data for each record, but it should be a good indication of what email was being read or what contact was being texted. This module is named interaction_contact_interactions.

Curious what the user was browsing when they were using Safari, try the knowledge_safari_browsing module. There are a few catches to this one, it will not record private browsing and entries will be removed when they are history is cleared (either by the system or user).

Using application activity streams in the KnowledgeC.db database we can extract more information using knowledge_app_activity module on to determine items like Apple Map directions, Mailbox or Message views, specific 3rd party application usage, and other native Apple iOS app activities.

I created a similar module, knowledge_app_calendar_activity, specifically for Calendar activity since it has a bit more calendar related metadata items associated with it.

knowledge_app_calendar_activity.png

Again using the KnowledgeC.db for context, I can use the knowledge_app_intents module to determine more details of application usage, including sent messages, map searches and navigation, Safari browsing, and phone calls. A keen eye will notice the data blob in the SERIALIZED INTERATION (HEX) column starts with the hex of a binary plist. This binary plist contains more specific contact information, such as who a message was sent to or what contact was called. I saved it in hex to easily copy/paste it into a hex editor or to save off as a plist file.

Finally, we can use the knowledge_application_portrait to get even more contact information for messages or account information for an associated email account. The items in GROUP ID can vary but usually if it’s a GUID it will correspond to a specific email account that can be found in the user’s Accounts database.

knowledge_application_portrait.png

Have you been naughty or nice? Us forensic analysts are watching!

Grab APOLLO Here!

Start with Day 1: On the First Day of APOLLO, My True Love Gave to Me - A Python Script – An Introduction to the Apple Pattern of Life Lazy Output’er (APOLLO) Blog Series

naughty-nice-why.jpg

On the Fourth Day of APOLLO, My True Love Gave to Me – Media Analysis to Prove You Listened to “All I Want for Christmas is You” Over and Over Since Before Thanksgiving

$
0
0

The fourth day brings us media artifacts using the knowledgeC.db and CurrentPowerlog.PLSQL databases. Each database stores similar yet somewhat different records when it comes to audio, and video usage.

Let’s get in the mood!

KnowledgeC.db 

Starting with the knowledgeC.db database we get an idea of audio inputs and outputs. Using the knowledge_audio_input_route and knowledge_audio_output_route modules we can extract this data.

The example below is audio inputs. Two different devices can be seen in the screenshot below, a CarPlay device and my AirPods.

In the output example we see the same two devices. Common to both is the fact that you may see it bouncing back and forth as devices are being used. For example, if you are using CarPlay rocking out to WHAM’s Last Christmas, it will bounce between playing your music and using the microphone/speaker to listen/dictate messages as they come in.

knowledge_audio_output_route.png

The knowledge_audio_media_nowplaying is where the real truth of your guilty musical pleasures will make an appearance. It provides a detailed listing of what the user was listening to at a particular time. The example below shows me listening to music, podcasts, and audio books. There is no denying that you started listening to holiday music entirely too early!

CurrentPowerlog.PLSQL

The powerlog_app_nowplaying module sounds like it should extract the same information as above, however it is different in that it will just show the application’s bundle ID being used to play the media.

powerlog_app_nowplaying.png

More context can be found by using the powerlog_app_audio module. This module will extract the app/service name and/or bundle ID for the app using the audio function. In the screenshot below, I received a phone call and a bit later connected the iPhone to my car to listen to music. During that time, I was also using Siri (assistantd) to dictate messages. Fortunately for me, this database doesn’t show what I was listening to! 🤭

Similar to the module above, is the powerlog_audio_routing module. This shows where the audio was routed to, either the Speaker, Receiver, or Car in this example. 

Finally, the Powerlog populates a table just for videos. The powerlog_video module will show the application bundle ID that the video was played with, however not what video was playing.

powerlog_video.png

Grab APOLLO Here!

Start with Day 1: On the First Day of APOLLO, My True Love Gave to Me - A Python Script – An Introduction to the Apple Pattern of Life Lazy Output’er (APOLLO) Blog Series

christmas-songs-72542.jpg

On the Fifth Day of APOLLO, My True Love Gave to Me – A Stocking Full of Random Junk, Some of Which Might be Useful!

$
0
0

Today we go over one of the stranger databases on iOS, the Aggregate Dictionary database, or ADDataStore.sqlitedb. This database is only available with a physical file system dump in the /private/var/mobile/Library/AggregateDictionary/ directory. The database also has a different way of storing its data. Instead of a “this time this event happened” storage system like many of the other database I’ve gone over. This one aggregates data for the last seven days. It only records data on a per-day basis so the APOLLO modules will only store a day timestamp. 

This database is good to find random bits of useful stuff, not every case will need it but you might be surprise what it is tracking. The Distributed Keys and the Scalars are each keeping track of seemingly obscure items. In my opinion, the Scalars are more interesting. On my example database I have 5398 unique keys for Scalars and 795 keys for the Distributed table. I can’t even begin to show you everything this database tracks, its best just to take a look at one yourself to see what might help in your own investigations. I will focus here on a few of the more interesting Scalars entries.

I’ve previously written about this database with respect to Pincodes, Passcodes, and Touch ID.

APOLLO only has two modules for the Aggregate Dictionary. Since these are using only a per-day timestamp, I’ve made them easy to filter out or as a user choose to not use these modules. They can look a tad messy in the final output.

The first item I pulled out of the stocking is CarPlay data. The example below shows how many cars I’ve connected using CarPlay in com.apple.CarPlay.VehicleCount. I’ve connected this device to three different cars. I’m still testing the difference between*.CarPlayCar.* and *.tCarPlayPhone.* keys, however I could guess that Activations has something to do with how many times the app was selected while the ActiveTime is how long the app was in use.

The next item has to do with the Messages application. This app is collecting metrics on the different types of items sent and received over SMS or iMessage protocols.

imessage.png

The Settings applications (com.apple.Preferences) keeps track of which setting got viewed. The example below shows I viewed the Bluetooth menu twice on the 10th, and the privacy settings once on the 14th. I encourage everyone to search for various bundle IDs of interest in this output – you never know what the apps are going to store!

preferences.png

The Clock app (com.apple.MobileTimer) keeps track of how many alarms the device has set, if any are active, number repeating, and named alarms. Some apps are better at storing data like this than others.

Safari records the number of tabs open on a particular day

safari_tabs.png

The Photos app (com.apple.mobileslideshow) keeps track of how many photos there are in the albums.

Curious how many times a device was plugged in during a day, try the com.apple.power.state.pluggedin.count key. We will revisit this action in an upcoming device state article.

plugincount.png

When I say obscure, I mean obscure – it also keeps track of button presses…because why not!

buttons.png

Some settings are also stored in this database. You can perform a filter for a couple of keywords – enabled or disabled. I’ve provided a screenshot for both. For the “Enabled” keys, I chose to filter on the main interface, Springboard (com.apple.Springboard). The value is a binary value that means on (1) or off (0). This is different for the “Disabled” keys.

springboard_enabled.png

If the keys have the term “disabled” in them, you have to think opposite. For example, all these Accessibility features are actually turned on or enabled. If the disabled setting is a 0, it means it is turned on (you can see many of the settings in the iOS screenshot, Shake to Undo and Vibration for example.)

accessibility_disabled.png

Finally, in the toe of the stocking we can get some data usage information. I’ve filtered here by the Twitter application (com.atebits.Tweetie2). The screenshot shows how much data was transferred in kilobytes over Wi-Fi and/or WWAN – incoming or outgoing.

datausage_twitter.png

Looks like Nick is ready to analyze what’s in his stocking!

Grab APOLLO Here!

Start with Day 1: On the First Day of APOLLO, My True Love Gave to Me - A Python Script – An Introduction to the Apple Pattern of Life Lazy Output’er (APOLLO) Blog Series

On the Sixth Day of APOLLO, My True Love Gave to Me – Blinky Things with Buttons – Device Status Analysis

$
0
0

On this sixth day we’re going to go back to looking at the knowledgeC.db and CurrentPowerlog.PLSQL databases. If you are unfamiliar with these databases, please go back a few blogs. Today is all about what state the device is in. 

Let’s start with the battery level. This is surprisingly covered in a couple of databases and multiple tables in these databases, plenty of places to get this information. The first one is using the knowledgeC.db database with the knowledge_device_batterylevel module. This database provides the usage time between battery levels which may be used to determine amount of usage during a particular time period by the user or device.

Similar is a couple of modules using the CurrentPowerlog.PLSQL database. These two have slight differences. The powerlog_battery_level_ui module just has the battery level as shown in the GUI, while the powerlog_battery_level shows additional information such as raw level and if the device is charging or is fully charged.

powerlog_battery_level.png powerlog_battery_level_ui.png

The next state is if the device is locked or not. Again, we’ll start with the knowledgeC.db knowledge_device_locked module. 

knowledge_islocked.png

Going back to the CurrentPowerlog.PLSQL database we have a couple of modules for the same stat. The difference between these is that the latter keeps track of devices locks if the device is using the timed auto-lock function, that “1” just shows that it is in a locked state. The first example shows lock and locked states.

powerlog_lock.png

The next few modules are all random device states that may come in handy. The first is the button state. The powerlog_button_state module appears to keep track of which button are being pressed. I’m still testing this one, but this data came from an iPhoneX that has just the power button (apart from the volume buttons). I believe button 48 may be the power button as the timestamps seem to align with locking the device.

button_state.png

The powerlog_camera_state module will keep track of which app and which camera is being used. This will truly tell how many duckface selfies you’ve taken.

Care to know if THE DEVICE IS AT FULL VOLUME PLAYING ANNOYING YOUTUBE VIDEOS? Well then, give powerlog_device_volume a try. 100% is a full volume, and 0 is no volume or “muted”. For some reason I cannot get the “MUTED” column to populate when the device is clearly muted. 🤷🏻‍♀️

The powerlog_mobilebackup module keeps track of backup activity, in this case iCloud backups.

powerlog_backup.png

Finally, we have the powerlog_torch_state, which keeps track of when the device flashlight is turned on and off. I still think the torch sounds odd, but I guess the rest of the non-US based worlds calls it that. 🤷🏻‍♀️

powerlog_torch.png

This is real torch in my opinion.

Grab APOLLO Here!

Start with Day 1: On the First Day of APOLLO, My True Love Gave to Me - A Python Script – An Introduction to the Apple Pattern of Life Lazy Output’er (APOLLO) Blog Series

On the Seventh Day of APOLLO, My True Love Gave to Me – A Good Conversation – Analysis of Communications and Data Usage

$
0
0

Today is all about the CurrentPowerlog.PLSQL database. This database keeps track of many ways that data is transferred either by cellular, Wi-Fi, or Bluetooth methods. These modules can help determine where the data is going, which app is pulling down the most data, or simply keeping an eye on which apps are sending the most notifications.

Telephony Activity 

Starting with telephony artifact we can review the cellular registration using the powerlog_device_telephony_registration module. This outputs the cellular provider and the level of service provided. 

telephony_registration.png

The powerlog_device_telephony_activity module will keep track of telephony activity on the device. In the screenshot below, each time the CALL STATUS shows ringing, I was receiving a phone call (that I ignored), but where it says ACTIVE, I made a phone call.

Another module that shows call usage, is the powerlog_incallservice module.. Like the example above this shows me ignoring three calls (callForegrounded, callBackgrounded) and a call made (callStart, callStop).

incallservice.png

Network Usage

Mobile devices have network interfaces that track where the data is going. The powerlog_network_usage module keeps track of the incoming and outgoing bytes for these interfaces.

network_usage.png

If you want a bit more detail on which apps or services are using your precious cellular data, take a look at the output of the powerlog_process_data_usage module. This can make it easy to see which app is burning through your mobile data. (Mine is always Twitter).

The powerlog_push_message_received module will show push notification activity for various network-based services. In the screenshot below are the notifications for Slack, Twitter, iMessage, etc.)

push_message.png

Bluetooth Activity

Many Apple technologies rely on Bluetooth technology to function. Determine what state Bluetooth was in is logged. Using the powerlog_bluetooth_device_state module, we can see which state it was in.

AirDrop is one of the technologies that uses Bluetooth (also Wi-Fi), the AirDrop state is recorded and can be extracted by the powerlog_airdrop module.

Continuity [https://www.apple.com/macos/continuity/] is a technology to move data back and forth between devices. AirDrop makes use of this technology. This activity can be extracted by the powerlog_ids_messages module.

ids_messages.png

Grab APOLLO Here!

Start with Day 1: On the First Day of APOLLO, My True Love Gave to Me - A Python Script – An Introduction to the Apple Pattern of Life Lazy Output’er (APOLLO) Blog Series

On the Eighth Day of APOLLO, My True Love Gave to Me – A Glorious Lightshow – Analysis of Device Connections

$
0
0

Today we’ll be analyzing the knowledgeC.db and CurrentPowerlog.PLSQL database for various connections. The first thing you may want to know in an investigation is – was the device plugged in or not? This can be gained from a few places.

The knowledgeC.db database tracks this information and can be parsed out by using the knowledge_device_pluggedin module. This will keep track of the plugged in and unplugged states of the device and for how long each of those events were as calculated out in the ‘Usage in Seconds’ column.

Similar data is captured in the CurrentPowerlog.PLSQL database. The powerlog_lightnining_connector_status module extracts the same events, however I have seen in my own data some slight oddities, like the plug in/unplug events every minute or so – almost like the cable was loose (it wasn’t). Take that observation for what it’s worth, at least we can corroborate with other data!

powerlog_lightnining_connector_status.png

Another option is the powerlog_accessory_connection module. This one also appears to be more accurate but I’m not entirely sure what all “accessories” would be covered. My own data shows connections to power cables, this would include my CarPlay connection.

Speaking of CarPlay, we can extract that connection information using the knowledge_device_carplay_connected module. This output only has the initial connection, not the disconnect event.

knowledge_device_carplay_connected.png

Instead of physical connections, we may also be aware of wireless connections like Bluetooth. We can use the knowledge_audio_bluetooth_connected module to extract this information from the KnowledgeC.db database. This output contains the Bluetooth MAC address and name of the device. I’m obviously rocking out using my AirPods like a good Mac Fan Girl. 🤘🎶

Next on the Bluetooth list is the Apple Watch. The knowledge.db database also keeps track if the device is near the iPhone to which it is paired. The knowledge_device_watch_nearby module will show if I walked away from my iPhone for a certain period of time.

knowledge_device_watch_nearby.png

In the Powerlog, the paired Apple Watch information is stored. It not really in a log format but could be useful information. I have yet to determine the significance of the timestamp, it is not the initial pairing of the device. This can be extracted using the powerlog_paired_device_config module.

Finally let’s look at Wi-Fi connections. The Powerlog is keeping track of each SSID that my phone has connected to, but the name is a bit odd, I’m still researching why it is using this naming scheme, ideas are welcome. The “SSID” is alphanumeric and always same length. The powerlog_wifi_properties module will extract this data.

powerlog_wifi_properties.png

Grab APOLLO Here!

Start with Day 1: On the First Day of APOLLO, My True Love Gave to Me - A Python Script – An Introduction to the Apple Pattern of Life Lazy Output’er (APOLLO) Blog Series

On the Ninth Day of APOLLO, My True Love Gave to Me – A Beautiful Portrait – Analysis of the iOS Interface

$
0
0

The interface of the device can produce some useful artifacts. Starting with screen orientation. Perhaps you want to know if the user was watching a video for a period of time. In conjunction with other artifacts that I’ve already details like app usage the knowledge_device_orientation module will show if the screen was in landscape or portrait mode.

knowledge_device_orientation.png

The knowledge_device_is_backlit module will let you know if the display was backlit or not, this is different than if the device was locked or not – perhaps the user was just checking their messages without unlocking the device.

knowledge_device_is_backlit.png

Moving to the Powerlog, we can use the powerlog_device_screen module to see what “screen” the device was on. I’ve researched this one a bit and on my iPhone7 on iOS 11. These are the “screens” I was able to determine.

  • Homescreen(s) = 2 

  • Widgets = 19

  • Control Center = 5

  • Lock Screen = 9

  • Pin Unlock Screen = 15

  • Blank Screen = 0

  • App Switcher = 4 

  • Spotlight Search = 18 

  • Lock Screen Camera = 11   

  • Lock Screen Widgets = 17

powerlog_device_screen.png

Perhaps the how light or dark the environment is can help you in an investigation. The Powerlog stores the screen brightness. The lower the brightness, theoretically the darker the environment is where the device is, especially if the auto adjust feature is on. The powerlog_display_brightness module can output this data.

powerlog_display_brightness.png

The next two modules powerlog_springboard_aggregate_bulletins and powerlog_springboard_aggregate_notifications] are some modules that I’d like to research more. I believe these are the notifications that are presented to the user for each application. However, I don’t know yet what the differences between a bulletin and a notification yet.

powerlog_springboard_aggregate_bulletins.png powerlog_springboard_aggregate_notifications.png

Grab APOLLO Here!

Start with Day 1: On the First Day of APOLLO, My True Love Gave to Me - A Python Script – An Introduction to the Apple Pattern of Life Lazy Output’er (APOLLO) Blog Series

On the Tenth Day of APOLLO, My True Love Gave to Me – An Oddly Detailed Map of My Recent Travels – iOS Location Analysis

$
0
0

I saved one of my favorite topics for (nearly) last. There is no question that location can play a major role in many investigations. 

iOS location data as changed drastically with iOS 11 from previous iOS versions. I published research on these locations in the past and parsing scripts.

It is my goal to update these scripts with this new research soon(ish).

Powerlog Metadata

The CurrentPowerlog.PLSQL contains some useful metadata associated with the primary locations data I’ll discuss a bit later in this article.

The powerlog_location_tech_status module contains a log of how location was determined. Was the location determined by Wi-Fi or GPS technologies? This information can contribute to how accurate the location data may be.

powerlog_location_tech_status.png

The powerlog_location_client_status module appears to keep track of which applications and services are requesting location data. Some app examples below include Waze, Weather Underground, The Weather Channel, and the AUDI app. The services can be seen in the second screenshot (the data contained in this table was too long for only one!). 

The type of location is also recorded along with accuracy figures. I’ve seen the following types.

  • Location

  •  Significant (Likely has something to do Significant Locations)

  • Fence (Geofencing?)

  •  Visit

powerlog_location_client_status1.png powerlog_location_client_status2.png

Finally, we have a small log of providing time zone context to the data. The powerlog_timezone module will extract this information.

powerlog_timezone.png

Significant Locations & Routined Databases

As I’ve mentioned above, the storage of the routined process locations and Significant Locations has changed dramatically in iOS11 from previous versions.

These databases are stored in the following path and are only accessible in full file system dumps.

  •  /private/var/mobile/Library/Caches/com.apple.routined/

    • Cache.sqlite

    • Cloud.sqlite

    • Local.sqlite

Cache.sqlite - routined Locations 

The first database, Cache.sqlite, contains an extremely detailed history of coordinates where the device was. In my own data I had over 40,000 (!) data points. This data is stored for just over a week. This can provide a very accurate map of where I was during that last week.

The routined_cache_zrtcllocationmo module can extract these coordinates along with a timestamp, altitude, course, speed (meters/second), and vertical/horizontal accuracy figures.

routined_cache_zrtcllocationmo.png

Also kept for about a week is data extracted with the routined_cache_zrthintmo module. It has fewer data points, but the timestamp and coordinates appear to be accurate.

routined_cache_zrthintmo.png

Cloud.sqlite - Significant Locations - Visits

The next few modules all use basically the same query but are keyed off of different timestamps. The example shown is of the first module.

Again, this screenshot was split into two because of the amount of data provided by this table. Each significant location visit contains various timestamps (visit entry/exit, visit creation/expiration, learned place creation/expiration). Each visit has coordinates along with a Place ID (an identifier for a specific location), data points collected for that place, uncertainty and confidence figures, and device logging information. 

In the second screenshot there are two odd looking columns, Place Name BLOB and Place Geo BLOB. Each of these columns is storing BLOB data in hex format. I chose this format as it is easy (relatively) to copy/paste into a hex editor for viewing. Examples below.

routined_cloud_visit_entry2.png

The first column “Place Name BLOB” contains a smaller amount of binary data (than the Place Geo BLOB), and as you can see you can fairly easily determine where I was at this time – Dulles Airport (I’m a frequent visitor there as you can imagine.) You get address, city, state, business name information in this blob.

The second column “Place Geo BLOB” contains much more binary data, but you can still pick out some similarities in the strings.

So here is the kicker – for YEARS I just accepted these BLOBS, tried to parse them and was unsuccessful but didn’t care too much as I could always see the contents of them. While putting this article together I finally discovered their format – it’s a Christmas miracle!

I do lots of mobile work, that includes Android devices for a good portion of the time (Android, eww – I know, but it provides a paycheck. 😉) When I see random BLOBs in anything Android related my first inclination is to say it’s a Protobuf – a very Googly format. 90% of the time I’m right, I can usually spot them pretty easily. For some reason while looking at them now, my usual protobuf triggers just slapped me in the face so I gave the protoc a try (see the usage below.) 

protoc --decode_raw < binary_BLOB

It worked! I finally have a parsed data structure, granted some of the protobuf pieces I still need to determine but its certainly further than I’ve gotten before. Below is the protobuf output for the “Place Name BLOB”. Many of the strings are obvious, however the highlighted section is the coordinates for Dulles Airport. These are 8-byte floats stored in big-endian as shown in the hex editor below.

place_nameBLOB.png lat.png long.png

The “Place Geo BLOB” is quite a bit lengthier, too long in fact to create a decent screenshot of but still contains the string data and coordinates as expected.

Fun Fact – These protobuf data BLOBs are scattered throughout macOS and iOS systems, you can also see them in Maps data if you are looking for examples to play with. Those also appear to contain timestamps! I promise I’ll do a nice protobuf location blog in the near future. I love me some protobufs! (I’m weird, I know.)

Local.sqlite - Significant Locations - Locations of Interest

Ok back to Significant Location databases. There is one left, the Local.sqlite database. This contains similar data to what we’ve seen before. Timestamps, coordinates, confidence, uncertainty, data point count, and (protobuf!) BLOBS. As with the other modules, they query is basically the same but is using different timestamps to key off from. The example is from the first module. These screenshots are also from the same query, too long to post as a single screenshot.

routined_local_learned_location_of_interest_entry2.png

The last piece of location data I’m extracting from the Local.sqlite database is parking history. I connect my iPhone to my vehicle via CarPlay so I’m not sure if this is required to populate this data. The first module routined_local_vehicle_parked shows the last location of my parked car. 

routined_local_vehicle_parked.png

The routined_local_vehicle_parked_history module shows a parking history.

These modules should give you a pretty good idea where a certain user’s device was a given moment. It is worth mentioning the data does expire after a certain period of time, the sooner you have the data the better the data will be for you. Historically it appears to be pretty accurate but significant locations, but it doesn’t have every location. Dump that phone ASAP! 

Santa can easily find where you live. Creepy Santa.


On the Eleventh Day of APOLLO, My True Love Gave to Me – An Intriguing Story – Putting it All Together: A Day in the Life of My iPhone using APOLLO

$
0
0

I did a blog article, especially about the knowledgeC.db about a day in the life of my iPhone and it went over really well. I’ve decided to do a similar story using all the data that I’ve parsed from my iPhone using APOLLO, quite a bit more data to handle. For my device, I had 1.6 million rows!

Grab a holiday cocktail or a mug of eggnog and sit back and read the (quite boring) tale of my iPhone on September 16, 2018. This is the query I used for this day to filter it down from ~8800 rows.

query.png

On this particular day I was out celebrating my good friend Brian Moran’s Birthday at his house in Maryland. Around Midnight I decided it was time to leave and connected my phone to my car using CarPlay. The Device Status here shows the plugged in and CarPlay connections.

0_pluggedin.png

Next, I put in directions to “Home” in Apple Maps. I haven’t left yet, I’m still sitting in his driveway. You can see the SPEED is 0.0 in the Location output. Once I start to leave, you’d see that get populated.

1.png

During the drive I’m listening to Apple Music, in the Application Activity entries you can open these in the cell browser (depends on your SQL browser) to get more information than is seen in the screenshot row – some entries are very lengthy. Its late at night, good time for some dance music! 

3_rocking_out.png

I barely leave his house for five minutes before I receive a text from him in the Messages application (💕you Brian! 😂). Again, clicking the row for more information can be helpful. You can see how often I chat with a contact, over what application, and various related timestamps.

4_2.png 4_text_with_Brian.png

I message him back using Siri through CarPlay. The App Usage shows com.apple.assistant_service and com.apple.MobileSMS which is Siri dictation for the Messages application. Just after that you can partially see a Send Message Intent in Application Activity. The next Application Activity/Device Status is CarPlay switching back to my music.

Apple Watch data is sometimes activated during a drive – here you can see me getting my steps in while I’m clearly driving. 🤷🏻‍♀️

6_still_getting_steps_in.png

While my iPhone is connected to CarPlay, it is also charging. Note the BATTERY LEVEL increasing in the next two screenshots.

7_phone_charging.png 8_phone_charging2.png

I get close to home, so I turn off my Maps navigation. The Application Activity can be used to determine my navigation “to” and “from” locations. Redacted below.

A few minutes later I’m home and parked, I disconnected my phone from my car.

10_disconnected.png

I unlock my phone and start checking my Messages. You can also see some population of Significant Locations here as well.

11_sigloc_sms.png

I have an Orangetheory [https://www.orangetheoryfitness.com] class in the morning (later this morning, really), I better set an alarm. Also check to make sure I know what time the class is.

12_settimer.png

I plug the phone in before going to sleep.

13_pluggin.png

Early in the morning, I want to know what time it is so I tap the screen to check. Still plenty of time to sleep!

14_tapscreen.png

I’m awake and (somewhat) active - I unplug the phone.

15_wokeup.png

Of course, I need to check Twitter.

16_checktwitter.png

…and some other apps…

17_checkotherapps.png

…and more apps, while drinking my coffee. 

18_moreapps.png

Time to walk to the gym and start a workout. Once I select workout on my Apple Watch a couple of Health Workout Locations get populated with the coordinates of my gym. (Feel free to join me!)

In the middle of my workout I feel like I’m dying. 😵

IMG_3681.jpg

A bit later I check WhatsApp, good to see my heart rate go down a bit too!

21_whatsapp.png

The afternoon is filled with research on my laptop at home. You’ll see plenty of location data of me going absolutely nowhere (other steps recorded around my condo) – however if you check my knowledgeC.db on my laptop things would be a bit more interesting!

22_stayinghome.png

I’m playing with the LiberiOS Jailbreak.

Looks like I logged in somewhere else that asked me for my two-factor code. (I don’t even remember.)

24_twofactor.png

Check in my Fantasy Football team, not doing so awesome this year. 😬

25_fantasy.png

Getting to Sunday evening, I start determining what I have to do in the next couple days. What exercise classes did I sign up for, what do I have to do on the 18th?

Finally, I set an alarm to make sure I get up on time for my workout.

27_settimer.png

Grab APOLLO Here!

Start with Day 1: On the First Day of APOLLO, My True Love Gave to Me - A Python Script – An Introduction to the Apple Pattern of Life Lazy Output’er (APOLLO) Blog Series

On the Twelfth Day of APOLLO, My True Love Gave to Me – A To Do List – Twelve Planned Improvements to APOLLO

$
0
0

My Christmas gift to you - improvements!

  1. More Queries – There is plenty more to come. There are more databases and many half-written queries that I have yet to add.

  2. Additional Testing – I want these to be as accurate as possible.

  3. BLOB/Protobuf Parsing – More location information is useful.

  4. Plist Extracting – So much metadata that puts more context to the data.

  5. Database Coalescing – Those WAL files are important.

  6.  Data Visualization – Pretty pictures always help.

  7. Unarchiving of Powerlog Archive Files – Can’t forget about those archives!

  8. More macOS Coverage – I’ve been focusing on iOS, but there is some good macOS databases too.

  9.  Version Detection for Different SQL Queries

  10. Potentially Different Output Formats – Any special requests?

  11.  Better Module Documentation – Describe what each query is extracting in the module notes.

  12. Better Activity Categorization – More specific categories for better filtering.

Video of 'From Apple Seeds to Apple Pie' from Objective by the Sea - Now Available!

Network and Application Usage using netusage.sqlite & DataUsage.sqlite iOS Databases

$
0
0

Two iOS databases that I’ve always found interesting (and probably should test more) are netusage.sqlite and DataUsage.sqlite. These two databases contain very similar information – one is available in a backup (and file system dumps) the other only in file system dumps. These databases are excellent at tracking application and process network usage. 

These databases can provide answers to investigative questions such as:

  • What apps were being used?

  • What apps were used more than others?

  • Did the device communicate over cellular or wi-fi more often and when?

  • What apps were used that are no longer on the device?

These databases are located in the following locations depending on the type of acquisition available.

  • /private/var/networkd/netusage.sqlite

    • Available in File System dumps only.

  • Backup: /wireless/Library/Databases/

    • DataUsage.sqlite

    • DataUsage-watch.sqlite (yes, there is one just for the Apple Watch!)

  • File System: /private/var/wireless/Library/Databases/DataUsage.sqlite 

I’ve created modules for these databases in APOLLO, but you can also use the SQL queries in a standalone environment. I’m still working on how best to represent the timestamp keys and may alter the APOLLO code to accept multiple timestamp keys. This will help some other modules I’ve been working on as well so keep an eye out for that. I also need to work on acceptance of multiple database names, thanks to DataUsage-watch.sqlite.

The first set of modules are netusage_zprocess and datausage_zprocess. These two use the same SQL query as it is the same table, just different databases. These query extracts the process and/or the application bundle id. This query will show two timestamps:

  • TIMESTAMP – I believe this is the most recent timestamp for the process/application.

  • PROCESS FIRST TIMESTAMP – This appears to be the first usage of the process/application.

The first example comes from netusage.sqlite, the second from DataUsage.sqlite. It is notable to show that more information is available potentially from DataUsage.sqlite. Since this database is backed up it has the potential to have very historical data. These examples come from my iOS 11.1.2 dump. NetUsage goes back to November 4,2017 when I first setup iOS 11 on the device. The DataUsage database on the same device goes all the way back to 2013! This was from my iPhoneX which certainly did not exist in 2013. I restore backups onto new devices. I also get many more records from the DataUsage database.

netusage_zprocess

netusage_zprocess

datausage_zprocess

datausage_zprocess

The next set of queries are netusage_zliveproces and datausage_zliveprocess. These modules technically have a copy of the ZPROCESS data so they may be redundant if you are running APOLLO. Again, this is the same query for each database. DataUsage will again have many more entries. The added value from the ZPROCESS queries is the added network data information, Wi-Fi In/Out and WWAN In/Out. I will assume this value is stored in bytes until I can test further.

The major difference that I can tell between the two databases (apart from number of records), is that the DataUsage database does not record Wi-Fi network data. I know for sure I was on Wi-Fi at some point in the last six years! (It shows in NetUsage – remember it is the same device. Check out my Twitter data, its almost horrifying! 🤭)

netusage_zliveprocess

netusage_zliveprocess

datausage_zliveprocess

datausage_zliveprocess

Finally, we have an additional query only for the netusage.sqlite database, netusage_zliverouteperf. This query extracts lots of information, some of which I have no idea what it is. The first step into determining this is creating the query! In addition to some timestamps that appear to be stored on a per-hour basis we have the type of network traffic (Cellular or Wi-Fi), bytes and packings coming and going, connection information.

netusage_liverouteperf.png

A second screenshot is required to show the rest of the extracted data. Some sort of cellular network identifier (any ideas?) or Wi-Fi (SSID/BSSID) are provided, with additional network-based information.

There is a lot of data going through these pipes!

Apple Pattern of Life Lazy Output’er (APOLLO) Updates & 40 New Modules (Location, Chat, Calls, Apple Pay Transactions, Wallet Passes, Safari & Health Workouts)

$
0
0

I started filling in the gaps to missing APOLLO modules. While doing this I realized there was some capability that was missing with the current script that had to be updated. As far as script updates go the following was done:

  • Support for multiple database name -Depending on the iOS version being used the database names may be different but the SQL query itself is the same. Instead of creating many redundant modules I now have it looking for the different database filenames.

  • Support for multiple queries on different iOS versions- You will now notice that all the modules have been updated with iOS version indicators and multiple SQL queries compatible for that version. Some going back as far as iOS 8! I put in as much legacy support as I had data for. I will likely not add much more unless it is by special request. I can’t imagine there is a whole lot of iOS 8 analysis going on out there, but you never know! I have kept it to major iOS release numbers and have tested with the data I have but it may have changed with a minor point release, if you find this to be true please feel free to let me know!

  • Module Timestamp Rearrangement and Module Cleanup– I’ve started to go through some of the modules and move the items around to make it easier to see what is going on with each record. I’ve mostly just moved the timestamps toward the end since most of them are shown in the Key column. I’ve also removed some superfluous columns and extraneous junk in the queries. I’m really only trying to extract the most relevant data. 

A few notes on script usage change. The script flags have changed, with the added arguments of -p = platform (iOS support only for now), and -v = iOS Version. You may also notice the new ‘yolo’ option – this one will likely be error prone if you are not careful. Use this when you what to run it on any database from any platform. It can also be used with your own custom modules if you don’t have versioning in them.

An example of the module changes is below. Notice the multiple databases listed. In this example, the same location data can be extracted from the cache_encryptedB.db or the cache_encrypted A.db databases depending on the iOS versions. The version information is listed in the “VERSIONS” key, while the specific queries have versions listed in the [SQL Query …] brackets, this is the version that the apollo.py script is following.

The big updates were with the modules, lots of new support! I now have support for 129 different pattern-of-life items! Most of the support is for iOS, however if you run the queries themselves on similar macOS databases you will find that many of them will work. Better macOS support is coming, I promise.

Application Specific Usage:

  • Chat – SMS, iMessage, & FaceTime messages extracted from the sms.db database.

    • sms_chat

  • Call History – Extracted from CallHistory.storedata database.

    • call_history

  • Safari Browsing – Extracted from the History.db database.

    • safari_history

  • Apple Pay/Wallet - Extracted from iOS passes23.sqlite database.

    • Apple Pay Transactions - passes23_wallet_transactions

    • Wallet Passes - passes23_wallet_passes

 Location :

  • locationd - The following modules extract location data from the [lock]cache_encryptedA.db & cache_encryptedB.db databases. This will include various cellular and Wi-Fi based location tables as listed in the module filename.

    • locationd_cacheencryptedAB_appharvest

    • locationd_cacheencryptedAB_cdmacelllocation

    • locationd_cacheencryptedAB_celllocation

    • locationd_cacheencryptedAB_celllocationharvest

    • locationd_cacheencryptedAB_celllocationlocal

    • locationd_cacheencryptedAB_cmdacelllocationharvest

    • locationd_cacheencryptedAB_indoorlocationharvest

    • locationd_cacheencryptedAB_locationharvest

    • locationd_cacheencryptedAB_ltecelllocation

    • locationd_cacheencryptedAB_ltecelllocationharvest

    • locationd_cacheencryptedAB_ltecelllocationlocal

    • locationd_cacheencryptedAB_passharvest

    • locationd_cacheencryptedAB_poiharvestlocation

    • locationd_cacheencryptedAB_pressurelocationharvest

    • locationd_cacheencryptedAB_scdmacelllocation

    • locationd_cacheencryptedAB_wifilocation

    • locationd_cacheencryptedAB_wifilocationharvest

    • locationd_cacheencryptedAB_wtwlocationharvest

  • locationd – These modules extract motion data from the cache_encryptedC.db database. Not specific location data but will show device movement.

    • locationd_cacheencryptedC_motionstatehistory

    • locationd_cacheencryptedC_nataliehistory

    • locationd_cacheencryptedC_stepcounthistory

  • routined – Extracts location data from the cache_encryptedB.db database. If you have a keen eye you will notice the database name is the same as from ‘locationd’. Completely different database with different data stored in two different directories.

    • routined_cacheencryptedB_hint

    • routined_cacheencryptedB_location

Health Workouts – Using the healthdb_secure.sqlite database I’ve extracted much of the metadata from workouts. I’ve also determined some of the workout types (ie: HIIT, Rower, Run, Walk, etc), but have not enumerated all of them yet. Please let me know if you come across others – easier if you do this on your own data and can easily look it up. Same for weather conditions (Sunny, Rainy, etc.).

  • health_workout_elevation

  • health_workout_general

  • health_workout_humidity

  • health_workout_indoor

  • health_workout_location_latitude

  • health_workout_location_longitude

  • health_workout_temperature

  • health_workout_timeofday

  • health_workout_timezone

  • health_workout_weather

Viewing all 113 articles
Browse latest View live