Venmo. The App for Virtual Ballers.

I recently went on a trip which required hanging out in a couple of airport terminals. While waiting on my flights I saw the usual scene: a sea of people staring down at their phones. I am not going to delve into the obvious security concerns (whole different topic), but I was able to see many home screens from my vantage point, and I noticed a few consistent apps. One was a blue square/circle with a white ‘V’ in it: Venmo, the social media payment app.

Full disclosure: I am not a Venmo person. I live in Apple’s walled garden and like to use Apple Pay whenever I can. I am reluctant to provide any merchant or service any financial information as I have been caught up in a couple of data breaches, specifically, Target and Home Depot. While those two incidents involved POS weaknesses, the pain they caused made me extremely paranoid when it comes to my financial information.

Not everyone has that attitude, however. While conducting testing for this post I was amazed at how many people in my contact list use Venmo. My spouse even uses it (she had to show me the ropes when I first fired up the app). As of April of 2019, Venmo reported 40 million active users with payment volume around $21 million; it is expected that payment volume will hit $100 million for the entirety of 2019. Comparatively, it sits behind its parent company, PayPal, and Amazon Pay. Third isn’t too shabby in the mobile payment space.

Because Venmo is owned by PayPal, users can, at many merchants, use Venmo where PayPal is accepted, but using it at merchants isn’t Venmo’s main draw. It is being able to pay people for whatever reason without having to use cash…especially since most people don’t accept cards and a majority of people, I would argue, don’t carry cash around. Venmo is also a social media app. It has a feed, similar to other social media feeds, that shows you what your “friends” are buying and selling. For example, in my Venmo social feed I saw payments for “schnacks,” daycare, date nights, booze, haircuts, groceries, picking up prescription medications, pizza, and a corn hole tournament. These were person-to-person transactions, not person-to-merchant. Paying people for whatever just by clicking a few buttons can be a lot easier than paying with cash (again, who does that nowadays???) or trying to figure out who accepts cards and who doesn’t. For some small merchants, it may be cheaper to use Venmo versus accepting cards and having to pay bank/card transaction fees.

There is also a public feed that shows what people (who you are not friends with) are buying and selling. This is notable as the default setting for transactions is “public” (more on that later).

This idea of a social feed is important. File it away for now because I will bring it up later when discussing iOS.

Like everything else, people have found a way to use Venmo for questionable activities. I found a site, Vicemo, that uses Venmo’s public API to track what it thinks are payments for booze, strippers, and narcotics. In 2017 there was a study that found a third of Venmo users have paid for weed, cocaine, and Adderall with Venmo, and that 21 percent of Venmo users have used it to make bets on sporting events.

Is This Useful?

Generally speaking, having access to this data can be beneficial as it can be considered pattern-of-life (POL) data. A lot can be gleaned from knowing what a person purchases or sells, and from/to whom they are purchasing or selling. Just think about the entry in my social feed regarding the prescription medication. Based on that entry, I may be able to deduce that person has a particular medical condition if the payment note has enough information in it. I could also look in my public feed and find similar bits of information.

This data can be a gold mine for investigators, and I would argue an investigator’s imagination is the limit for its application. For example, think of the drug dealer who is using Venmo for payments. Want to know who the buyers are or who the source is? Just pull the Venmo data, do some analysis, and start slinging subpoenas/court orders/search warrants for Venmo account information. What about the local fence who operates in your jurisdiction? Want to know who the fence sold some stolen property to? Same scenario.

My point is people do not randomly give money away. They are paying for things they need, want, or are significant to them in some fashion. Understanding this allows an investigator to draw conclusions by taking this data and applying some deductive reasoning.

POL data is extremely useful. There has been a lot of research during the past couple of years that has shown just how much data about our lives is collected by our mobile devices. This data, when interpreted correctly, can be powerful.

The Setup

As usual, just a few notes on the hardware/software used.

Pixel 3:   Android 10 (patch level 9/5/19), rooted, Venmo version 7.40.0 (1539)

iPhone SE:  iOS 13.2, non-jailbroken, Venmo version 7.40.1 (1)

For testing I used a couple of pre-paid cards that I picked up at a Wal-Mart. I had to register the cards first with their respective “banks”, and then load them into Venmo; if you were to use a card issued to you the registration part would not be necessary. Also, you have the option to link an actual bank account to your Venmo account, which is something I did NOT do.

I will add that during my analysis, I did not find where either OS stored the actual card information, even though I could see it within the UI. It may be there, encoded somehow, but I didn’t see it.


Before we go down the forensic road, I want to show what a transaction screen looks like in the Android UI. It will help make things clearer.

Figure 1 shows the payment screen. In the red box is the transaction recipient. While I didn’t do it during testing, and you can add more than one recipient here. The green box is obvious…the amount of money I am sending. The blue box shows the note that is attached to the payment. Venmo requires that there be something in this field, even if it is an emoji. The orange box is the share-level of the transaction. It can be set to Public (everyone on Venmo sees it), Friends Only, or Private (just you and the recipient see the transaction). The default is Public, but you can change the default setting from the Settings menu.

Figure 1.png
Figure 1.  Android payment UI.

The purple box dictates what happens to this transaction. If you hit “Pay” the money is sent. If you hit “Request” a request goes to the transaction recipient who can either pay or decline to pay the requested amount. More on those in a bit.

There is one other way to send someone money. An intended transaction recipient can display a QR code on their device, which the sender can scan, fill out the note and amount fields, and then hit “Pay” or “Request.”

Venmo data in Android resides in /data/data/com.venmo. Because of new technical hurdles with Android 10 on the Pixel 3, I had to copy the folder over to the /sdcard/Download folder via shell and then run an ADB pull from there.

Unlike my previous post about Wickr, Venmo databases are pretty straight forward. There are three files of interest, with the biggie being venmo.sqlite. The database can be found in ./databases folder. See Figure 2.

Figure 2.png
Figure 2.  Available databases in Android.

There is an additional database of interest here, too, named mparticle.db, which I will discuss shortly.

This database contains all of the transaction information along with any comments about transactions and any responses to the transactions. Take a look at the screen shot in Figure 3, which shows a completed transaction. The iOS device paid the Android device $5.00 on 10/31/2019 at 9:56 PM (EDT). The note sent with the payment was “For the testing stuff. My first payment.” The Android device responded to the comment (no time stamp is seen).


Figure 3.png
Figure 3. Android screenshot of a completed payment.

Figure 4 shows the table marvin_stories. You will notice transactions are called stories, and that timestamps are stored in Zulu time in human-readable format.

Figure 4.png
Figure 4.  The marvin_stories table.

The columns of interest here are story_data_created, story_note, and story_audience. However, if you want to get all of that information and more in one place, you need to look at the contents of the last column, story_blob. See Figure 5.

Figure 5
Figure 5.  Transaction information from the story_blob column.

The contents of these cells are broken up in to three parts. Actor (transaction sender), transaction information, target (transaction recipient). If you recall from Figure 2, the iOS device sent the Android device $5.00. So, the actor, the iOS device, is seen in the green box. There you can see the action (“pay” the Android device), the display name, friend status, the user ID for that account, last name, how many mutual friends we may have, and the actual user name (Josh-Hickman-19).

In the purple box you find the transaction information: the amount of money (5.0 – Venmo drops tailing zeros occasionally), the date the transaction was created and completed, the transaction ID (more on that in a moment), the note that came with the payment, and the fact that it was “settled.” The status of “settled” is the only status I have seen and I have not been able to change the value in this field.

The orange box has the transaction recipient, or the target, which is the Android device (ThisIs-DFIR). It has the same information as the green box.

When a transaction is completed in Venmo, both parties get an email notification. The transaction ID seen in the purple box in Figure 5, also appears in the email (Figure 6, red box).

Figure 6
Figure 6.  Email with transaction ID.

The column story_likes_blob is simple, and is seen in the red box in Figure 7. If there is a value present in this cell it means someone “liked” the transaction. An example of how that appears in the UI is seen in Figure 8.

Figure 7.png
Figure 7.  story_likes_blob column.


Figure 8.png
Figure 8.  A “liked” transaction.

Values in the column are also stored in JSON. The “like” for the transaction in Figure 8 is displayed in Figure 9. As you can see, much of the information in the transaction JSON data is also present here.

Figure 9.png
Figure 9.  A “like” in the database.

A note about the privacy level of transactions. After a transaction is completed, it goes into a social feed. The feed it goes into is dependent upon what privacy level setting was chosen at the time the transaction was sent; however, the transaction privacy level can be changed by any party that was part of the transaction at any time. If the privacy level is changed, the transaction is removed from the original feed and placed in the new feed.

The reason privacy level is important is that people not part of the transaction may be able comment on it (because they can see it). Their ability to do so is dependent upon the privacy level. For example, if I set the privacy level of a transaction as “Private,” only the other person (or persons if there is more than one party) can comment on the transaction. If I set the privacy level to “Friends Only,” then my “friends” in Venmo can comment on the transaction along with the parties involved. If I set the privacy level to “Public” anyone on Venmo can comment on the transaction.

Figure 10 shows a transaction that has a comment. As you can see in the blue box, I set the privacy level of this particular transaction to “Friends Only,” which means any of my Venmo “friends” could add a comment to this transaction if they chose to do so.

