analysis

Part 3: Step-by-step Tooling for iOS Research (via @bizzybarney)

This is the third and final piece of the Mac and iPhone setup process!  Sorry for the long delay between the last one and this one, but better late than never right?

giphy-3.gif

This guide will help you setup your iDevice with two binaries that can greatly assist with targeted testing and analysis.  My goal is to equip you to do your own research and testing to confidently answer the questions you will surely have as you learn this beautiful dance we call DFIR.  If you currently rely on a commercial tool to extract your iDevice data and then parse the data for you, that is totally normal and this article is absolutely for YOU!  Years ago, @iamevltwin broke my thought process on how to address mobile devices.  My training and education up to that point was great, and I knew a LOT about mobile devices and strategies for finding the evidence I was looking for.  But….I relied on data extraction methods by commercial tools and mostly parsing by commercial tools as well.  While that is acceptable and perfectly fine to do, it can be very time consuming.  Trust me when I say, if @iamevltwin asked me a question, and my response was “I’ll let you know in a few hours”…she would probably throw a steak and cheese egg roll at my head. [*Editors Note: I would never waste a delicious steak and cheese egg roll, instead I would deeply judge and give him the side eye.—S]  So for the sake of never wanting to waste a good egg roll, I learned how to target just the data I want and address it in a very specific way.  

To summarize what we are about to do:

  1. 1. Install and run “fsmon” and “cda” binaries that already have proper entitlements, so you don’t have to make the files.

  2. 2. Very basically learn what they do and how to run them.

  3. 3. Use them to target a specific piece of data on the iPhone.

  4. 4. Extract that specific piece of data to my desktop so I can “GET SHIT DONE” 

**If you are reading this, please make sure you have read and followed the instructions for Part 1 and Part 2 .  If you are jumping in here and trying to follow along, I assume your Mac and iDevice are the same as mine from the end of Part 2.  It is strongly advised that you do this on a secondary, test / research device and not your primary use device.  Nothing we are doing here should break anything, but things happen when you are in a root shell into your device and you have been warned!.**

Download iOS Binaries

I have both binaries you will need already made and entitled, trying to make this process as easy as possible to get you setup for testing!  The link below will take you to a .zip file containing ‘cda’ and ‘fsmon’, which are both Mach-O 64-bit ARM executables.  

The ‘cda’ binary helps locate where an app is storing it’s data! iOS stores most app data behind randomly generated GUID’s in the file system, so finding where a certain app is storing its user data can be a real pain.  This binary makes quick work of telling us exactly the directories we need to pay attention to, and does so in seconds.

The ‘fsmon’ binary is a file system monitor.  Plain and simple, it prints to your screen the changes occurring in the file system.  For research purposes, this is priceless.  If you need to know what happens when you take a photo, send an SMS, install an app, etc. you can run ‘fsmon’ while pressing the buttons on your device and watch your screen light up with what changed!

1. Click this link and download the .zip file. (Not (knowingly) malware, I promise!)

If you want to do it yourself, or are simply curious about what you’re downloading - here are the links to the GitHub repo’s where I got them:

  • cda - “A simple iOS command line tool to search for installed apps and list container folders (bundle, data, group). Thank you, Andreas Kurtz!!

  • fsmon - A file system monitor. Thank you, Sergi Àlvarez & Nowsecure!!

2. Now that you have the binaries, we will put them into a folder on your Desktop for simplicity.  Create a folder on your Desktop named ‘binaries’ and move the .zip file there.  Unzip it so the two binaries are in the ‘binaries’ folder.  It should look like this:

Connect to Test iDevice

Now that we have the files we need, we need to make sure our iDevice is connected to our Mac via USB and we are able to communicate with it.  Following the instructions from the Part 2 article, get connected to your iDevice via USB.  I’m going to show my actions below but if you have any trouble, go back and make sure your system is setup correctly from the previous articles.

My test device is an iPhone X (A1865) on iOS 14.2 that is jailbroken with checkra1n.

1. Open Terminal window on Mac.  Type iproxy 4242 44 and press return.  (If you’re on a device using unc0ver jailbreak you might need to use port 22 instead of 44).

