They say imitation is the sincerest form of flattery, and that is my intention here. Late last year Heather Mahalik & Ian Whiffan put out an article describing how examiners can detect when an iOS device is wiped. It is a great article, one every examiner should bookmark and read because it is guaranteed an examiner will have that question asked of them at some point if they do mobile forensics. The article can be found here.
Recently I saw a couple of users on DFIR Discord ask the same question about Android devices. After doing some digging, I discovered no one had really addressed Android factory resets (wipes) before (if they have, I was unable to find it), so I thought it would be great to look into it.
Like Heather and Ian, I want to make it clear that just because a wipe is detected does not mean the user was intentionally trying to be malicious. There are a lot of legitimate reasons a user may wipe their device, so it is up to the examiner/investigator to determine the motivation of the user.
Testing involved a few different sources: my Android 10 and 11 images, and new data generated using my Pixel 3 running Android 11 (August 2021 patch). I also used a Samsung Galaxy A30 running Android 10 (March 2020 patch) & Android 11 (April 2021 - latest supported patch at the time). The Samsung was upgraded from Android 10 to 11 during this exercise (more on that later). I considered what was available in both rooted and non-rooted states, what was available using open source tools, and considered four different scenarios which I may refer to occasionally in this article:
A user resets their phone and completes the setup process.
A user resets their phone, partially completes the setup process, but leaves the phone in the setup state for an extended period of time prior to completion. Then the user starts to use the phone and completes the setup process at a later time.
A user resets their phone, but leaves the device at the initial setup screen. The phone is seized in this state and requires the examiner to set the phone up offline in order to perform the extraction.
A user resets their phone, sets the phone up “offline” but contemporaneous to the wipe, and then completes the online setup (i.e. signs into their Google account) at a later time.
During testing the devices were wiped using two different methods: via the Android UI and via Recovery. After the wipes, the phones were setup as both new and restored from backups.
As far as tools, a few different ones were used:
DB Browser for SQLite (3.12.2)
Cellebrite UFED (18.104.22.168)
Cellebrite Physical Analyzer (22.214.171.124)
TextMate for macOS (2.0.19)
Android Triage Tool (1.2)
The good news is that there are artifacts examiners can use to determine the approximate time an Android phone was wiped. There were a few files that initially appeared to be good candidates, but, because there were so many caveats with them, I decided not to document them here as they could be unreliable depending on the scenario. Some of the files documented here do have caveats, which I will describe so that an examiner can make a determination about the usability of the timestamp as it relates to their examination.
Because this is Android, things are a little messy as the artifacts are scattered throughout the operating system. The availability of these files depends on the OEM, how the OEM implemented Android, the version of Android itself, and the level of access to the phone file system (i.e. root/not root). This blog post only addresses the Pixel (the "purest" version of Android) and Samsung (one of if not the most popular Android OEMs) line of phones, but other OEMs may implement Android in different ways that may alter the artifacts available on their respective devices.
Additionally, mobile carriers may install custom applications on Android that may also contain artifacts that can help an examiner approximate a time of wipe. Those types of artifacts are not addressed in this blog post.
Nuts & Bolts
The first file is suggestions.xml, and it is found in the same location in Android 10, & 11: /data/data/com.google.android.settings.intelligence/shared_prefs. There is an additional location in Android 11: /data/user/%USER%/com.google.android.settings.intelligence/shared_prefs. Because of its location, an examiner would need a full file system extraction (or access to /data/data). There was good news, however, for Android 11: the file was available in both a full file system and advanced logical extraction in Cellebrite.
There are two XML tags in this file that contain timestamps that reflect the approximate time of the wipe:
Figure . DEFERRED_SETUP_setup_time.
Figure . FingerprintEnrollSuggestionActivity_setup_time.
The titles of both tags are a bit deceptive. Each tag contained a timestamp that was indicative to the approximate time of the wipe, regardless of whether the user started the setup process immediately following the factory reset (including the option to enroll a fingerprint on the device).
To validate this finding, we turned to the public Android images. Figure 3 shows suggestions.xml and the documentation from Android 10, and Figure 4 shows suggestions.xml and the documentation from Android 11. Note that both images were clean installs; Android was flashed to the device using ADB. Again, note that the times are approximate. On the Android 10 image, the exact time of flashing is not documented, but, I did connect the Pixel to the wireless network right after wiping it.
Figure . Android 10 suggestion.xml and documentation excerpt (time in UTC -0500).
Figure . Android 11 suggestion.xml and documentation excerpt (time in UTC -0400).
One additional note here: the folder com.google.android.settings.intelligence was not found on the Samsung phone, so an examiner will likely find this folder, and suggestions.xml, to be absent.
The next file is setup_wizard_info.xml, which is in the same location as suggestions.xml. The previous caveats about extraction availability and Samsung phones apply, and there is one additional caveat: this file was observed in Android 11 only.
There is a single XML tag in this file, suw_finished_time_ms. See Figure 5.
Figure . suw_finished_time_ms.
The title of this tag also does not fully match what it represents. In testing, this timestamp represented the approximate time when a device was wiped regardless of whether a user initiates the setup process immediately following the wipe. To validate, I went back to the public Android 11 image. See Figure 6.
Figure . Android 11 suw_finished_time_ms.xml and documentation excerpt (time in UTC -0400).
The next file is persistent_properties. The file is located in /data/property, and was found in both the Samsung and Pixel. This file, while extension-less, can be viewed in any text editor/viewer, and was only available in a full file system extraction. Searching for the string reboot,factory_reset found a Unix Epoch timestamp associated with the entry which represents the time of the wipe. See Figures 7 (Pixel) and 8 (Samsung).
Figure . reboot,factory_reset in persistent_properties from the Pixel.
Figure . reboot,factory_reset in persistent_properties from the Samsung.
Four notes here. First, the timestamp was consistent across all scenarios on both the Pixel and Galaxy A30. Second, this file keeps track of booting history. Based on testing, it keeps track of the three previous boot times on the Pixel. So, if the phone has rebooted more than three times since the last wipe, the reboot,factory_reset string and associated timestamp will not be present in this file. Examiners should be aware of this log roll off. Some of the commercial tools available to us do cause a device reboot in order to successfully access the file system of the device. Doing so may cause the factory_reset timestamp to roll off prior to extraction. This timestamp can also roll off even after three or more reboots in scenario 3. There is a way to mitigate this "too many reboots" issue, which is described below.
As an example of too many reboots, Figure 9 shows persistent_properties from the Pixel after rebooting three times after the last wipe. Notice the string 'userrequested.' The two times associated with that string represent me manually rebooting the Pixel via the UI.
Figure . reboot,factory_reset timestamp is missing after three reboots.
Third note: this timestamp is available without root access. Using Mattia Eppafani’s Android Triage tool, an examiner can find this data without the need for root access or a reboot of the device, which can help mitigate the issue described above. Executing the “Collect Basic Information” option in Android Triage will generate a series of text files, one of which is getprop.txt. This file will also contain the string reboot,factory_reset, along with the Unix Epoch timestamp which is approximate to when the device was wiped. See Figure 10 for the getprop.txt file from the Pixel.
Figure . reboot,factory_reset in getprop.txt from the Pixel.
To validate this data, I again turned to the Android 11 image and documentation. See Figure 11.
Figure . persistent_properties from the Android 11 image with documentation excerpt.
Note that the reboot,factory_reset string was missing in the Android 10 public image documentation, but this is not surprising as there were multiple reboots of the device, which would have caused the factory_reset timestamp to roll off. I did, however, find it in the Samsung A30, which was running Android 10. It also contained four (4) timestamps, which is one more than the Pixel.
Figure . reboot,factory_reset in persistent_properties from the Samsung.
And, finally, the fourth note. During validation, it was noted that this timestamp was not correct on one of test validation devices (a Samsung Galaxy S10e; however, the timestamp was accurate in all scenarios, and between Android 10 and 11 on my Galaxy A30 and the Pixel. An attempt was made to recreate the timestamp from S10e device by re-flashing the Pixel to Android 10 and then upgrading to Android 11, which also failed to recreate the incorrect timestamp. This just goes to show how Android can be a bit finicky at times between OEMs and OEM models. Corroboration with other data on the device is extremely important!
The next file, appops.xml, appears to track application operations, and is located in the /data/system/ directory path. It can have quite a bit of data in it, but for the Pixel, there was one XML tag that was pertinent: com.google.android.setupwizard. See Figure 13.
Figure . setupwizard in appops.xml
This tag has multiple timestamps associated with it, and there may be multiple com.google.android.setupwizard XML tags in this file. Finding the earliest timestamp (regardless of which XML tag if there are multiple), chronologically, was a good indication of approximate time of wipe.
The Samsung, as expected, looked a little different. Samsung phones have their own setup application: com.sec.android.app.SecSetupWizard. This wizard and the Google wizard work together to facilitate the setup process. In appops.xml on Samsung phones the XML tag com.sec.android.SecSetupWizard can be used in much the same way as the Google wizard tag by finding the earliest chronological timestamp. Again, this is an approximate time of wipe. See Figure 14.
Figure . com.sec.android.app.SecSetupWizard in Samsung appops.xml.
Do note that the timestamp will not be accurate in a situation such as scenario 3.
The next file is a Samsung exclusive. swlpdb.db is a database that tracks when a user agrees to the EULA for the device. It can be found in /data/data/com.sec.android.app.setupwizardlegalprovider/databases. The good news about this file is that it is available in a Cellebrite Advanced Logical extraction as well as a full file system. The table of interest is db_agreement, which tracks when the user agrees to the EULA. The times are stored in UTC. See Figure 15.
Figure . db_agreement.
After the wipe, the Samsung phone rebooted and the phone displayed the welcome screen, which was followed by the EULA screen. While this time was accurate when the EULA was agreed to contemporaneous to the wipe, it would not be accurate during scenario where there was a delay between wipe and initial setup, such as scenario 3. As an example, the timestamp seen in Figure 14 is approximately 8 minutes after I wiped the Samsung because I purposely waited to do so.
The next file is also a Samsung exclusive: history. It can be found in the /efs/recovery/ directory path, and, while it is extension-less, it can be read by any text editor/reader. This file is available in a full file system extraction only. Not only does it contain an approximate time of wipe, but it also contains a history of wipes. I wiped the Samsung phone three (3) different times during this research (last one being on 2021-08-15 at 16:34 UTC -0400) and found references to all three in this file. Additionally, the historical wipe data is persistent across upgrades. After I upgraded the phone from Android 10 to 11, history retained data about the previous wipes in Android 10.
See Figures 16, 17, and 18. While only three are shown here, be aware there may be more '--wipe_data' timestamps in this file.
Figure . history (1st wipe).
Figure . history (2nd wipe).
Figure . history (3rd wipe).
One thing to note about history. The figures above document how history entries look when the wipe is done via the Android UI. However, entries look a little different if the wipe is initiated from Recovery. See Figure 19.
Figure . Entry for wipe initiated from Recovery.
The entry is substantially less verbose than the previous ones. The red box represents when I initiated the wipe from Recovery, and the blue box represents when I rebooted after the wipe. Examiners should be aware of this difference.
eRR.p is also a Samsung exclusive. See Figure 20.
Figure . eRR.p from the Samsung.
Heather put me on this file. It is located in the /data/system/users/service/data/ directory path. While I was not able to find any documentation about what its actual purpose was, it, too, appears to keep a history of device boots along with what caused the boot (recovery, userrequested, adb). It also accurately reflects the approximate time of the last wipe that occurred. The wipe time is highlighted in the red box in Figure 16, and is the lone timestamp in UTC. The remaining timestamps are in UTC -0400, which is the current offset where I live. Figure 21 shows the boot history eRR.p keeps.
Figure . eRR.p boot history.
Just be aware that the contents of this file may not look exactly like that seen in Figures 20 and 21.
An additional note here. During validation it was noted that this file had a single entry on Heather's test device, which had a timestamp in her local time. Some follow-up testing found that restoration from backups can affect the earliest chronological timestamp. When a Samsung device is restored from a backup (from Google Drive), the earliest timestamp in eRR.p indicates the time the device was restored, and is displayed in local time.
The next artifact is Digital Wellbeing. I wrote a lengthy article about it last year, which you can read here. Digital Wellbeing, or digital wellbeing-like features, are required on all phones that ship with Android 10 or higher, or are upgraded to Android 10 or higher, so an examiner can expect to find it on most modern Android phones.
To summarize, Digital Wellbeing is tracking everything on an Android device, including device power ups/downs, phone unlocks (and locks on Samsung phones), and when applications move to and from the foreground. For the Pixel, the database file app_usage is found in /data/data/com.google.android.apps.wellbeing/databases/, and is only available in a full file system extraction. The data is spread across multiple tables, but a quick SQL query pulled the data together. Again, see the article for the query. Once it was run, the results were sorted chronologically. Figure 22 shows the output from the Pixel.
Figure . Beginning of Digital Wellbeing from the Pixel.
Notice that the first entry in the database is NOT a device startup, which was an interesting find. In fact, a device reboot is not detected until rows 13 & 14 (Figure 22 - red box). After the reboot, the package com.google.android.setupwizard is seen pausing and resuming a bit in Figure 23 (blue box). This is indicative of the setup process starting, and, thus, a wipe which occurred just prior at 20:39 UTC. Note that the entries in the database may not look exactly like this, so it’s up to the examiner to interpret the data here and corroborate it with other data to make a determination about whether it represents a wipe event.
Figure . Setupwizard pausing and resuming.
One additional note here. There is no documentation available about how long Digital Wellbeing keeps its data. The longest I've seen and examined is approximately two (2) weeks, and this was on the Pixel. Samsung looks to have a Digital Wellbeing retention time of seven (7) days before the logs start rolling off.
Because Samsung has their own version of Digital Wellbeing, things were a little different for the A30. The file dwbCommon.db is found in /data/data/com.samsung.android.forest/databases, and is also available only in a full file system extraction. The query (also found in the aforementioned article) looks a little different, but the output was similar. See Figure 24.
Figure . Beginning of Digital Wellbeing from the Samsung.
Unlike the Pixel, the first entry here is a device start. Because Samsung's Digital Wellbeing solution keeps additional data that is not seen in Google's version, there will be additional codes in this database. One of which is event Type 12 (STANDBY_BUCKET_CHANGED). This event type appeared for 173 rows before other packages started to appear, including com.google.android.setupwizard (red box - Figure 25) and com.sec.android.app.SecSetupWizard (blue box - Figure 25).
Figure . Google Setup Wizard and Samsung Setup Wizard.
To validate the findings, I went back to Digital Wellbeing from the Android 10 public image. Figure 26 shows a device startup (red box) as the first entry (again, the device was flashed prior to generating data for the public image) with entries from com.google.android.setupwizard following shortly thereafter.
Figure . Android 10 Digital Wellbeing (time in UTC).
The last file is internal.db, which documents storage on an Android device. It has a companion database, external.db, which I wrote an article on last year, and is very similar to a $MFT file in Windows in that it documents metadata about files including the date the files were added to the device. internal.db is created as a result of the android.provider.MediaStore class. It was present in both the Pixel and Galaxy A30 phones, and only available in full file system extractions. In the Pixel it was located in the following locations in Android 10 and 11, respectively:
On the Galaxy A30, it was located in
Sorting the database table files from the Galaxy A30 chronologically using the column date_added renders what is seen in Figure 27. Note that the files/folders are system files and folders, not ones that would typically be added by a user, and definitely not locations that are typically accessible to a user.
Figure . internal.db from the A30 sorted by date_added.
The red box in Figure 27 shows several entries with the same timestamp (there were more - this is only an excerpt). When converted from Unix Epoch, this is 2021-08-19 at 11:03:30 UTC -0400, and is an approximate time of wipe. To confirm I went back to the file history (example seen in Figures 16, 17, and 18) we find what is seen in Figure 28.
Figure . history from the A30.
Approximately 5 minutes prior to the timestamps in Figure 27, there is an entry for a wipe at 10:58:25 UTC -0400. I will note the A30 was painfully slow during boot taking around 4-5 minutes to boot after wipe, so this time makes sense.
To validate this, I returned to the public Android 10 and 11 images.
Figure . Excerpt from public Android 11 image documentation (UTC -0400).
Figure . internal.db from public Android 11 image.
Figure . Excerpt from public Android 10 image documentation (UTC -0500).
Figure . internal.db from public Android 10 image.
There is nothing worse for a mobile device examiner than being handed a device that shows the "Welcome" or "Hi There" screen. Typically, that means the device was wiped, and any data that was there is gone. While the user data may be gone there can be great investigative value in knowing when the device was wiped, and now, with the artifacts described in this article, examiners can determine exactly that.
Again, I do want to thank Alexis, Heather, and Jared for their extremely helpful insight on this one. This post would not have turned out the way it did without their insights. This was a total team effort.
Alexis Brignoni, in his customary fashion, has already outfitted his ALEAPP tool to parse the artifacts discussed in this article. Head over to his GitHub page and download the latest copy along with the other super-useful tools he writes.
It's funny what you find when you are looking for other things. Last week I pushed out a public Android 12 image, and while I was looking around for things that had changed between Android 11 and 12, I stumbled across the /data/misc/bootstat folder in Android 12. Take a look at Figure 33.
Figure . Android 12 bootstat folder.
The red box in Figure 33 highlights a file factory_reset along with that file's Modified Time. Now take a look at Figures 34 and 35, both of which are excerpts from the Android 12 public image documentation.
Figure . Flashed time for Android 12 image (UTC -0400).
Figure . Android 12 reboot after flashing (UTC -0400).
factory_reset is an empty file, but its Modified Time is indicative of when the Pixel 3 was flashed to start the creation of the Android 12 image. If you happen to do iOS forensics, this is the same type of behavior for the .obliterated file (thanks to Kevin Pagano for the analogy).
Figure 33 also highlights the file last_boot_time_utc (blue box). Note the Modified Time and then see the blue box in Figure 36, which is also an excerpt from the Android 12 public image documentation.
Figure . Last boot time (UTC -0500).
Figure 36 shows the Pixel 3 booting after the battery died. While I was observing it, I couldn't tell exactly when it booted, but the boot screen was present between 07:27 and 07:29 (UTC -0500). Based on the Modified Time of factory_reset I know it booted at 07:28.
Interestingly enough, /data/misc/bootstat is also present in Android 11. Take a look at Figure 37, which is from the Android 11 public image.
Figure . bootstat in Android 11.
factory_reset is also present here (red box). Note the Modified Time and then see Figures 38 and 39, which are from the Android 11 public image documentation.
Figure . Flashed time for Android 11 image (UTC -0400).
Figure . Android 11 reboot after flashing - red box (UTC -0400).
As can be seen, the Modified Time of factory_reset in Android 11 is also indicative of the time the Pixel 3 was wiped.
Figure 37 also has the file last_boot_time_utc (blue box). In Figure 39 the last boot time of the device is also seen (blue box) (UTC -0400).
I also took a look at the Samsung Galaxy A30, which was running Android 11. The /data/misc/bootstat directory was present, as were the factory_reset and last_boot_time_utc files. The Modified Times for both files were indicative of the last time of reset based on my notes. See Figures 40 and 41.
Figure . factory_reset from the Galaxy A30.
Figure . last_boot_time_utc from the Galaxy A30.
To further test this, I reset a second Pixel 3 in both Android 10 and 11 from the Android UI, and found the Modified Time for both factory_reset and last_boot_time_utc were both indicative of the time of last reset and last boot, respectively. See Figures 42 and 43.
Figure . Second Pixel 3 files in Android 11.
Figure . Second Pixel 3 files in Android 12.
A few notes. First, the /data/misc/bootstat is relatively new. It was not present in any of the earlier Android public images (10 and below). Second, a full file system extraction is needed; these files were not present in a backup on either device. Third, even though the examples from the public images are from when the device was flashed, the timestamps still hold up when doing a factory reset from the Android UI; figures 42 and 43 reflect that. And finally, an examiner could potentially get these timestamps by running bootstat -p via ADB, but I found that root was needed to do so. Sample output of bootstat is seen in Figure 37. It comes from the second Pixel 3 running Android 12, and aligns with the highlighted times seen in Figure 44.
Figure . bootstat output from the Pixel 3 in Android 12.
This update was the result of me poking around in one of my public images, which led me to another public image, and a light bit of testing. It just goes to show that you never know what you will find until you start looking.
Overall, this is a very good, very detailed article. It includes several methods/files that can be used to find the setup timestamp, covering several eventualities. The different Android versions coupled with all the different wiping/install/flashing scenario's really strengthen the validity of the testing.
It is the type of question that all examiners get asked and may not know how to answer. This paper gives not only the knowledge of how to find the answers, but a document that can be referenced by the examiner in the future. There is a direct value add for practitioners and its application in forensic analysis.
The paper also outlines it's own limitations to full extractions from Pure Android and Samsung devices and acknowledges that other device manufacturers may have different results. It may have been useful to highlight the actual time of the wipe early on, before showing the artifacts recovered/found. A reviewer also suggested it might be helpful to include an appendix or a chart with all the files listed, their location within Android, and whether or not the file was able to be obtained logicially or if a FFS was needed.
Some future work could include looking into additional phone manufacturers to see what additional artifacts could be found specific to them. Future releases of the Android OS could also be examined, as well as OEMs that follow Samsung in popularity.
Karan Dwivedi (Methodology Review)
Cesar Quezada (Methodology Review)
Ian Whiffin (Methodology Review, Verified Review Using Author Provided Data Sets)