Figure 10.png
Figure 10.  A transaction with a comment.

Getting back to the database, the table comments contains information about comments made on transactions. See Figure 11.

Figure 11
Figure 11.  The comments table.

Four columns are important here. The first is obvious: the comment_message column (orange box). This contains all of the comments made. The column next to it, created_time is the time the comment was left (blue box). The column in the red box, comment_story_owner, is important as it links the comment back to the transaction. The values in this column correspond to the values the story_id column in the marvin_stories table. Note that some transactions may not have entries in the table if no one comments on them.

The column seen the green box, comment_user_blob contains JSON data, and contains much of the same JSON data seen in previous figures. This documents who made the comment. If you are in a hurry and don’t want to look at the JSON data, you can clearly see them username value of the user who made the comment in the cell. 🙂

The last table in this database is table_person, and contains data about anyone with whom you have conducted a transaction. The data is simple. See Figure 12.

Figure 12
Figure 12.  table_person.

The next file of interest is also a database: mparticle.db. It resides in the same location as venmo.sqlite. The only data I was able to generate in this database appears in the attributes table. See Figure 13.

Figure 13
Figure 13.  Attributes from the mparticle.db.

The columns attribute_key, attribute_value, and created_time (stored in Unix Epoch) are straight forward. One note about the time, though. Users are able to change their display names and phone numbers, and if they do, the created_time values will also change. I changed my first and last name, but left the phone number. The created_time for the phone number in Figure 13 corresponds to when I created the account, but the other values correspond to the time I last made changes to my first and last name.

The last file is venmo.xml, and it resides in ./shared_prefs folder. This file contains some basic information along with an additional nugget or two. Figure 14 shows the first part of the file.

Figure 14.png
Figure 14  vemo.xml, Part 1.

In the green box is the userID for my “top friend.” Seeing how I had only one friend for this particular account, the value relates back to the account on the iOS device. The blue box has the timestamp for the last time time I sync’d my contacts, the yellow box has the email account associated with the Android account, and the red box contains the userID and last last name associated with the Android account.

Figure 15 has three items, the full name (display name) and phone number associated with the account (red box), and the display first name (blue box). The names seen here correspond to the values seen in the attributes table in the mparticle.db.

Figure 15.png
Figure 15.  venmo.xml, Part 2.

Figure 16 has two items. The first is seen in the green box, and is the user name on the Android account. The other, the user_balance_string value, corresponds to the amount of money this account has in Venmo, which can be seen in the blue box in Figure 17.

Figure 16.png
Figure 16.  venmo.xml, Part 3.
Figure 17.png
Figure 17.  Venmo balance.

When a transaction is completed in Venmo, the money goes into what I like to think of as a staging area. This staging area holds the funds, and you can either use them in other transactions, or transfer them to a bank account if you have one linked. You can also have the balance sent to a credit card, but the credit card has to be a certain type, and my pre-paid card didn’t meet the criteria.

Paying someone via “Pay” or scanning a QR code is not the only way a user can get paid. A user can request payment. Remember the “Request” button in Figure 1? Well, there is a way to tell if that was the method by which funds were transferred. See Figure 18.

Figure 18.png
Figure 18.  The “charge” action.

Figure 18 has the same data in the same green, purple, and orange boxes as seen in Figure 5. The only difference here is the “action” field at the top of the green box has changed from “pay” to “charge” (red arrow). This indicates the transaction occurred because the Actor (the transaction sender in the green box) box requested payment, and the Target (the transaction recipient in the orange box) granted the request. As a side note, you can see that there are more digits in the “amount” field this time (purple box).

I tried requesting payment and declining the request three times to see what was left behind. Interestingly enough, there is no record of those three requests anywhere. Venmo may keep this data server side, but you will not get it from the device.

That’s it for Android. I had to triple check everything because I thought I was missing something, again, because of the amount of work involved in the Wickr post. That being said, there are other capabilities of Venmo I did not test, such as Facebook, Snapchat, and Twitter integration, along with linking my bank account. As I previously mentioned, I was surprised I did not find any references to the bank card used for transactions; it may be there, but I did not find it.


Good news: Venmo data is available in an encrypted iOS backup in iOS 13.2, so I assume that is the same for previous iOS versions. This is great because that means all an examiner needs to do is create a backup, or use their preferred forensic extraction tool to get this data. Nothing else was necessary.

iOS contains the same data as the Android version, just in a different format. There was also a few additional bits of data I found that could be useful in certain situations, and I will review that as well.

Transaction information is stored in the net.kortina.labs.Venmo/Documents folder. Remember when I mentioned the idea of a social feed being important? Well, iOS is why. Unlike Android, iOS stores Venmo transactions in three different files. Which file it stores a transaction in depends on the privacy level set at the time of the transaction. See Figure 19.

Figure 19.png
Figure 19.  Contents of the net.kortina.labs.Venmo/Documents folder.

The files FriendsFeed, PrivateFeed, and PublicFeed“should look familiar. These are the three privacy level settings for Venmo transactions. These three files are binary plist files. Figure 20 shows the same transaction as seen in Figure 5, and comes from the PrivateFeed file.

Figure 20.png
Figure 20.  Same transaction as Figure 5.

Reading this is a little tricky as the data is not as neatly grouped as that in the Android database. First, the file stores data from the bottom up, chronologically speaking. Second, this transaction was found in the PrivacyFeed file (remember the privacy level setting seen in the orange box in Figure 1). To help see the comparison to Android, I grouped the actor, transaction information, and target data using the same green, purple, and orange boxes. In the red box is the comment the Android account left for this transaction, complete with the timestamp; see Figure 21 for how this looks in the iOS UI.

Figure 21.PNG
Figure 21.  Comment from Figure 20.

One thing you will notice is that the “action” and status fields are missing. I looked in this file and the only time these fields showed was the most recent transaction that occurred with the privacy level set to Private (at the top of the PrivacyFeed file). The rest of the transactions in this feed did not have an action or status associated with them. I may not necessarily be reading this bplist file correctly, so if someone else knows, please let me know so I can update this post.

Figure 22 was the most recent “Private” transaction on the iOS account. Figure 23 shows the data in the bplist file with the usual groupings (green box = actor, purple box = transaction information, orange box = target), and Figure 24 shows that same transaction in the venmo.sqlite database from the Android device. Notice the “action” and “status” fields are present in Figure 23.

Figure 22.png
Figure 22.  Last “private” transaction on the iOS account.
Figure 23.png
Figure 23.  bplist entry for the transaction in Figure 22.
Figure 24.png
Figure 24.  Android entry for the comparison.

Figure 25 shows the “Request” transaction from Figure 18. Again, I used the same colored boxes to the group the data. Note the red box at the bottom; it contains the privacy level setting for the transaction.

Figure 25.png
Figure 25.  The “request” transaction from the iOS point of view.

Since we are on transactions I will head over to the “FriendsFeed” for just a moment. This is an additional bit of information that I saw in iOS that was not present in Android. This feed contains a lot of information about your Venmo friends’ transactions. The data is not as verbose as the data about my transactions, but you can see when transactions occur, the transaction information (time, note, and transaction ID – purple box), the actor (green box) and target (orange box). Notice the action and status fields are missing. Because the target and actor are not aware of this blog post, I have redacted pertinent information. See Figure 26.

Figure 26
Figure 26.  A transaction by one of my Venmo friends.

If you recall from Figure 19, there is a database present named Model.sqlite. This database contains information about a user’s Venmo friends. The table ZMANAGEDUSER contains friend information. See Figure 27.

Figure 27.png
Figure 27.  Venmo friends.

These columns are fairly self-explanatory. ZCREATEDAT is the time the user account was created. ZDISPLAYNAME is the display name for the account. ZFAMILYNAME is the user’s last name. ZGIVENNAME is the user’s first name. ZIDENTIFER is the user’s userID, and ZUSERNAME is the user’s user name.

The PublicFeed file contains the same data as the Private and Friends versions, but includes data about people with whom the user is not friends with.

The next interesting file is net.kortina.labs.Venmo.plist which is found in the ./Library/Preferences folder. The top part of the file is seen in Figure 28.

Figure 28.png
Figure 28.  net.kortina.labs.Venmo.plist, Part 1.

The data in the red square is the iOS equivalent to the Android data seen in Figure 13. The blue square references Venmo friends. I expanded it in Figure 29.

Figure 29.png
Figure 29. plist friends from net.kortina.labs.Venmo.plist.

The data in Figure 29 comes from the user’s contact list on device.

Figure 30 is the rest of the net.kortina.labs.Venmo.plist. The data in the red squares are the display name, the email address associated with the account, and the phone number associated with the account. You can see, based on the data in the blue square, that I changed my default privacy level to “Friends.”

Figure 30.png
Figure 30. net.kortina.labs.Venmo.plist, Part 2.

Figure 31 shows the file found in the same directory as the previous file. The app version and the first time the app was opened can be found in the red and blue squares, respectively.

Figure 31.png
Figure 31.

That’s it for iOS. The data is readily available, and includes data that is not necessarily present in Android. As with Android, I did not find any information on the card attached to the account, and I did not test any of the linking or integration abilities.