2. Still working within your Terminal window, press command+T on the keyboard to open a new Terminal tab.  In the new tab, type ssh root@127.0.0.1 -p 4242 and press return.  You will be prompted for your password to access the device via SSH.  If you haven’t set a unique password, your default password is alpine.  Nothing appears when you type, so type your password and press return.  You should then see some version of a bash prompt with a # like in the screenshot below:

You’re now essentially in a CLI (command line interface) on your iPhone via your Mac.  What does this mean?  Well, it means you should be careful.  There isn’t an operating system lifeguard to keep you from removing files and directories you didn’t intend to.  If you aren’t familiar with navigating via CLI, that’s ok, do some research.  Look for a Mac Terminal cheat sheet online to expand your knowledge, but I’ll try to be very descriptive with the commands we use here.  

If you’re keeping score, we now have one Terminal window open that we used to iproxy into the iPhone.  We won’t use that window again unless our connection fails and we have to start it up again.  Your second Terminal tab should be a shell into your test iPhone.  

3. In the tab with the shell into your iPhone, type pwd and press return and it will show you your current directory or “Print Working Directory”.  We can see that we are in the directory /var/root.  Now type ls -la and press return to list the files in the current directory you are in.  

**For any of the CLI utilities we use in this exercise, in a Mac terminal shell you can type man <name_of_utility> and press return to see the manual for it, with all of the available flags you can use.  For example, if I wanted to remember how to use ‘ls’ to recursively list all the files in a directory and subdirectories, I would type man ls and press return.  Using the man page, I could see that using ls -laR will (l) list long format, (a) revealing directory entries beginning with a dot (.), (R) and the recursively list subdirectories encountered - respectively.  To leave a man page, just press Q and it will jump back out to your Terminal shell.**

Copy Binaries from Mac to iPhone

Now that we have the files downloaded and on our Desktop, and have a shell into our iPhone - we can move the files onto the iPhone.  

1. From your Terminal shell into your iPhone, press command+T again to open a new Terminal tab.  This new tab is a shell on your Mac, not the iPhone.  Click into the newly opened Terminal tab on your Mac and type the following: scp -P 4242 ~/Desktop/binaries/cda root@127.0.0.1: then press return.  You will be prompted for the password to access the iPhone - not the pin to unlock it, but instead either alpine or the unique password you set if you changed it.  Enter the password and press return.

We are using ‘scp’ to “secure copy” or remotely copy a file between our host Mac and our connected iPhone.  The command we typed and entered would more literally read: “scp (secure copy) -P (port) 4242 (port number) ~/Desktop/binaries/cda (a file named cda located at /Users/<your_username>/Desktop/binaries/) root@127.0.0.1: (root is the username and 127.0.0.1 is our localhost and you have to have the : at the end!).

If it worked successfully, you should see this:

2. To be super, extra sure it worked, you can check the list of file present on the iPhone.  Click into the Terminal tab that is the shell into your iPhone.  Type ls -la again and press return.  Assuming you didn’t leave the /var/root directory, you should see a list of the files present at the root of the file system and you should now see ‘cda’ in your list.

Yay!  One down, one to go.  Let’s do it again but this time let’s send ‘fsmon’ to the iPhone.

3. Click back over to your Mac Terminal tab we just used to send the ‘cda’ file to the iPhone.  We are simply repeating the same thing we just did, but for ‘fsmon’ this time.  Type scp -P 4242 ~/Desktop/binaries/fsmon root@127.0.0.1: and press returnEnter the password and press return.

4. That should work pretty cleanly if the first one did, but let’s check to be sure.  Click into the Terminal tab that is the shell into your iPhone.  Type ls -la and press return.  You should now see ‘fsmon’ in the file list as well.

If you see both files, feel free to pour yourself your favorite beverage and sip that for a moment.  You might need it for the next part..

5. The next thing we are going to do is copy these binaries to a different directory on the iPhone.  Assuming you’re following the directions explicitly, you should still be in /var/root on your iPhone, which is where both binaries should be.  In that shell, type cp ./cda /usr/bin/ and press return.  Nothing appears to happen, but we just copied the ‘cda’ file to the directory /usr/bin/.  Let’s quickly do the same for fsmon, type cp ./fsmon /usr/bin/ and press return.

