“TikTok will honor formal requests to preserve user information for 90 days. TikTok will preserve information for an additional 90-day period upon receipt of a formal request to extend the preservation. We may not honor multiple extension requests beyond one additional 90-day period. If TikTok does not receive formal legal process for the preserved information before the end of the preservation period, the preserved information may be deleted when the preservation period expires.
Preservation requests must be sent on law enforcement letterhead, signed, and must include information regarding the specific username to be preserved. In addition, the preservation request must include a statement about the steps being taken to obtain a court order or other legal process for the data sought.”
Notable reported instances involving Tiktok include celebrities receiving abusive content [1], hosting self-harm/suicide-depicting content [2; 5], offensive and racist content [3; 4; 6; 7] and indecent imagery [8].
In regards to analysis of TikTok, the following examples of forensic examination of the TikTok application exist:-
Academic publications:-
Khoa, N.H., Duy, P.T., Do Hoang, H. and Pham, V.H., 2020, October. Forensic analysis of TikTok application to seek digital artifacts on Android smartphone. In 2020 RIVF International Conference on Computing and Communication Technologies (RIVF) (pp. 1-5). IEEE.
Domingues, P., Nogueira, R., Francisco, J.C. and Frade, M., 2020, August. Post-mortem digital forensic artifacts of TikTok Android App. In Proceedings of the 15th International Conference on Availability, Reliability and Security (pp. 1-8).
Figure 2 provides an overview of the methodology utilised during testing. The test device was an iPhone 6s running iOS version 13.2. The device was jailbroken using the Checkra1n exploit, where OpenSSH was installed upon the device and WinSCP (5.15.5) used to access filesystem content. TikTok version 17.6.0 was installed on the device. Test data generation was iterative. Single device actions were performed, designed to explore each individual function of the TikTok application, followed by an extraction of the applications ‘folder’ from the device. Multiple actions for each app function were performed in an attempt to establish reliable behaviour and evidence interpretation.
* Important:- All findings discussed have been found to be present in the described test environment above. It is hoped that these are transferable to other investigative scenarios but this cannot be guaranteed.
Figure 2: An outline of the test methodology.
3 Account information
Current user account information is located in the ‘com.zhiliaoapp.musically.plist’, a binary .plist file (located at ‘<Application Folder>/Library/Preferences/com.zhiliaoapp.musically.plist’). The value stored in key ‘<key>AppsFlyerOriginalUserId</key>’ on testing appears to correspond with the first time that a user downloads the TikTok application.
3.1 Account names and usernames
It is important to note that accounts maintain two identifiers, a ‘name’ and a ‘username’. Whilst account ‘names’ can be changed at any time, ‘usernames’ can only be changed once every 30 days. When searching for account metadata, practitioners should be aware when analysing the ‘com.zhiliaoapp.musically.plist’, standard keyword searching techniques may not identify account information. Content in the ‘com.zhiliaoapp.musically.plist’ is stored in a series of nested .plist files, each encoded in BASE64. Therefore practitioners must analyse the toplevel plist, extract and decode the chunks of BASE64 content, then review the encoded .plist (Figure 3). Plists can be viewed either through a dedicated mobile forensic software platform or a viewer like Notepad++ with the bplist plugin. BASE64 data can be decoded using services like CyberChef (http://icyberchef.com/).
Figure 3: Extracting encoded .plist files.
An account which is currently logged into the TikTok application has details stored in the encoded .plist under the ‘<key>kDYACurrentLoginUserPersistenceKey</key>’ key (shown in Figure 4).
Figure 4: The BASE64 encoded ‘<key>kDYACurrentLoginUserPersistenceKey</key>’ plist
Information about currently logged in users was found to be consistently present during testing as part of the string text shown in Figure 5 (BASE64 decoded ‘<key>kDYACurrentLoginUserPersistenceKey</key>’ key), where MickMouse77 is the account ‘name’ and @Terryblue9 is the account ‘username’ (where testing suggested usernames are preceded by an ‘@’ symbol). The URL starting with 'https://m.tiktok.com/' can be used to view the profile of the user account online, if it is public
Figure 5: String text containing the ‘name’ and ‘username’ of the current TikTok account.
3.1.1 Changes to the account username
Changes to the account username can be identified in the file ‘heimdallr.db’ (located <Application Folder>/Library/Heimdallr/heimdallr.db), with specific attention drawn to the ‘HMDHTTPDetailRecord’ table. This database is discussed later in Section 3.4 in relation to identifying user search terms, but also reveals username changes. Values stored in the ‘absoluteURL’ column in the ‘HMDHTTPDetailRecord’ table should be examined where string contents may contain the value ‘unique_id=’ which directly precedes the account username. ‘absoluteURL’ values can be chronologically ordered based on the ‘timestamp’ value (UNIX timestamp) within the table to show the time and dates where an account ‘username’ changes value. When a ‘username’ changes, future records show a different username proceeding the ‘unique_id=’ in later records, whilst records showing the old username are still present in the database (see Figure 6).
Figure 6: ‘HMDHTTPDetailRecord’ table showing an account ‘username’.
3.2 Account profile picture
The encoded .plist found under the ‘<key>NHAccountManagerCustomUsersKey</key>’ key contains links which when followed, show the current TikTok account profile picture (see Figure 7). Yet it must be noted that the privacy settings of the account may impact whether the image can be viewed when following these links.
Figure 7: Links to the TikTok user profile picture.
3.3 Which accounts is the user ‘following’?
In order to establish those accounts which a user is following, analysis of the ‘AwemeIM.db’ (located at ‘<Application Folder>/Documents/AwemeIM.db’) is required. This is a single table database, where table ‘AwemeContactsV4’ maintains the following relevant information.
Table 1: A breakdown of relevant fields in the ‘AwemeIM.db’.
Column
Value
uid
Account identifier (6876767349338375174)
customID
Account ‘Username’
followStatus
‘1’ if following, ‘2’ if following and they are following the user.
nickname
Account ‘Name’
signature
Biographical input for account.
url1 & url2 & url3 (separate fields)
Testing revealed these to be a TikTok URL for the account profile picture (accessible if the account is public)
*The table also contains the user’s TikTok account information which can be validated against the information found in the ‘com.zhiliaoapp.musically.plist’ by matching the ‘uid’ values in both files (<Application Folder>/Library/Preferences/com.zhiliaoapp.musically.plist - in the value stored in key ‘<key>kDYACurrentLoginUserPersistenceKey</key>’).
3.4 How often does the user use TikTok:- Active Sessions
Using the ‘HMDApplicationSessions’ table in the ‘heimdallr.db’ (located <Application Folder>/Library/Heimdallr/heimdallr.db), user sessions on TikTok can be established. This gives an indication of how often a user uses TikTok on their device.
Table 2: The ‘HMDApplicationSessions’ table and session information
Column
Value
Session ID
Attributable to a single session (active TikTok application on handset)
timestamp
Date & time of start of session
duration
Numerical value representing duration of active session in seconds. Sessions start when the application is opened, and end when the application is minimized/closed or when the device locks/shuts down.
3.4.1 Search Terms
In the ‘HMDHTTPDetailRecord’ table (located <Application Folder>/Library/Heimdallr/heimdallr.db), an option to establish what has been done within the session is also possible. Here focus will be maintained on user initiated search terms. The ‘HMDHTTPDetailRecord’ table maintains detailed records of the actions which occur in each TikTok session, where the sessionID value can be used to identify individual sessions. A description of the events which occur in each session can be found in the ‘absoluteURL’ field. In order to identify keyword search actions by the user the attribute ‘keyword=’ should be identified which is directly followed by the search criteria (shown in Figure 8). The URL also contains other search criteria previously used by the user which would typically be shown to the user in the TikTok GUI (shown in Figure 9). The ‘timestamp’ entry record denotes the time and date of the search.
Figure 8: The ‘keyword=’ value
Figure 9: The TikTok search GUI.
Due to the chronological implementation of the ‘HMDHTTPDetailRecord’ table, even when the user deletes search terms through the TikTok GUI, historic records in the ‘HMDHTTPDetailRecord’ table still show previous search terms and the time and dates they were shown in the GUI of the TikTok application.
4 User-created TikToks
Tiktoks created by the account are located in ‘<Application Folder>/Documents/kAWEPublishLocalVideoStorageFolder/’. Each file is prefixed 'publish_video_local_’ and is type .mp4. Filesystem metadata is consistent with the time of creation of the TikTok.
5 Cache from TikTok feed
TikTok creates a lot of ‘noise’ via general usage on a device; therefore if possible, it is important that this information is separated from that content which is triggered as a direct result of acts carried out by a user. TikTok users are provided with a ‘feed’ which contains both ‘followed’ user content and content offered by TikTok. This feed maintains a cache located at ‘<Application Folder>/Library/Caches/com.ibireme.yykit.feed/’ (Shown in Figure 10).
Figure 10: The TikTok Feed Cache directory.
The quantity of cached content within the feed cache is dependent on how much of his/her feed a user browses. Testing indicated that for every TikTok viewed, the first splashscreen of the TikTok is cached as a still image and the user’s profile tile. When a user stops viewing their feed, the next ‘unviewed’ (but next in line on the feed to be viewed) TikTok video also has its first splash screen and user tile cached (shown in Figure 11).
Figure 11: The TikTok Feed Cache order.
**To Note: As previously discussed, TikTok records different TikTok ‘sessions’ carried out by the user. A session typically occurs when the user closes the TikTok app then reopens it. If the user closes the TikTok app, but does not reopen it, the feed cache remains in-tact. When TikTok is next opened, the feed cache folder is purged.
The manifest.sqlite database within the /images directory keeps a record of all feed cache contents. Cached images (splashscreens and user tiles) can be embedded as BLOBs within the inline_data field of this database or stored in the /images/data folder as separate .jpg and .png files. These files can be matched to their corresponding entries in the manifest.sqlite database using the filename field (if the image is embedded within the database, the filename field will be null).
The modification_time field (UNIX timestamp) within the manifest.sqlite database can be used to indicate when a user first views a TikTok. As previously discussed, each TikTok has two corresponding cached images-the creator’s profile picture and the splashscreen-and thus two corresponding entries within the database. The modification_time for both entries is essentially identical. It should be noted, however, that creator profile pictures will not be cached more than once. If multiple TikToks created by the same account are viewed in the same session, the creator profile picture will only be cached when the first TikTok from that account is viewed. The remainder of the TikToks created by that account will only have one corresponding entry in the database for the splashscreen. When the user starts watching a TikTok, the entries for the next one in the feed are written to the cache. Therefore, the time when a TikTok was first viewed corresponds to the modification_time for the entries in the database that list the creator’s profile picture and splashscreen of the next TikTok in the feed. It should be noted that the entries for the next TikTok in the feed may not immediately follow the entries for the previous TikTok if the user switches feeds or if the same TikTok appears more than once in one session.
5.1 TikTok generic cache TikTok also maintains a ‘generic’ cache directory (<Application Folder>/Library/Caches/com.ibireme.yykit/images/) and this cache is not purged following different TikTok sessions. Some data which is purged from the feed cache (user profile tiles) can be found in the generic cache but not all and testing could not establish consistent behaviour causing content to enter the generic cache (Shown in Figure 12). As a result, practitioners should be cautious when seeking to infer meaning to content in the generic cache. It should also be noted that the general cache does not appear to consistently record any information about viewed TikToks, but does contain remnants of other types of app activities such as images from search results
Figure 12: The generic cache directory.
5.2 Cached videos which have been watched
Full videos which the user has viewed in his/her feeds are cached in the ‘<Application Folder>/Library/Caches/TTPlayerCache/’ directory (Shown in Figure 13). This directory can but does not always include TikToks viewed in previous sessions, and also includes various numbers of unviewed TikToks from both the “for you” and following feeds. These files are .mdl (which an .mp4 header - ‘....ftypisom....’) and are playable using a standard media player (VLC for example). They are named starting with the character v followed by a 5 digit number. This number is consistent for all TikToks from a particular feed (e.g. the file names for TikToks from the for you feed may all start with v07044).
Some TikToks are cached in both 540p and 720p, while others are only cached in one resolution. If there is one copy of the TikTok (i.e. it was cached in one resolution) and it was viewed, the file metadata associated with the .mdl file is consistent with the time the TikTok was viewed. If there are two copies of the TikTok (i.e. it was cached in two resolutions), the file metadata associated with each copy is different. If the TikTok was viewed, the later time is consistent with the time the TikTok was viewed while the earlier time is consistent with the start of the session in which the TikTok was viewed.
Figure 13: ‘TTPlayerCache’ contents.
5.3 SnapShots
When the user closes down TikTok, a snapshot of the screen is taken and stored in <Application Folder>/Library/SplashBoard/Snapshots/.
5.4 ‘Clear cache’
TikTok maintains a ‘Clear cache’ function which alerts the user to the volume of cache content retained by their TikTok application (shown in Figure 14).
Figure 14: The ‘Clear cache’ setting.
The impact of the ‘Clear cache’ function is as follows:
Data in the generic cache (<Application Folder>/Library/Caches/com.ibireme.yykit/images/) & feed cache (<Application Folder>/Library/Caches/com.ibireme.yykit.feed/) is gone.
Testing indicates that the ‘clear cache’ function cleans content from the ‘<Application Folder>/Library/Caches/’ region of the system only. For example, watched video content located at ‘<Application Folder>/Library/Caches/TTPlayerCache/mdlManual/’ remains intact.
6 Chat logs
The chat function of TikTok maintains logs at ‘<Application Folder>/Library/Application Support/ChatFiles’. Under this subfolder, chats are stored in a folder named with the TikTok user’s account identifier (‘uid’ - which can be found at ‘<Application Folder>/Documents/AwemeIM.db’), in the ‘db.sqlite’ (shown in Figure 15).
In the ‘db.sqlite’ , the ‘TIMMessageORM’ table contains records of conversations, where the ‘sender’ column identifies the sender of the message. Messages sent from the user’s account should have their ‘uid’ matched against the value in the ‘AwemeIM.db’ (located at ‘<Application Folder>/Documents/AwemeIM.db’). The ‘serverCreatedAt’ UNIX timestamp reflects the time and date that a message was sent from or received by the application.
Figure 16: The ‘TIMMessageORM’ table showing messages received from 2 separate users (highlighted black & blue), and sent from the user’s TikTok account.
In order to establish the name of the account that a user is receiving messages from, the ‘sender’ uid from the ‘TIMMessageORM’ table should be queried against ‘uid’ records in the ‘AwemeIM.db’ (located at ‘<Application Folder>/Documents/AwemeIM.db’), where corresponding name and username account information can be identified (shown previously in Table 1).
Message content is stored in the content column in JSON format. Messages which have content beginning ‘{"aweType":0,"text":’ are string-based communications, where the plain text message is available for review. Chronological ordering of the ‘serverCreatedAt’ column shows the order of conversation.
*To note: The ‘TIMMessageORM’ table maintains records of deleted messages. The ‘delete’ column records message values of ‘0’ for live messages and ‘1’ for deleted messages.
7. Summary
Figure 17 provides a summary of the key locations for data relating to specific digital actions found in the TikTok application folder on iOS.
Figure 17: Key locations in the TikTok application folder.
It is also necessary to identify some areas of challenge where testing was not able to establish the existence of digital trace evidence describing user actions. The following actions could not be established during testing.
Comments made on TikTok video.
Favourite videos.
Date of the case study:- September 2020
DFIR Review
This paper addresses TikTok artifacts that have not been previously addressed by other research papers. One of the reviewers was able to verify the authors’ findings using an iPhone 6S with iOS 13.1.3 and TikTok version 18.3.0.
The author may want to distinguish the difference between account names and usernames by indicating which contains the @ symbol (section 3.1). Usernames precede with the ‘@’ symbol. Account names or display names are listed above profile picture (as in screenshot on Figure 1).
One of the reviewers found some issues with some of the URLs.
The signature column has the description “biographical input for account”. It is unclear what is meant by biographical input, the reviewer would like to see further clarification.
Figure 17 only lists subdirectory (mdlManual) where the viewed TikTok videos would reside and does not list parent directory. In Reviewer’s test data set, there were more videos present in the TTPlayerCache versus mdlManual.
One of the reviewers was curious how the references found in section 1.1 informed the paper. Reviewers suggested some grammatical and formatting changes.
Future Work
Future work could include determining why some of a particular video would be cached in different resolutions. It would also be helpful to validate the findings with Android devices.
One of the reviewers was able to identify the username and account name by searching for some of the text such as “Follow me @<username>” as shown in Figure 5. However if you search for just the username, it appears at multiple locations. Besides the kDYACurrentLoginUserPersistenceKey, are there specific keys the user should be looking for?
During testing, viewed TikTok videos were identified in both ‘<Application Folder>/Library/Caches/TTPlayerCache/’ and ‘<Application Folder>/Library/Caches/TTPlayerCache/mdlManual’ directories. It is unclear based on this document why some would appear in the parent directory (TTPlayerCache) versus subdirectory (mdlManual).
Reviewers
Selena Ley (Methodology Review, Validated Review using Reviewer Generated Datasets)
Nice work! Question: It says, “*To note: The ‘TIMMessageORM’ table maintains records of deleted messages. The ‘delete’ column records message values of ‘0’ for live messages and ‘1’ for deleted messages.” Are you saying the “deleted messages” (i.e., actual content) are actually still retained in the database? If so, was it tested to see how long they were retained in the database?