Virtual payments are a thing, no doubt about it. Amazon Pay, PayPal, Venmo, Zelle and many others along with the platform-specific pay services like Apple Pay and Google Pay are all trying to help people pay for things. Venmo is ranked 3rd in that group, and stands out from the crowd by mixing payment services with social media capabilities.

Venmo contains POL data, which can be valuable, and the data is versatile. It can be used to extrapolate information about the user which can be useful for investigators.

Wickr. Alright. We’ll Call It A Draw.

Ugh.  Not again.

Portions of this blog post appeared in the 6th issue of the INTERPOL Digital 4n6 Pulse newsletter. 

I would like to thank Heather Mahalik and Or Begam, both of Cellebrite, who helped make the Android database portion of this blog post possible, and Mike Williamson of Magnet Forensics for all the help with the underpinnings of the iOS version.

I have been seeing the above pop-up window lately.  A  lot.  Not to pick on any particular tool vendor, but seeing this window (or one simmilar to it) brings a small bit of misery.  Its existence means there is a high probability there is data on a particular mobile device that I am not going to get access to, and this is usually after I have spent a considerable amount of time trying to gain access to the device itself.  Frustrating.

One of my mentors from my time investigating homicides told me early in my career that I was not doing it right unless I had some unsolved homicides on the books; he felt it was some sort of badge of honor and showed a dedication to the craft.  I think there should be a similar mantra for digital forensic examiners.  If you conduct digital forensic examinations for any substantial amount of time you are going to have examinations where there is inaccesible data and nothing you do is going to change that.  You can throw every tool known to civilization at it, try to manually examine it, phone a friend, look on Twitter, search the blog-o-sphere, search the Discord Channel, query a listserv, and conduct your own research and you still strike out.  This is a reality in our discipline.

Not being able to access such data is no judgment of your abilities, it just means you may not win this round.  Keep in mind there is a larger fight, and how you react to this setback is a reflection of your dedication to our craft.  Do you let inaccessible data defeat you and you give up and quit, or do you carry on with that examination, getting what you can, and apply that same tenacity to future examinations?

One needs the latter mindset when it comes to Wickr.  For those that are unfamilar, Wickr is a company that makes a privacy-focused, ephemeral messaging application. Initially available as an iOS-only app, Wickr expanded their app to include Android, Windows, macOS, and Linux, and branched out from personal messaging (Wickr Me) to small teams and businesses (Wickr Pro – similar to Slack), and an enterprise platform (Wickr Enterprise).  Wickr first hit the app market in 2012, and has been quietly hanging around since then.  Personally, I am surpised it is not as popular as Signal,  but I think not having Edward Snowden’s endorsement and initially being secretive about its protocal may have hurt Wickr’s uptake a bit.

Regardless, this app can bring the pain to examinations.

Before I get started, a few things to note.  First, this post encompasses Android, iOS, macOS, and Windows.  Because of some time constraints I did not have time to test this in Linux.  Second, the devices and respective operating system versions/hardware are as follows:

Platform                    Version                 Device                                                   Wickr Version

Android                      9.0                         Pixel 3                                                    5.22

iOS                               12.4                       iPhone XS and iPad Pro 10.5            5.22

macOS                        10.14.6                  Mac Mini (2018)                                  5.28

Windows 10 Pro       1903                      Surface Pro                                           5.28

Third, Wickr Me contains the same encryption scheme and basic functionality as the Pro and Enterprise versions: encrypted messaging, encrypted file transfer, burn-on-read messages, audio calling, and secure “shredding” of data. The user interface of Wickr Me is similar to the other versions, so the following sections will discuss the functionality of Wickr while using the personal version.

Finally, how do you get the data?  Logical extractions, at a minimum, should grab desktop platform Wickr data during an extraction.  For Android devices, the data resides in the /data/data area of the file system, so if your tool can get to this area, you should be able to get Wickr data.  For iOS devices, you will need a jailbroken phone or an extraction tool such as one that is metal, gray, and can unlock a door to get the Wickr database.  I can confirm that a backup nor a logical extraction contains the iOS Wickr database.

Visual Walkaround

Wickr is available on Android, iOS, macOS, and Windows, and while these platforms are different, the Wickr user interface (UI) is relatively the same across these platforms. Figure 1 shows the Windows UI, Figure 2 shows the macOS UI, Figure 3 shows the iPhone, and Figure 4 shows the iPad. The security posture of the Wickr app on Android prevents screenshots from being taken on the device, so no UI figure is available.  Just know that it looks very similar to Figure 3.

Figure 1
Figure 1.  Wickr in Windows.
Figure 2.png
Figure 2.  Wickr in macOS.


Figure 3.png
Figure 3.  Wickr on iPhone.
Figure 4
Figure 4.  Wickr on iPad.

Each figure has certain features highlighted. In each figure the red box shows the icons for setting the expiration timer and burn on read (setting that allows the sender of a message to set a self-destruction timer on a message before it is sent – the recipient has no control over this feature), the blue arrow shows the area where a user composes a message, the orange arrow shows the area where conversations are listed, and the purple arrow shows the contents of the highlighted conversation (chosen in the conversations list).  Not highlighted is the phone icon seen in upper right corner of each figure. This initiates an audio call with the conversation participant(s).

The plus sign seen in the screen (red boxes) reveals a menu that has additional options: send a file (including media files), share a user’s location, or use one of the installed quick responses. Visually, the menu will look slightly different per platform, but the functionality is the same.  See Figure 5.

Figure 5
Figure 5.  Additional activity options (Windows UI).

The sending and receiving of messages and files works as other messaging applications with similar capabilities. Figure 6 shows an active conversation within the macOS UI.

Figure 6.png
Figure 6.  A conversation with a text message and picture attachments (macOS UI).

Wickr is similar to Snapchat in that messages “expire” after a set period of time. The default time a message is active is six (6) days, which is the maximum amount of time a message can be available, but a user can set message retention times as short as one second. This setting is device specific; if a user has multiple devices they can choose different retention periods for each device.

Users can also set “burn-on-read” times in which a message will expire (“burn”) after a certain period of time after the message has been read. This setting is controlled by the message sender, regardless of the recipient’s message retention period setting.  The retention period for burn-on-read messages can also be set anywhere between 1 second and 6 days. Figure 7 shows the Windows Wickr UI when a burn-on-read message has been received and opened (bottom of the active conversation window pane), and Figure 8 shows the same UI after the burn-on-read retention period expired.

Figure 7
Figure 7.  A burn-on-read message (timer in red).
Figure 8
Figure 8.  Poof! The message has been burned.

The Secure Shredder function is Wickr’s feature by which data that has been deleted by the app is rendered unrecoverable by overwriting the deleted data.  Secure Shredder is an automated feature that runs in the background but has a manual configuration feature if a user is part of the Wickr Pro Silver or Gold tiers, which allows users to manually initiate the function.  Testing showed this feature automatically runs every +/- one (1) minute while the device is idle.

Encryption.  All Of The Encryptions.

Wickr is designed with total privacy in mind, so all three versions use the same encryption model. The app not only protects messages, media, and files in transit, but it also protects data at rest. The app has been designed with perfect forward secrecy; if a user’s device is compromised, historical communications are still protected unless the attacker has the user’s password and the messages have not expired.

When a new message is received, it arrives in a “locked” state.  See Figure 9.

Figure 9.png
Figure 9.  A new message.

When a message is sent, the sender’s device will encrypt the message using a symmetric key. To generate the symmetric key, internal APIs gather random numbers which are then run through the AES-256 cryptographic algorithm in Galois/Counter Mode (GCM). Each message is encrypted using a new symmetric key, and this operation occurs strictly on the sender’s device. This encryption happens regardless of whether the message contains text, a file, or a combination of the two. The cipher text and the symmetric key (i.e. the package) are encrypted using the signed public key of the recipient’s device (I’ll discuss asymmetric operations in a minute), and then sent to the recipient who then decrypts the package using their private key. The symmetric key is then applied to the cipher text in order to decrypt it.

The takeaway here is that unlocking a received message = decrypting a received message.  A user may set their device to automatically unlock messages, but the default behavior is to leaved them locked on receipt and manually initiate the unlock.

Asymmetric operations are applied to messages in transit.  As previously mentioned, cipher text and the symmetric key used encrypt it are packaged up and encrypted using the public key of the intended recipient’s device.  The public key is signed with components from said device.  The recipient device uses the corresponding private key to decrypt the package, and then the symmetric key is used to decrypt the cipher text  (unlocking the message) so the recipient can read it. If a message is intended for multiple recipients or for a recipient who has multiple devices, a different set of keys is used for each destination device.

Here is where the pain starts to come. The keys used in the asymmetric operations are ephemeral; a different set of public/private key pairs are used each time a message is exchanged between devices. Wickr states in its technical paper that pools of components (not the actual keys themselves) of private-public pairs are created and refreshed by a user’s device while they are connected to Wickr’s servers.  If a device is disconnected from the Wickr servers, it will use what key pairs it has, and will then refresh its pool once it has re-established the connection.

Even if a private key is compromised, the only message that can be decrypted is the one that corresponds to that specific private/public key pair; the rest of the messages are still safe since they use different pairs.