6. Now that we copied them to the /usr/bin/ directory, lets go there and check it out.  To change directories, we will use ‘cd’ and then simply type where we want to go.  Type cd /usr/bin/ and press return.  Then let’s check this directory and make sure our files copied here correctly.  Type ls -la and press return and you should see a longer list of files here, but make sure you see ‘cda’ and ‘fsmon’.  If you see both, give yourself a high-five for making it this far.  We are now one step away from being able to use these things!!

7. Ok, we now have the binaries where we want them, but we have to give them permission to execute on our device.  Type chmod +x cda and press return, and then type chmod +x fsmon and press return.  You shouldn’t get any visible or affirmative response to entering the command, but we just set both binaries so they can execute, or run on your device.

The Moment of Truth - Do the Binaries Work?

Alright, this is it.  This is the moment where you are going to fist pump and exclaim for joy - or cuss, kick things and go back through the instructions above and figure out what you did wrong.  Let’s hope for shouts of joy.  We will start with ‘cda’ because it is going to tell us which directories we might want to run ‘fsmon’ on to monitor activity.

1. Type cda safari and press return.  I picked Safari because pretty much every iDevice you might be doing this on has it and should yield a result.  You should immediately see results populate on your screen.  My device displayed two different results for the native Safari application, one for com.apple.SafariViewService and the other for com.apple.mobilesafari.  Both results are quite typical for any application you might search for, it commonly displays a path to the Bundle, the Data, and Group (if one exists).  We aren’t going to get too deep into the details of explaining these three paths, but generally, here’s a synopsis:  

  • Bundle - This path is where the actual application files exist.  The code that is the application itself, but not the user’s data.  You can find language packs, plugins, and other stuff here but unless your goal is to reverse engineer the application - you probably don’t need to spend any time here.  Think of these files as the files that are downloaded when you install an application, so it appears on your device - but you haven’t opened it and interacted with it yet so no user data has been generated.

  • Data - Go here.  You want to go here.  User data exists here.  Every application you locate using ‘cda’ will have a Data path.

  • Group - Yeah, you’re going to want to go here too.  User data exists here too.  Not every application uses a ../Shared/AppGroup/ directory to store user data.  Don’t be concerned if you don’t see a Group path for an application, but you also cannot ignore one if you see one.  Some applications store the juicy goodness here!

(Optional) Now that we know ‘cda’ is working, I’m going to use it once more, but this time to address a third party application - Google Voice.  You may not have Google Voice, but feel free to use ‘cda’ to search for a third party application if you have one!  I wanted to show this to you so you can see more than one example of ‘cda’ because it tells us exactly where we need to look to do our research!  In the photo below, you can see I typed cda google voice and pressed return and it displayed a bundle, data, and two different group paths to data for Google Voice.

2. Alright, we are moving on to a pointed example of using ‘cda’ to appropriately leverage ‘fsmon’ to GET SHIT DONE!  But, we first have to make sure ‘fsmon’ is going to work for us.  This binary is simple to use, we just have to start it and tell it which directory we want it to monitor.  One thing I have learned from using it is the less you monitor, the easier it is to see what’s going on.  Before I tell you how to start it I’m going to tell you how to STOP IT!  You will press control+C to stop it after it’s started.  

3. To make sure it’s working, type fsmon / and press return.  This is running the file system monitor on the root of the file system.  (**If you get an error, you might have to type /usr/bin/fsmon / to get it to work.)  As soon as you press return to start ‘fsmon’ just open any app on your phone such as Settings, Mail, whatever it doesn’t really matter.  You should see your screen light up with file system creation, modification, and deletion entries.  Your output is definitely going to look different than mine, that’s expected.  Press control+C and stop it.  Hopefully that worked nicely for you like it did for me, and you can now start to play with it and develop strategies for using it.

Now I’m going to walk you through one approach to using these binaries to target specific data, and then we are going to extract that data from our iPhone out to our Desktop.  

1. I am choosing to install the application, Viber Messenger: Chats & Calls, and I will use ‘cda’ to tell me where it stores data, then use ‘fsmon’ to try to see the results of a specific action.  I navigated to the App Store on my iPhone and searched for Viber, then pressed GET to install it onto my device.  (If you’re wondering, yes, you could technically be running ‘fsmon’ while doing all of this to see what’s happening on the file system!)

Alright, I have Viber installed.  But…before I open it I want to get setup to see what it’s doing.

2. In your shell into your iPhone, type cda viber and press return.  I see that Viber returns a path to its Bundle, as everything will.  It has a Data path, as everything will, but also has one Group path that I need to pay attention to.

Now that I know where Viber might store user data, I am going to monitor the Data path only.

3. For my installation of Viber, the Data path is /private/var/mobile/Containers/Data/Application/FAE649F5-56EB-4859-A4FB-BD88616720DE.  To monitor that path while I setup the application, type fsmon /private/var/mobile/Containers/Data/Application/FAE649F5-56EB-4859-A4FB-BD88616720DE and press return.  Once it is up and running, open the app and set it up.   As you can see in the image below, the file system goes crazy while I start to setup the application, but I’m seeing everything happening.

**If you wanted or needed to monitor the Group path too, you could simply open a new Terminal tab, and open another shell into your iPhone (ssh root@127.0.0.1 -p 4242, return, enter password, return) and run ‘fsmon’ on that Group directory too.**

Ok, you setup the app, and did whatever actions you wanted and you watched it all printing to your screen thanks to ‘fsmon’ doing an amazing job.  I hope you can see how this can assist you in doing research, and quickly honing in on pertinent files and folders as you work.  You make a specific action, and quickly go look at that file and find what you’re looking for.  Make sense?  Easy right?  Let’s target the Viber data and extract it out to our Desktop so we can quickly investigate it!

From the output for ‘cda viber’ I need to get the contents of the Data and the Group paths.  I’m not going to get the Bundle path…ever.  But for the example I’m about to show you below, your paths are going to differ from mine.  If you installed Viber to follow along, your path is not the same as mine, so you will have to copy your Data and Group paths and follow the template I’m giving you to achieve the same outcome.

4. Go back into Terminal but click over to the shell of your Mac, not the iPhone tab.  We are going to use ’tar’ via SSH to make a .tar of the Data and Group directories for Viber on our Desktop.  

In the Mac Terminal shell, type ssh root@127.0.0.1 -p 4242 ‘tar -cvf - <paste_path_to_Data> <paste_path_to_Group>’ > ~/Desktop/Viber1.tar and press returnEnter the password for SSH access to your iPhone (alpine or what you changed it to)  and press return.  You should see a long list of files populate on your screen and you should have a new file on your Desktop named Viber1.tar.

**We preserved timestamps for the data with this .tar command, so if you care about timestamp integrity make sure manage the data you extracted as READ ONLY to not update the timestamps each time you open a file.**

I pasted the exact text I typed into my Terminal window to successfully copy this data out to my Desktop below (to clarify any spaces or issues with the command above):  

bizzybarney@MacBook-Pro ~ % ssh root@127.0.0.1 -p 4242 'tar -cvf - /private/var/mobile/Containers/Data/Application/FAE649F5-56EB-4859-A4FB-BD88616720DE /private/var/mobile/Containers/Shared/AppGroup/1195ECFB-4F5B-4BC0-9E7F-490418D1651C' > ~/Desktop/Viber1.tar

You now have all of the files and folders attributed to Viber’s Data and Group paths on your Desktop.  Crack that thing open and dig in!  You have successfully extracted these files without using any commercial tools to extract a bunch of other data you don’t need or care about, and can start into examining your results in seconds without need to wait for any lengthy parsing process either!  You can easily go back into Viber and take more actions that create new data, then pull these files again and just change the output filename to Viber2.tar or whatever you choose.  If you are doing a full teardown of an application, don’t be surprised if you have pulled the data dozens of times, each time learning a bit more about how the data is being stored.