But wait, it gets worse.  Just to turn the knife a bit more, Wickr has a different encryption scheme for on-device storage that is separate from message transfers.  When Wickr is first installed on a device a Node Storage Root Key (Knsr) is generated. The Knsr is then applied to certain device data (described as “device specific data and/or identifiers derived from installed hardware or operating system resources that are unique, constant across application installs but not necessary secret“) to generate the Local Device Storage Key (Klds). The Klds is used to encrypt Wickr data stored locally on the device, including files necessary for Wickr to operate.

The Klds is itself encrypted using a key derived from the user’s password being passed through scrypt. When a user successfully logs in to the Wickr app, the Klds is decrypted and placed into the device’s memory, allowing for successful exposure of the locally stored Wickr data through the app UI. When the app is terminated, placed in an inactive state, or a user logs out, the Klds is removed from memory, and the Wickr data is no longer available.

For those who have legal processes at their disposal (court orders, search warrants, & subpoenas), the news is equally dire.  Wickr does keep undelivered messages on their servers for up to six (6) days, but, as I previously mentioned, the messages (which are in transit) are encrypted.  Wickr states they do not have acess to any keys that would decrypt what messages are stored.  There is some generic account and device information, but no message content.  For more information on what little they do have, please read their legal process guide.

So, Is There Anything I Can Actually Get?

The answer to this question is the standard digital forensics answer:  “It depends.” The encryption scheme combined with the on-device security measures makes it extremely difficult to recover any useful data from either the app or Wickr, but there is some data that can be retrieved, the value of which depends on the goal of the examination.

Testing has shown a manual examination is the only way, as of the time of this post, to recover message content from iOS, macOS, and Windows (files not included). This requires unfettered access to the device along with the user’s Wickr password. Due to a change in its encryption scheme (when this happened is unknown), Wickr is not supported by any tool I tested on any platform, which included the current versions of Cellebrite, Axiom, and XRY. This included the Android virtualization options offered by two mobile vendors.  Along those same lines, I also tried Alexis Brignoni’s virtualization walkthrough using Nox Player, Virtual Box, and Genymotion, with no luck on all three platforms.

Things can be slightly different for those of you who have Wickr deployed in an enterprise environment.  The enterprise flavor of Wickr does have compliance (think FOIA requests and statutory/regulatory requirements) and eDiscovery features, which means message content may be retained so as long as the feature is enabled (I didn’t have access to this version so I could not ascertain if this was the case).  Just be aware that if the environment includes Wickr, this may be an option for you.

The type and amount of data an examiner can possibly get is dependant upon which platform is being examined. The nice thing is there is some consistency, so this can help examiners determine, rather quickly, if there is anything to be recovered.  The consistencey can be broken up in to two categories:  iOS and Android/macOS/Windows. One thing is consistent across ALL platforms, though: an examiner should not expect to find any message content beyond six (6) days from the time of examination.


The most important thing to remember for Android, macOS, and Windows platforms is that order matters when doing a manual examination. That is, the order in which you examine the device for Wickr content is important. Failure to keep this mind may result in recoverable data being deleted unnecessarily.  Android can be slightly different, which I will discuss shortly.

I will go ahead and get one thing out of the way with all three platforms: the databases containing account information, conversation information, contacts, and message content are all encrypted.  The  database is protected with SQL Cipher 3, and the Wickr user password is not the password to the database (I tried to apply the correct Wickr password in DB Browser for SQLite, and none would open – you’ll see why below). Figure 10 shows the macOS database in hexadecimal view and Figure 11 shows the Windows database.  While not shown here, just know the Android database looks the same.

Figure 10.png
Figure 10.  Wickr database in macOS
Figure 11.PNG
Figure 11.  Wickr database in Windows.

You may have noticed the file name for both macOS and Windows is the same:  wickr_db.sqlite.  The similarities do not stop there.  Figure 12 shows the location of the database in macOS, Figure 13 shows the database’s location in Windows.

Figure 12
Figure 12.  Home in macOS.  ~/Users/%UserName%/Library/ApplicationSupport/Wickr, LLC/WickrMe/
Figure 13
Figure 13.  Home in Windows.  C:\Users\%UserName%\AppData\Local\Wickr, LLC\WickrMe\

As you can see, most of the file names in each home directory are the same.  Note that the last folder in the path, “WickrMe,” may be different depending on what version is installed on the device (Wickr Me, Wickr Pro, Enterprise), so just know the last hop in the path may not be exactly the same.

Interesting note about the “preferences” file in Windows:  it is not encrypted.  It can be opened, and doing so reveals quite a bit of octet data.  The field “auid” caught my attention, and while I have a theory about its value, I’ll save it for another blog post.

For Android, the directory and layout should look familar to those who examine Android devices.  The database file, wickr_db, sits in the databases folder.  See Figure 14.

Figure 14
Figure 14.  Home in Android.  /data/data/com.mywickr.wickr2

If you will recall, when a user unlocks a message it is actually decrypting it.  This also applies to files that are sent through Wickr.  Unlike messages, which are stored within the database, files, both encrypted and decrypted, reside in the Wickr portion of the file system.  When a message with a file unlocked, an encrypted version is created within the Wickr portion of the file system.  When the file is opened (not just unlocked), it is decrypted, and a decrypted version of that file is created within a different path within the Wickr portion of the file system.  Figure 15 shows the Android files, Figure 16 shows the macOS files, and Figure 17 shows the Windows files.  The top portion of each figure shows the files in encrypted format and the bottom portion of the figure shows the files in decrypted format.

Figure 15.png
Figure 15.  Encrypted/decrypted files in Android.
Figure 16
Figure 16.  Encrypted/decrypted files in macOS.
Figure 17
Figure 17.  Encrypted/decrypted files in Windows.

When a file is sent through Wickr it is given a GUID, and that GUID is consistent across devices for both the sender and the recipient(s).  In the figures above, Android represents Test Account 1 and macOS/Windows represents Test Account 2, so you will notice that the same GUIDs are seen on both accounts (all three platforms).

The fact an encrypted version of a file exists indicates a device received the file and the message was unlocked, but doesn’t necessarily indicate the file was opened.  It isn’t until the user chooses to open the file within the Wickr UI that a decrypted version is deposited onto the device as seen above.  An example of the open dialogue is seen in Figure 18.  The triple dots in the upper righthand corner of the message bubble invokes the menu.

Figure 18.png
Figure 18.  Open dialogue example (Windows UI).

If a picture is received and the message is unlocked, then a thumbnail is rendered within the Wickr UI message screen, as seen in Figure 18, but this doesn’t deposit a decrypted version of that picture; the user must open the file.  Any other file type, including vidoes, merely display the original file name in the Wickr UI.  A user will have to open the file in order to view its contents.

The directories for files on each platform is as follows (path starts in the Wickr home directory):

Platform                                   Encrypted Files                                    Decrypted Files

Android                                    ~/files/enc                                             ~/cache/dec

macOS                                      ~/temp/attachments                           ~/temp/preview

Windows                                 ~/temp/attachments                           ~/temp/preview

This behavior applies to files both sent and received.  Also keep in mind there is a probability that you may find encrypted files with no corresponding decrypted version.  This may be due to the message retention time expiring, which is why the order of examination is important, or it may mean the user never opened the file.

For both macOS and Windows, the only way to recover message content is via a manual examination using the Wickr UI, which means that a logical image should contain the sought after data.  However, the order of your examination can impact your ability to recover any decrypted files that may be present on the device.  Since the Wickr application is keeping track of what files may have passed their message retention period, it is extremely important to check for decrypted files prior to initiating Wickr on the device for a manual examination.  Failure to do so will result in any decrypted file whose message retention time has expired being deleted.

The Android database.  Slightly different

While the databases for macOS and Windows are inaccessible, the story is better for Android.  While conducting research for this post I discovered Cellebrite Physical Analyzer was not able to decrypt the wickr_db database even though it was prompting for a password.  Cellebrite confirmed Wickr had, in fact, changed their encryption scheme and Physical Analyzer was not able to decrypt the data.  A short time later they had a solution, which allowed me to proceed with this part of the post.  While not currently available to the public, this solution will be rolled out in a future version of Physical Analyzer.  Fortunately, I was granted pre-release access to this feature.

Again, thank you Heather and Or.  🙂

While there is still a good deal of data within the wickr_db file that is obfuscated, the important parts are available to the examiner, once decrypted.  The first table of interest is “Wickr_Message.”  See Figure 19.

Figure 19.png
Figure 19.  Wickr_Message table.

The blue box is the timestamp for sent and received message (Unix Epoch) and the orange box contains the text of the message or the original file name that was either sent or received by the device.  The timestamp in the red box is the time the message will be deleted from the Wickr UI and database.  The values in the purple box are inteteresting.  Based on testing, each file I sent or received had a value of 6000 in the messageType column.  While not that important here, these values are important when discussing iOS.

The blobs in the messagePayload column are interesting in that they contain a lot of information about file transfers between devices.  See Figure 20.

Figure 20.png
Figure 20.  Message payload.

The file sender can be seen next to the red arrow, the file type (e.g., picture, document, etc.) is next to the blue arrow, the GUID assigned to the file is seen in green box.  The GUID values can be matched up to the GUIDs of the files found in the /enc and /dec folders.  Here, the GUID in the green box in Figure 20 can be seen in both folders in Figure 21.  Finally, you can see the original name of the file next to the purple arrow (iOS_screenshot).  The original file name also appears in the cachedText colum in Figure 19.

Figure 21
Figure 21.  Matching GUIDs

The orange box in Figure 20 contains the recipients username along with the hash value of the recipient’s Wickr User ID.  That value can be matched up to the value in the senderUserIDHash column in the same table (see the red box in Figure 22).  The title of this column is deceptive, because it isn’t actually the userID that is represented.

Figure 21
Figure 22.  Sender’s hashed ID

Figure 23 shows the same hash in the serverIDHash column in the table Wickr_ConvoUser table.

Figure 23
Figure 23.  Same IDs.

Also of note in this table and the one seen in Figure 22 is the column vGroupID.  Based on testing, it appears every conversation is considered to be a “group,” even if that group only has two people.  For example, in my testing I only had my two test accounts that were conversing with each other.  This is considered a “group,” and is assigned a GUID (seen in the blue box).  The good thing about this value is that it is consistent across devices and platforms, which could come in handy when trying to track down conversation participants or deleted conversations (by recovering it from another device).  An example of this cross-platform-ing is seen in Figure 24, which shows the table ZSECEX_CONVO from the Wickr database in iOS.  Note the same GroupID.

Figure 24
Figure 24.  Same group ID.

Figure 25 shows, again, the serverIDHash, but this time in the table Wickr_User.  It is associated with the value userIDHash.  The value userAliasHash (the same table) is seen in Figure 26.

Figure 25
Figure 25.  serverIDHash and the userIDHash.
Figure 26
Figure 26.  userIDHash (Part 2).

Figure 27 shows some telemetry for the users listed in this table.

Figure 27
Figure 27.  User telemetry.

The columns isHidden (purple box) and lastMessaged (red box) are self-explanatory.  The value of 1 in the isHidden column means the user does not appear in the Conversations section of the UI.  That value coupled with the value of 0 in the lastMessaged column indicates this row in the table probably belongs to the logged in account.

The lastRefreshTime column (blue box) has the same value in both cells.  The timestamp in the cell for row 1 is when I opened the Wickr app, which, undoubtedly, caused the app to pull down information from the server about my two accounts.  Whether this is what this value actually represents requires more testing.  The same goes for the values in lastActivityTime column (orange box).  The value seen in the cell in row 1 is, based on my notes, the last time I pushed the app to the background.  The interesting thing here is there was activity within the app the after the timestamp (the following day around lunch time PDT).  More testing is required in order to determine what these values actually represent.  For now, I would not trust lastActivityTime at face value.

The table Wickr_Settings contains data of its namesake.  The first column of interest is appConfiguration (red box).  See Figure 28.

Figure 28.PNG
Figure 28.  Wick_Settings

The data in this cell is in JSON format.  Figure 29 shows the first part of the contents.

Figure 29
Figure 29.  JSON, Part 1.

There are two notable values here.  The first, in the blue box, is self explanatory:  locationEnabled (Wickr can use location services).  I let Wickr have access to location services during initial setup, so this value is set to ‘true.’  The value in the red box, alwaysReauthenticate, refers to the setting that determines whether or not a user has to login into Wicker each time the app is accessed.  It corresponds to the switch in the Wickr settings seen in Figure 30 (red box).

Figure 30.PNG
Figure 30.  Login each time?  No thanks.

Because I didn’t want to be bothered with logging in each time, I opted to just have Wickr save my password and login automatically each time, thus this value is set to ‘false.’  If a user has this set and does not provide the Wickr password, a manual examination will be impossible.

The rest of the contents of the JSON data are unremarkable, and is seen in Figure 31.

Figure 31
Figure 31.  JSON, Part 2.  Nothing much.

There are three additional columns that are notable in this table.  The first is the setting for the Secure Shredder, autoShredderEnabled.  This value is set to 1, which means that it is enabled.  I would not expect to see any other value in this cell as Secure Shredder runs automatically in Wickr Me and some tiers of the Wickr Pro versions; there is no way to disable it unless the Silver, Gold, or Enterprise versions of Wickr is present.  See Figure 32.

Figure 32
Figure 32.  Anonymous Notifications, Secure Shredder, and Auto Unlock.

The second notable column is unlockMessagesEnabled (red box).  As its name implies, this setting dictates whether a message is unlocked on receipt, or if a user has to manually initiate the unlock.  I took the default setting, which is not to unlock a received message (database value of 0).  Figure 33 shows the setting in the Wickr Settings UI.

Figure 33
Figure 33.  Message Auto Unlock switch.

Figure 32 also shows anonymousNotificationsEnabled (orange box).  This setting dictates whether Wickr notifications provide any specific information about a received message/file (e.g., sender’s user name, text of a message, file name), or if the notification is generic (e.g., “You have a new message”).  Again, the default is to show generic notifications (database value of 1).  Figure 34 shows the setting in the Wickr Settings UI.  Note the switch is off, but since I have Auto Unlocks disabled, this switch is not used because my messages are not automatically unlocked on receipt.

Figure 34.PNG
Figure 34.  Anonymous Notification setting.

I want to address one last table;  Wickr_Convo.  Using the conversation GUIDs, you can determine the last activity within each conversation that is stored on the device.  In Figure 35, this conversation GUID is the same as the ones seen in Figure 23 and 25.

Figure 35
Figure 35.  Conversations listed by GUID.

There are two values that are notable.  The first is is the lastOutgoingMessageTimestamp (red box). That is a pretty self-explanatory label, right?  Not quite, and examiners should be careful interpreting this value.  That same timestamp appears in the Wickr_Message table seen in Figure 37, but with a different label.

Figure 36
Figure 36.  Wickr_Convo table timestamps.
Figure 37.png
Figure 37.  Wickr_Message table timestamps.

It appears that the lastOutgoingMessageTimestamp from Wickr_Convo applies to the last message that did not involve a file transfer (value timestamp seen in the Wickr_Message table) .  The value lastUpdatedTimestamp (blue box in Figure 36) actually represents the last communication (message or file transfer) in the conversation, which is seen in the blue-boxed timestamp value in the Wickr_Message table (blue box in Figure 37).

The value messageReadTimestamp (orange box in Figure 36) represents the time the last message was unlocked.  Notice that the value is just about the same as that seen in lastUpdatedTimestamp, but with more granularity.

A couple more things

There are two more files I’d like to touch on with regards to the Android version.  The first is found in the /shared_prefs folder.  See Figure 38.

Figure 38
Figure 38.  Measurement data for the app.

This file keeps track of certain data about app usage.  The most obvious data points are the install time for the app itself (orange box) and the first time the app was opened (red box).  The next two data poins are app_backgrounded (yellow box) and last_pause_time (green box).  The app_backgrounded value, as you can see, is a boolean value that indicates whether the app is active on the device screen or if the app is running in the background (i.e. not front-and-center on the device).  The value last_pause_time is the last time the app was pushed to the background by the user (“paused”).  If an examiner is pulling this data from a seized device is highly likely that the app_backgrounded value will be true, unless the device is seized and imaged while Wickr is actively being used.

The value in the blue box, last_upload, is a deceiving value, and I have yet to figure out what exactly it represents.  I have a theory that it may be the last time the app uploaded information about its current public key which is used in the asymmetric encryption operations during message transport, but I can not be totally sure at this point.  Just know that last_upload may not necessarily represent the last time a file was uploaded.

The last file is COUNTLY_STORE.xml.  Based on research, it appears this file may be used for analytical purposes in conjunction with the Countly platform.  This file keeps some metrics about the app, including the cell service carrier, platofrm version (SDK version), hardware information, and a unique identifier, which, on Android, is the advertising ID (adid).  The data appears to be broken up into transactions with each transaction containing some or all of the data points I just mentioned. Each transaction appears to be separated by triple colons.  Each also contains a timestamp.

A representitive example can be seen in Figure 39; it does not contain all of the data points I mentioned but it gives you a good idea as what to expect.

Figure 40
Figure 39.  COUNTLY_STORE.xml in Android.

This file is inconsistent.  On some of my extractions the file was empty after app use and on others it was full of data.  Sometimes the timestamps coincided with my being in the app, and others did not.  There does not seem to be enough consistency to definatively say the timestamps seen in this file are of any use to examiners.  If someone has found otherwise please let me know.

There is a iOS equivalent:  County.dat.  This file contains most of the same data points I already described, and while it has a .dat extension, it is a binary plist file.  In lieu of the adid (from Android), a deviceID is present in the form of a GUID.  I think this deviceID serves more than one purpose, but that is speculative on my part.

Speaking of iOS…

iOS is different. Of course it is.

The iOS version of Wickr behaves a little differently, probably due to how data is naturally stored on iOS devices.  The data is already encrypted, and is hard to access.  The two biggest differences, from a forensic standpoint, are the lack of decrypted versions of opened files, and the database is not encrypted.

Before I proceed any further, though, I do want to say thank you again to Mike Williamson for his help in understanding how the iOS app operates under the hood.  🙂