In the image below, you can see the Data and Group (../Shared/AppGroup/) files and folders for Viber, and I can quickly open the Preferences - com.viber.plist and see the user phone number I entered during setup!

Feel free to practice with the steps outlined above on different applications, and target their specific data.  Also, don’t forget about the native iOS files in /private/var/mobile/Library/ on your iPhone - we can monitor those directories as well and there is an insane amount of awesomeness there!

If you followed all of these steps and arrived here successfully, congratulations!! I know this setup is taxing, and especially difficult if you’re just starting out in CLI.  I hope I can offer encouragement by saying it wasn’t so long ago that I was doing this for the first time.  After lots of practice, failures, and cussing - I am now able to find the data I want to research using ‘cda’, watch the file system with ‘fsmon’, then ‘tar’ out the data I want in just minutes.  

Thanks again to @iamevltwin for hosting this content! Also a huge thanks to the people developing and supporting unc0ver, checkra1n, cda, and fsmon - you make this type of research possible!

Please contact me on Twitter @bizzybarney with any questions or concerns, and I will help as I have time.

Until next time, “Stay classy, forensicators.”

giphy-2.gif

Analysis of Apple Unified Logs: Quarantine Edition [Entry 11] – AirDropping Some Knowledge

I’ve written about this before in this article but wanted to revisit it for this series. For this scenario I want to test what certain items might look like when they are AirDrop’ed from an unknown source. Many schools have been receiving bomb threats via AirDrop, I want to see if there is a way to discover where they originated from.

In my testing you will see artifacts from two iOS devices:

  • Sender: Elwood’s iPhone

  • Receiver: miPhone11 

Note: This article focuses on iOS. For macOS you will likely have to add --info to these queries to acquire similar information.

Starting with the AirDrop basics – we need to determine the AirDrop ID for each user. One thing I’ve discovered since my last analysis was that the AirDrop ID is not consistent for the life of the device, it changes all the time! The last (current) AirDrop ID can be found in the /private/var/mobile/Library/Preferences/com.apple.sharingd.plist on iOS devices. I’ve even seen where there is no AirDrop ID in this plist due to AirDrop inactivity. The following query can provide the Airdrop IDs that are still available in the unified logs.

log show system_logs.logarchive --predicate 'eventMessage contains "AirDrop ID"'

We may also want to know what Discoverability Mode was being used at the time. A quick query for this is to look for ‘SharingDaemon’ which contains some sharingd metadata information.

log show system_logs.logarchive --predicate 'eventMessage contains "SharingDaemon State"'

These messages contain a few useful items:

  • Device make/model

  • iOS Version

  • Battery Status

  • Discoverability mode (Everyone, Contacts Only, Off)

  • Screen Status

  • Unlock Status

  • Wireless Proximity Status

In our contrived scenario we are assuming the receiver has their discoverability mode set to ‘Everyone’ during the time in question. The current mode can also be seen in the com.apple.sharingd.plist file. One more way of seeing the discoverability mode is by using this query (yes, I accidentally put in two --info arguments, this of course is not required):

log show --info system_logs.logarchive --predicate 'eventMessage contains "Scanning mode"'

On the Sender Device (Elwood’s iPhone):

Sharing Methods 

The first indication of AirDrop usage is how it is being initiated. This process is known as the ‘ShareSheet’. This is the window that is presented to the user to choose how they want to share an item. In this screenshot, I want to share a photo from within the Photos app. We can choose AirDrop, Messages, Mail, Notes, etc. Below that is a set of other activities that can be performed on the chosen photo.

This query can show us what application an item is being shared from. Each shared item may have different sharing options. This blog will show activity while AirDropping a photo, a note, a map, and a Safari link. 

log show system_logs.logarchive --predicate 'category = "ShareSheet" or category = "SharingUI"'

Starting at the top, a good indicator that something is about to be shared is to look for the message ‘Activating com.apple.sharing.sharesheet’. A connection will be made with the specific app that is to be shared from, in this example com.apple.mobileslideshow (Photos).

The items highlighted in red are looking for people to share with. This particular device is a test device with no contacts; therefore none were suggested. 