I searched high and low in my iOS extractions, and never found decrypted versions of files on my device.  So there are two possible explanations:  1, they are in a place I didn’t look (highly unlikely but not completely impossible), or 2, they are never created in the first place.  I’m leaning towards the latter.  Regardless, there are no decrypted files to discuss.

Which leaves just the database itself.  While it is not encrypted, a majority of the data writtent to the table cells is encrypted.  I will say I am aware of at least two mobile device forensic vendors, who shall not be named at this time, that will probably have support for Wickr on iOS in the near future.  In the meantime, though, we are left with little data to review.

The first table is ZWICKR_MESSAGE, and, as you can guess, it contains much of the same data as the Wickr_Message table in Android.  Remember when I mentioned the messageType value in Android?  In iOS that value is ZFULLTYPE.  See Figure 40.

Figure 38
Figure 40.  Type 6000.

The value of 6000 is seen here, and, as will be seen shortly, correspond to files that have been sent/received.  Also, note the Z_PK values 8 and 10, respectively, because they will be seen in another table.

Figure 41 shows some additional columns, the titles of which are self-explanatory.  One I do want to highlight, though, is the ZISVISIBLE column.  The two values in red boxes represent messages I deleted while within the Wickr UI.  There is a recall function in Wickr, but I was not able to test this out to see if this would also place a value of 0 in this column.

Figure 39.png
Figure 41.  Deleted message indicators.

Figure 42 shows another set of columns in the same table.  The columns ZCONVO and Z4_CONVO actually come from a different table within the database, ZSECEX_CONVO.  See Figures 42 and 43.

Figure 40.png
Figure 42.  Conversation and Calls.
Figure 41
Figure 43.  ZSECX_CONVO table.

In Figure 42 the two columns highlighted in the orange box, ZLASTCALLCONVO and Z4_LASTCALLCOVO, appear to keep track of calls made via Wickr; in my case these are audio calls.  Here, the value indicates the last call to take place, and what conversation it occured in.  This is interesting since the Android database did not appear to keep track of calls as far as I could tell (the data may have been encrypted).  Remember, this table is equivalent to the Wickr_ConvoUser table in the Android database, so you will be able to see the ZVGROUPID, shortly.

The next bit of the table involves identifying the message sender (ZUSERSENDER), the timestamp of the message (ZTIMESTAMP), the time the message will expire (ZCLEANUPTIME), and the message identifier (ZMESSAGEID).  The timestamps in this table are stored in Core Foundation Absolute Time (CFAbsolute).  See Figure 44.

Figure 42.png
Figure 44.  Messages and their times.

The values in the ZUSERSENDER column can be matched back to the Z_PK column in the ZSECX_USER table.

That’s it for this table!  The rest of the contents, including the ZBODY column, are encrypted.

The ZSECX_CONVO table has some notable data as seen in Figure 45.  The one column I do want to highlight is ZLASTTIMESTAMP, which is the time of the last activity (regardless of what it was) in the conversation (the “group”).  Interestingly, the times here are stored in Unix Epoch.

Figure 43.png
Figure 45.  Last time of activity in a conversation (group).

Figure 46 shows some additional data.  The last conversation in which a call was either placed or received is seen in the column ZLASTCALLMSG (orange box – timestamp can be gotten from the ZWICKR_MESSAGE table), along with the last person that either sent/received anything within the conversation  (ZLASTUSER – red box). The value in the ZLASTCALLMSG column can be matched back to the values in the Z_PK column in the ZWICKR_MESSAGE table.  The value in the ZLASTUSER column can be matched back to the Z_PK column in the ZSECX_USER table. And, finally, as I previously showed in Figure 24, the ZVGROUPID (blue box).

Figure 44
Figure 46.  The last of the ZSECX_CONVO table.

The table ZSECEX_USER, as seen in Figures 47 and 48, contains data about not only the account owner, but also about users who the account holder may be conversing with.  The table contains some of the same information as the Wickr_User table in Android.  In fact, Figure 47 looks very similar to Figure 27.  The values represent the same things as well.

Figure 47
Figure 47.  Hidden status and last activity time.

Figure 48 shows the same items as seen in Figure 26, but, as you can see, the hash values are different, which makes tracking conversation participants using this informaiton impossible.

Figure 48
Figure 48.  Same participants, different hashes.

File transfers in iOS are a bit tricky because some of the data is obfuscated, and in order to figure out which file is which an examiner needs to examine three tables:  Z_11MSG, ZWICKR_MESSAGE, and ZWICKR_FILE.  Figure 49 shows the Z_11MSG table.

Figure 49
Figure 49.  Z_11MSG.

The colum Z_13MSG refers to the ZWICKR_MESSAGE table, with the values 8 and 10 referring to values in the Z_PK column in that table.  See Figure 50.

Figure 50
Figure 50.  Trasferred files.

Obviously, associated timestamps are found in the same row further into the table.  See Figure 51.

Figure 51
Figure 51.  Timestamps for the transferred files.

The column Z_11Files in Figure 49 refers to the ZWICKR_FILE table.  See Figure 52.

Figure 52
Figure 52.  Files with their GUIDs.

The values in Z_11FILES column in Figure 49 refer the values in the Z_PK values seen in Figure 52.  Figure 53 shows the files within the file system.  As I previously mentioned, there are no decrypted versions of these files.

Figure 53
Figure 53.  The file GUIDs from the database table.

Figure 54 shows values ZANONYMOUSNOTIFICATION and ZAUTOUNLOCKMESSAGES values  from the ZSECEX_ACCOUNT table (the Android values were seen in Figure 32).  Both values here are zero meaning I had these features turned off.

Figure 54
Figure 54.  Anonymous Notification and Auto Unlock settings in iOS.

The last table I want to highlight is the ZSECX_APP table.  See Figure 55.

Figure 55
Figure 55.  Users and their associated app installations.

The values in the ZUSER column relate back to the values seen in the Z_PK column in the ZWICKR_USER table.  Each different value in the ZAPPIDHASH represents a different app install on a device.  For example, Test Account 1 appeared on four different devices (iPhone, iPad, Windows, macOS).  This means four different devices each with their own individual installation of Wickr, which translates to a different ZAPPIDHASH value for each individual device.  Knowing a user has multiple devices could be beneficial.  Warning:  be careful, because this isn’t the only way to interpret this data.

As part of the testing, I wanted to see if this value could change on a device, and, as it turns out, it can.  Test Account 2 was only logged in on the Pixel 3.  I installed the app, used it, pulled the data, wiped the Pixel and flashed it with a new install of Android, and then reinstalled Wickr.  I repeated those steps one more time, which means Wickr was installed on the same device three different times, and, as you can see, there are three different hash values for ZUSER 2 (Test Account 2).

The morale of this story is that while this value can possibly represent different devices where a user may be logged in, it actually represents instances of app installation, so be careful in your interpretation.


Wickr is a tough one.  This app presents all sorts of forensic challenges.  At the moment there is very little data that is recoverable, but some insights about communication and app usage can be gleaned from what little data is available.  Sometimes, files can be recovered, and that may be all an examiner/investigator needs.

The good news is, though, there is help on the horizon.

Ridin’ With Apple CarPlay

I have been picking on Google lately.  In fact, all of my blog posts thus far have focused on Google things.  Earlier this year I wrote a blog about Android Auto, Google’s solution for unifying telematic user interfaces (UIs), and in it I mentioned that I am a daily CarPlay driver.  So, in the interest of being fair, I thought I would pick on Apple for a bit and take a look under the hood of CarPlay, Apple’s foray into automotive telematics.

Worldwide, 62 different auto manufacturers make over 500 models that support CarPlay.  Additionally, 6 after-market radio manufacturers (think Pioneer, Kenwood, Clarion, etc.) support CarPlay.  In comparison, 41 auto manufacturers (again, over 500 models – this is an increase since my earlier post) and 19 after-market radio manufacturers support Android Auto.  CarPlay runs on iPhone 5 and later.  It has been a part of iOS since its arrival (in iOS 7.1), so there is no additional app to download (unlike Android Auto).  A driver simply plugs the phone into the car (or wirelessly pairs it if the car supports it) and drives off; a wired connection negates the need for a Bluetooth connection.  The toughest thing about CarPlay setup is deciding how to arrange the apps on the home screen.

In roughly 5 years’ time CarPlay support has grown from 3 to 62 different auto manufacturers.  I can remember shopping for my 2009 Honda (in 2012) and not seeing anything mentioned about hands-free options.  Nowadays, support for CarPlay is a feature item in a lot of car sales advertisements.  With more and more states enacting distracted driving legislation, I believe using these hands-free systems will eventually become mandatory.

Before we get started, let’s take a look at CarPlay’s history.

Looking in the Rearview Mirror

The concept of using an iOS device in a car goes back further than most people realize.  In 2010 BMW announced support for iPod Out, which allowed a driver to use their iPod via an infotainment console in select BMW & Mini models.

iPod Out-1
Figure 1.  iPod Out.  The great-grandparent of CarPlay.
iPod Out-2
Figure 2.  iPod Out (Playback).

The iPod connected to the car via the 30-pin to USB cable, and it would project a UI to the screen in the car.  iPod Out was baked in to iOS 4, so the iPhone 3G, 3GS, 4, and the 2nd and 3rd generation iPod Touches all supported it.  While BMW was the only manufacturer to support iPod Out, any auto manufacturer could have supported it; however, it just wasn’t widely advertised or adopted.

In 2012 Siri Eyes Free was announced at WWDC as part of iOS 6.  Siri Eyes Free would allow a user to summon Siri (then a year old in iOS) via buttons on a steering wheel and issue any command that one could normally issue to Siri.  This differed from iPod Out in that there was no need for a wired-connection.  The car and iOS device (probably a phone at this point) utilized Bluetooth to communicate.  The upside to Siri Eyes Free, beyond the obvious safety feature, was that it could work with any in-car system that could utilize the correct version of the Bluetooth Hands-Free Profile (HFP).  No infotainment center/screen was necessary since it did not need to project a UI.  A handful of auto manufacturers signed on, but widespread uptake was still absent.

At the 2013 WWDC Siri Eyes Free morphed in to iOS in the Car, which was part of iOS 7.  iOS in the Car can be thought of as the parent of CarPlay, and closely resembles what we have today.  There were, however, some aesthetic differences, which can be seen below.

Figure 3.  Apple’s Eddy Cue presenting iOS in the Car (Home screen).
Figure 4.  Phone call in iOS in the Car.
FIgure 5.  Music playback in iOS in the Car.
Screen Shot 2013-06-10 at 12.59.52 PM
Figure 6.  Getting directions.
Screen Shot 2013-06-10 at 2.09.12 PM
Figure 7.  Navigation in iOS in the Car.

iOS in the Car needed a wired connection to the vehicle, or so was the general thought at the time.  During the iOS 7 beta, switches were found indicating that iOS in the Car could, potentially, operate over a wireless connection, and there was even mention of it possibly leveraging AirPlay (more on that later in this post).  Unfortunately, iOS in the Car was not present when iOS 7 was initially released.

The following spring Apple presented CarPlay, and it was later released in iOS 7.1.  At launch there were three auto manufactures that supported it:  Ferrari, Mercedes-Benz, and Volvo.  Personally, I cannot afford cars from any of those companies, so I am glad more manufacturers have added support.

CarPlay has changed very little since its release.  iOS 9 brought wireless pairing capabilities to car models that could support it, iOS 10.3 added recently used apps to the upper left part of the screen, and iOS 12 opened up CarPlay to third party navigation applications (e.g. Google Maps and Waze).  Otherwise, CarPlay’s functionality has stayed the same.

With the history lesson now over, there are a couple of things to mention.  First, this research was conducted using my personal phone, an iPhone XS (model A1920) running iOS 12.2 (build 16E227).  So, while I do have data sets, I will not be posting them online as I did with the Android Auto data.  If you are interested in the test data, contact me through the blog site and we’ll talk.

Second, at least one of the files discussed (the cache file in the locationd path) is in a protected area of iPhone, so there are two ways you can get to it:  jailbreaking iPhone or using a “key” with a color intermediate between black and white. The Springboard and audio data should be present in an iTunes backup or in an extraction from your favorite mobile forensic tool.

Let’s have a look around.

Test Drive

I have been using CarPlay for the past two and a half years.  A majority of that time was with an after-market radio from Pioneer (installed in a 2009 Honda), and the last six months have been with a factory-installed display unit in a 2019 Nissan.  One thing I discovered is that there are some slight aesthetic differences in how each auto manufacturer/after-market radio manufacturer visually implements CarPlay, so your visual mileage may vary.  However, the functionality is the same across the board.  CarPlay works just like iPhone.

Figure 8 shows the home screen of CarPlay.

IMG_0769 2
Figure 8.  CarPlay’s home screen.

The home screen looks and operates just like iPhone, which was probably the idea.  Apple did not want users to have a large learning curve when trying to use CarPlay.  Each icon represents an app, and the apps are arranged in rows and columns.  Unlike iPhone, creating folders is not an option, so it is easy to have multiple home screens. The icons are large enough to where not much fine motor skill is necessary to press one, which means you probably won’t be hunting for or pressing the wrong app icon very often.

The button in the orange box is the home button.  It is persistent across the UI, and it works like the iPhone home button:  press it while anywhere and you are taken back to the home screen.  The area in the blue box indicates there are two home screens available, and the area in the red box shows the most recently used apps.

Most of the apps should be familiar to iPhone users, but there is one that is not seen on iPhone:  the Now Playing app.  This thing is not actually an app…it can be thought of more like a shortcut.  Pressing it will bring up whatever app currently has control of the virtual sound interface of CoreAudio (i.e. whatever app is currently playing or last played audio if that app is suspended in iPhone’s background).

Swiping left, shows my second home screen (Figure 9).  The area in the red box is the OEM app.  If I were to press it, I would exit the CarPlay UI and would return to Nissan Connect (Nissan’s telematic system); however, CarPlay is still running in the background.  The OEM app icon will change depending on the auto maker.  So, for example, if you were driving a Honda, this icon would be different.

IMG_0771 1.jpg
Figure 9.  The second batch of apps on the second home screen.

A user can arrange the apps any way they choose and there are two ways of doing this, both of which are like iPhone.  The first way is to press and hold an app on the car display unit, and then drag it to its desired location.  The second way is done from the screen seen in Figure 10.

Figure 10.  CarPlay settings screen.

The screen in Figure 10 can be found on iPhone by navigating to Settings > General > CarPlay and selecting the CarPlay unit (or units – you can have multiple)…mine is “NissanConnect.”  Moving apps arounds is the same here as it is on the display unit (instructions are present midway down the screen).  Apps that have a minus sign badge can be removed from the CarPlay home screen.  When an app is removed it is relegated to the area just below the CarPlay screen; in Figure 10 that area holds the MLB AtBat app, AudioBooks (iBooks), and WhatsApp.  If I wanted to add any relegated apps to the CarPlay home screen I could do so by pushing the plus sign badge.  Some apps cannot be relegated:  Phone, Messages, Maps, Now Playing, Music, and the OEM app.  Everything else can be relegated.

One thing to note here.  iOS considers the car to be a USB accessory, so CarPlay does have to abide by the USB Restricted Mode setting on iPhone (if enabled).  This is regardless of whether the Allow CarPlay While Locked toggle switch is set to the on position.

The following screenshots show music playback (Figure 11), navigation (Figure 12), and podcast playback (Figure 13).

Figure 11.  Music playback.
Figure 12.  Navigation in CarPlay.
Figure 13.  Podcast playback.

Messages in CarPlay is a stripped-down version of Messages on iPhone.  The app will display a list of conversations (see Figure 14), but it will not display text of the conversations (Apple obviously doesn’t want a driver reading while driving).  Instead, Siri is used for both reading and dictating messages.

Figure 14.  Messages conversation list.

Phone is seen in Figures 15; specifically, the Favorites tab.  The tabs at the top of the screens mirror those that are seen on the bottom in the Phone app on iPhone (Favorites, Recents, Contacts, Keypad, and Voicemail).  Those tabs look just like those seen in iPhone.

Figure 15.  Phone favorites.
Figure 16.  The keypad in Phone.

If I receive a phone call, I can answer it in two ways:  pressing the green accept button (seen in Figure 17) or pushing the telephone button on my steering wheel.  Answering the call changes the screen to the one seen in Figure 18.  Some of the items in Figure 18 look similar to those seen in iOS in the Car (Figure 4).

Figure 17.  An incoming call.
Figure 18.  An active phone call.

Most apps will appear like those pictured above, although, there may be some slight visual/functional differences depending on the app’s purpose, and, again, there may be some further visual differences depending on what car or after-market radio you are using.

Speaking of purpose, CarPlay is designed to do three things:  voice communication, audio playback, and navigation.  These things can be done fairly well through CarPlay, and done safely, which, I believe, is the main purpose.  Obviously, some popular apps, such as Twitter or Facebook, don’t work well in a car, so I don’t expect true social media apps to be in CarPlay any time soon if at all (I could be wrong).

Now that we have had a tour, let’s take a look under the hood and see what artifacts, if any, can be found.

Under the Hood

After snooping around in iOS for a bit I came to a realization that CarPlay is forensically similar to Android Auto:  it merely projects the apps that can work with it on to the car’s display unit, so the individual apps contain a majority of the user-generated data.  Also, like Android Auto, CarPlay does leave behind some artifacts that may be valuable to forensic examiners/investigators,  and, just like any other artifacts an examiner may find, these can be used in conjunction with other data sources to get a wholistic picture of a device.

One of the first artifacts that I found is the cache.plist file under locationd.  It can be found in the private > var > root > Library > Caches > locationd path.  cache.plist contains the times of last connect and last disconnect.  I did not expect to find connection times in the cache file of the location daemon, so this was a pleasant surprise.  See Figure 19.

Figure 19.  Last connect and last disconnect times.

There are actually three timestamps here, two of which I have identified.  The timestamp in the red box is the last time I connected to my car. It is stored in CF Absolute Time (aka Mac Absolute Time), which is the number of seconds since January 1, 2001 00:00:00 UTC.  The time, 576763615.86389804, converts to April 12, 2019 at 8:06:56 AM (EDT).  I had stopped at my favorite coffee shop on the way to work and when I hopped back in the car, I plugged in my iPhone and CarPlay initialized.  See Figure 20.