The items highlighted in purple and blue show the Share and Action activities that the user should see in the ShareSheet view.

In green, the “performing activity” message shows that AirDrop was selected by the user.

In pink, messages that start with “Item:” and have a GUID show that photos need a bit more preparation (file conversion, thumbnail creation, etc.). This was not seen in shared notes, maps, and Safari links. This specific activity can be filtered by using the GUID as shown below. The items highlighted in dark green provide temporary file paths used for the preparation but most importantly a filename that should be consistent with the item filename in the Photos.sqlite database (IMG_6782.JPG).

log show system_logs.logarchive --predicate 'eventMessage contains "74745469-9184-442C-B49D-5BE37CDD8CAA"'

More examples sharing methods of an AirDropped Note, Map, and a Safari Link are shown below. Notice the differences in the activities for each application. 

Note

Map

Safari Link

AirDropping an Item

Just because we see something was attempted to be shared, does not necessarily mean it was actually sent and received. The first part of this process is finding someone to AirDrop something to. I will be using the following query to go through some of these entries. 

log show system_logs.logarchive --predicate 'category = "AirDrop"'

In the screenshot above I’ve changed the default style to compact [with --style] to fit more in the screenshot. This shows the iPhone attempting to discover known and unknown contacts via Bonjour and AWDL. Highlighted are the entries that find my MacBook Air (Airdrop ID: eb4f5a53391b). Note the AWDL IPv6 addresses shown in yellow. These do appear get cached on the receiving end (look for messages that contain “com.apple.p2p: Caching peer:”). It appears AWDL IPv6/MAC addresses get rotated fairly frequently. These is another way of pairing two each device together (along with AirDrop IDs) but these are not kept forever and you need both devices to do this analysis.

Now that we have AirDrop contacts, lets send a photo! I sent a photo from Elwood’s iPhone to miPhone11 (IMG_6782.JPG) via Photos.

The message that start with “startSending” (in yellow) is what is being AirDrop’ed. It shows the item or file that it is sending along with the Receiver ID and Session ID. The Receiver ID is the AirDrop ID for the device that this item is being sent to, while the Session ID keeps track of this AirDrop session.

In green, the AirDrop transaction is started, however in dark green it shows that a connection cannot be made. During my testing, my miPhone11’s AirDrop ID got caught in an odd cached state with the wrong ID (3603f73a17de). The first time I attempted to AirDrop this photo it failed. It eventually discovered the correct ID (ecec57b722d8). Elwood’s iPhone showed a ‘Waiting…’ message and the transaction would not complete.

The second time around it actually sent. Note the changed AirDrop ID for miPhone11 is now 04f30cbdcb55. These IDs change all the time. It also recognizes the device can handle a live photo in an HEIC file format, so it sends that instead of the JPG.

The ShareSheet information for the Live Photo is below. I recommend matching up the GUIDs to find this information. Filtering for 6C85AC86-BEF2-42BC-9862-4982211791DF (from the screenshot above) would allow me to run the query below to find the rest of the actions associated with this asset.

log show system_logs.logarchive --predicate 'eventMessage contains "A79A3C4F-AF63-486E-A7FC-4173753B12E2"'

A few more AirDrop examples, a note, a map, and a Safari link.

Note

These entries show a note with the title ‘This is a threatening note!’ was shared but no contents of the note itself.

Map

Sharing a Map item, provides title but no exact address in this example.

Safari Link

Sending a Safari link shows the domain but no specific details on the URL. 

The same Safari link as a PDF file:

Sending the same link but as a PDF shows no domain at all.

These items lose context when only the unified logs are looked at. You may have to correlate these actions with other application databases and artifacts (Photos, Notes, Maps, Safari History, etc.) to provide this context.

On the Receiving Device (miPhone11):

We will be using a generic AirDrop query to find all entries associated.

log show system_logs.logarchive --info --predicate 'category = "AirDrop"'

A user receiving files can choose to accept or decline. These responses are documented in the unified logs.

For an incoming transfer an AirDrop connection is made with an identifier (0x101495960). After this entry there are quite a few lines detailing what type of file it is and where it is coming from. To know if the user has Accepted or Declined the transfer we need to focus on the ‘userResponse’ sections. The entry shown in green is the popup alert that is presented to the user to do this action.

Once the user has selected ‘Accept’, the transfer continues and is opened up in the default application for the file. This example shows the photo being imported and opened in Photos (com.apple.mobileslideshow). Once complete, the AirDrop connection is terminated. This photo could be found by looking for the “16C753E1-309A-46FD-A742-998D7A31047E” ZUUID in the ZGENERICASSET table of the Photos.sqlite database and looking for the associated file name.

If the user declines the AirDrop transfer the same message would show Declined or Cancelled and the AirDrop connection is terminated. 

How about an all-in-one query to tell me what transfers were initiated, from whom, where they Accepted or Declined, and opening information.

log show system_logs.logarchive --predicate 'category = "AirDrop" and (eventMessage contains "New incoming transfer" or eventMessage contains "Opening URLs:" or eventMessage contains "alertLog: idx:")' --style compact

Each of the gray highlighted sections is an incoming transfer from Elwood’s iPhone. Some transfers have an ‘Opening URLs’ entry that provides more context to what was sent, especially when it comes to Map and Safari links. It should be pointed out that just because you see a hostname like Elwood’s iPhone to be careful with attributing it to Elwood. Device hostnames are incredibly easy to change to let’s say…’Jake’s Google Pixel! 

I spent ages trying to come up with a smoking gun on a ‘victim’ device to attribute an AirDrop action to a specific sender device. There really does not appear to be a static identifier to be able to identify a specific address. AirDrop ID, AWDL IPv6/MAC addresses are the only way to pair these actions between devices but you need both devices to be able to do this type of correlation. This, of course, can be tricky in most investigations. Even if you do have access to the devices, the data gets flushed fairly quickly – you may only have a few days to acquire these logs.

Analysis of Apple Unified Logs: Quarantine Edition [Entry 9] – We all know you're binging Netflix! Now Playing on your Apple Devices!

We’ve been trapped inside our homes for months. We’ve reached the end of Netflix, listened to everything on Apple Music, watched old vacation videos trying to remember what travel was like, and mindlessly browsed YouTube videos. All these actions have been recorded in your unified logs!

I came across this one while researching another topic and thought it might be useful and a quick write-up. Turns out it wasn’t as quick as I had hoped – so many different scenarios to test! I’d still like to dig into this one a bit more as it can be quirky as noted in the last section. While sometimes odd, I think this information can provide insight into what media a user is viewing on their systems - not just macOS, but iOS as well. 

The query below will show information related to media that is “Now Playing”, not just on the computer that the logs came from, but also potentially other AirPlay connected devices. There will be many entries but we will only focus some in this article.

log show --predicate 'category = "MediaRemote"'

Movie time in the Photos.app

Gather the family and start reminiscing over vacation videos. You might bring up Photos.app and search for various videos that you were going to show all your friends and family (and never actually did, but you just HAD to get that video.) 

In the screenshot below, the ‘MediaRemote’ is what we are filtering on in the query above (highlighted in yellow). 

Various pieces of data get recorded in the unified logs. In many entries you should see the bundle id or application name being used – in this example Photos or com.apple.photos. A good keyword to look for is “client-“ before the bundle id for the app.

You can also see two sections that contain media metadata that includes:

  • Media Duration (in seconds)

  • Elapsed Time – We can use this to determine how long it was viewed/listened to.

  • Item Identifier (GUID) – This GUID changes over the period of viewing so not a great filter for a specific file. It will change if media is stopped, paused, etc.

  • File Path & Name

This video is 10 seconds long, using the elapsedTime entry we can see that it was played all the way though.

The file path is in the user’s Photos Library package directory which is not surprising. This filename however, is not the original filename of this video. We can use ‘xattr -p’ to print the extended attribute that contains this data (com.apple.assetsd.originalFilename). Using the original file name IMG_3586.MOV we might be able to do a search across the system to find other artifacts of its use and more metadata in the Photos.sqlite database including a running count of how many times it was played.