Figure 20.  Time of last connect.

The time stamp in the green box just under the string CarKit NissanConnect, is a bit deceptive.  It is the time I disconnected from my car.  Decoding it converts it to April 12, 2019 at 8:26:18 AM (EDT).  Here, I disconnected from my car, walked into work, and badged in at 8:27:14 AM (EDT).  See Figure 21.

Figure 21.  Time of last disconnect.

The time in the middle, 576764725.40157998, is just under a minute before the timestamp in the green box.  Based on my notes, it is the time I stopped playback on a podcast that I was listening to at the time I parked.  I also checked KnowledgeC.db (via DB Browser for SQLite) and found an entry in it for “Cached Locations,” with the GPS coordinates being where I parked in my employer’s parking lot.  Whether the middle timestamp represents the time the last action was taken in CarPlay is a good question and requires more testing.

The next file of interest here is the file.  It can be found by navigating to the private > var > mobile > Library > Preferences path.  See Figure 22.

Figure 22.  carplay.plist

The area in the red box is of interest.  Here the name of the car that was paired is seen (NissanConnect) along with a GUID.  The fact that the term “pairings” (plural) is there along with a GUID leads me to believe that multiple cars can be paired with the same iPhone, but I wasn’t able to test this as I am the only person I know that has a CarPlay capable car.  Remember the GUID because it is seen again in discussing the next artifact.  For now, see Figure 23.

Figure 23.  Main CarPlay setting page in iOS.

Figure 23 shows the settings page just above the one seen in Figure 10.  I show this merely to show that my car is labeled “NissanConnect.”

The next file is 10310139-130B-44F2-A862-7095C7AAE059-CarDisplayIconState.plist.  It can be found in the private > var > mobile > Library > Springboard path.  The first part of the file name should look familiar…it is the GUID seen in the file.  This file describes the layout of the home screen (or screens if you have more than one).  I found other files in the same path with the CarDisplayIconState string in their file names, but with different GUIDs, which causes me to further speculate that multiple CarPlay units can be synced with one iPhone.  See Figure 24.

Figure 24.  CarPlay Display Icon State.

The area in the red and blue boxes represent my home screens.  The top-level Item in the red box, Item 0, represents my first home screen, and the sub-item numbers represent the location of each icon on the first home screen.  See Figure 25 for the translation.

Figure 25.  Home screen # 1 layout.

The area in the blue box in Figure 24 represents my second home screen, and, again, the sub-item numbers represent the location of each icon on the screen.  See Figure 26 for the translation.

Figure 26.  Home screen # 2 layout.

The entry below the blue box in Figure 24 is labeled “metadata.”  Figure 27 shows it in an expanded format.

Figure 27.  Icon state “metadata.”

The areas in the green and purple boxes indicate that the OEM app icon is displayed, and that it is “Nissan” (seen in Figure 26).  The areas in the orange and blue boxes describe how the app icon layout should be (four columns and two rows).  The area in the red box is labeled “hiddenIcons,” and refers to the relegated apps previously seen in Figure 10.  As it turns out, the items numbers also describe their position.  See Figure 28.

Figure 28.  Hidden icon layout.

Notice that this file did not describe the location of the most recently used apps in CarPlay (the area in the upper left portion of the display screen).  That information is described in, which is found in the same path.  See Figure 29.

Figure 29.  Springboard and most recently used apps.

Just like the app icon layout previously discussed, the item numbers for each most recently used app translate to positions on the display screen.  See Figure 30 for the translation.

IMG_0769 1
Figure 30.  Most recently used apps positions.

The next file is the, which is found in the private > var > mobile > Library > Preferences path.  This file had a bunch of data in it, but there are three values in this file that are relevant to CarPlay.  See Figure 31.

Figure 31.  Celestial.

The string in the green box represents what app had last played audio within CarPlay prior to iPhone being disconnected from the car.  The area in blue box is self-explanatory (I had stopped my podcast when I parked my car).  The item in the red box is interesting.  I had been playing a podcast when I parked the car and had stopped playback.  Before I disconnected my iPhone, I brought the Music app to the foreground, but did not have it play any music, thus it never took control of the virtual sound interface in CoreAudio. By doing this, the string in the red box was generated.  Just to confirm this, I tested this scenario a second time, but did not bring the Music app to the foreground; the value nowPlayingAppDisplayIDUponCarPlayDisconnect was not present in the second plist file.  I am sure this key has some operational value, although I am not sure what that value is.  If anyone has any idea, please let me know.

As I mentioned earlier in this post, Siri does a lot of the heavy lifting in CarPlay because Apple doesn’t want you messing with your phone while you’re driving.  So, I decided to look for anything Siri-related, and I did find one thing…although I will say that this  is probably not exclusive to CarPlay.  I think this may be present regardless of whether it occurs in CarPlay or not (more testing).  In the path private > var > mobile > Library > Assistant there is a plist file named PreviousConversation (there is no file extension but the file header indicates it is a bplist).  Let me provide some context.

When I pick up my child from daycare in the afternoons, I will ask Siri to send a message, via CarPlay, to my spouse indicating that my child and I are on the way home, and she usually acknowledges.  The afternoon before I extracted the data from my iPhone (04/11/2019), I had done just that, and, after a delay, my spouse had replied “Ok.”

PreviousConversation contains the last conversation I had with Siri during this session. When I received the message, I hit the notification I received at the top of the CarPlay screen, which triggered Siri.  The session went as so:

Siri:                 “[Spouse’s name] said Ok.  Would you like to reply?”

Me:                  “No.”

Siri:                 “Ok.”

See Figure 32.

FIgure 32.  Session with Siri.

The area in the red box is the name of the sender, in this case, my spouse’s (redacted) name.  The orange box was spoken by Siri, and the blue box is the actual iMessage I received from my spouse.  The purple box is what was read to me, minus the actual iMessage.  Siri’s inquiry (about my desire to reply) is seen in Figure 33.

Figure 33.  Would you like to reply?

Figure 34 contains the values of the message sender (my spouse).  Inside of the red box the field “data” contains the iMessage identifier…in this case, my spouse’s phone number.  The field “displayText” is my spouse’s name (presumably pulled from my Contact’s list).  Figure 35 has the message recipient information:  me.

Figure 34.  Message sender.
Figure 35.  Message recipient (me) plus timestamp.

Figure 35 also has the timestamp of when the message was received (orange box), along with my spouse’s chat identifier (blue box).

Figure 36.  Siri’s response.

Figure 36 shows Siri’s last response to me before the session ended.

Interesting note:  this plist file had other interesting data in it.  One thing that I noticed is that each possible response to the inquiry “Would you like to reply?” had an entry in here:  “Call” (the message sender), “Yes” (I’d like to reply), and “No” (I would not like to reply).  It might be a good research project for someone.  🙂

The next artifact actually comes from a file previously discussed:  While examining this file I found something interesting that bears mentioning in this post.  My iPhone has never been paired via Bluetooth with my 2019 Nissan.  When I purchased the car, I immediately started using CarPlay, so there has been no need to use Bluetooth (other than testing Android Auto).  Under the endointTypeInfo key I found the area seen in Figure 37.

Figure 37.  What is this doing here?

The keys in the red box contain the Bluetooth MAC address for my car.  I double-checked my Bluetooth settings on the phone and the car, and the car Bluetooth radio was turned off, but the phone’s radio was on (due to my AppleWatch).  So, how does my iPhone have the Bluetooth MAC address for my car?  I do have a theory, so stay with me for just a second.  See Figure 38.

Figure 38.  AirPlay indicator.

Figure 38 shows the home screen of my iPhone while CarPlay is running.  Notice that the AirPlay/Bluetooth indicator is enabled (red box).  Based on some great reverse engineering, it was found that any device that uses the AirPlay service will use its MAC address in order to identify itself (deviceid).  Now, see Figure 39.

Figure 39. Virtual Audio Interfaces for AirPlay and CarPlay.

Figure 39 shows two files, both of which are in the Library > Audio > Plugins > HAL path.  The file on the left is the info.plist file for the Halogen driver (the virtual audio interface) for AirPlay and the file on the right is the info.plist file for the Halogen driver for CarPlay.  The plug-in identifiers for each (both starting with EEA5773D) are the same.  My theory is that CarPlay may be utilizing AirPlay protocols in order to function, at least for audio.  I know this is a stretch as those of us that use AirPlay know that it typically is done over a wireless connection, but I think there is a small argument to be made here.  Obviously, this requires more research and testing, and it is beyond the scope of this post.


CarPlay is Apple’s attempt at (safely) getting into your car.  It provides a singular screen experience between iPhone and the car, and it encourages safe driving.  While a majority of the user-generated artifacts are kept by the individual apps that are used, there are artifacts specific to CarPlay that are left behind.  The app icon layout, time last connected and disconnected, and last used app can all be found in these artifacts.  There are also some ancillary artifacts that may also be useful to examiners/investigators.

It has been a long time since I really dug around in iOS, and I saw a lot of interesting things that I think would be great to research, so I may be picking on Apple again in the near future.