MOV Files in QuickTime

Maybe you don’t use Photos.app, instead you downloaded the movie to your macOS system and viewed it using QuickTime player (com.apple.QuickTimePlayerX). Many of the same metadata pieces are still there but the filename might look strange to you. This is a good example of a “File Reference URL”. This is the same video I used as the example above. I exported it out of Photos using the original filename, IMG_3586.MOV and saved in the Downloads directory.

In the screenshot above the elapsed time is 00:00:00, and duration is 00:00:10 (10 seconds). Below, the elapsed time is 00:00:05 (5 seconds, actually closer to 6 if we round up.). I started the video, watched ~5 seconds and played out the rest of the video (these additional entries are not shown.) The playback rate entry appears to be a 1 while playing and a 0 while stopped/paused. A GIF of this action was recorded below. Featuring a playful elephant at the Taronga Zoo in Sydney.

Getting back to that “File Reference URL”, you probably want to find the original file as part of an investigation. We can use the inode section of the URL to find it. In this example I renamed IMG_3586.MOV to elephants.mov. Most forensic tools should be able to query for a file system inode number. Inode numbers do not change when a file gets renamed.

Finding a sense of calm with Music.app

I queued up a new album by one of my favorite classical musicians, Ludovico Einaudi. An Italian, who created this album while in quarantine at his home in Italy. The album includes 12 songs, and one video (not shown in the screenshot.)

We can see the queue count for Music (com.apple.Music). While I listen to this album, it will tick down, one-by-one.

Finding the End of the Internet

To get a few laughs, I used Safari browser to watch clips of Archer on YouTube. Safari is not listed as the application, but com.apple.WebKit.WebContent is – this is a signature of Safari WebKit being used. Surrounding entries (not shown) will show hints that Safari.app is being used as this time.

In Chrome, I went to watch videos on the BBC and found this excellent video of a dog who helps rescue Koalas in Australia (running theme? 🤔). We can see the Google Chrome (com.google.Chrome) app is being used, but it may not necessarily state the website. You may have to determine this using other user activity artifacts (browsing history!).

What about AirPlay?

The media examples above were all viewed on a local macOS system, what would it look like if I used my extensive Apple ecosystem of devices? Might as well use these devices for “research”, right?

While doing this research, I was watching one of my favorite older television shows, Alias using Amazon Prime Video (com.amazon.aiv.AIVApp) on one of my Apple TVs. Every episode that it would run though would show entries on my Mac. My Mac had nothing to do with my binge watching, but the entries were recorded anyway…cool! I should note that if the system is not being used (laptop shut), these entries do not appear in my logs. The Apple TV is named ‘Living Room’.

Of course, I also have a HomePod and stream music and news to it all day long. In this example I’m streaming from my macOS laptop to my HomePod named StationX. I have found that the elapsed time doesn’t seem to update as the examples above did.

Quirky? Yes.

While doing this research and testing various applications, I came across entries while I was most definitely sleeping. Seems my laptop wanted me to listen to the radio very, very early in the morning for about 15 seconds. 🤷🏻‍♀️

Do entries like this make all the examples in the article inaccurate? Absolutely not. Computers act in weird ways. This is a great example of why correlating this information to user activity through other means (ie: sleep status, device unlocks, user activity in knowledge, etc.) is required in investigations.

I hope this article gets you thinking about all the other apps that you watch media from. Again, this is not just on macOS but also on iOS (and likely tvOS as well). All those applications, native and 3rd party, are just waiting to catch you binge watching your favorite show, finding the end of YouTube, and rocking out to your favorite 90’s boyband jams!

Analysis of Apple Unified Logs: Quarantine Edition [Entry 8] – Man! What a process!?

A quick trick to get more info when you are testing different Unified log examples is to use Terminal’s man page lookup feature. This is useful to provide more context to processes that you may not be familiar with. Perhaps you have something interesting in the eventMessage field and want to know more about what processes use that information.

In this example, I “right-clicked” some of the process names to get more information about them; sharingd, bluetoothd, and powerd. However, identifityservicesd does not have a man page so I’ll have to research that one another way!