Cellebrite CTF 2020: Ruth Langmore

 · 18 mins read

TL;DR: Breakdown of our answers to Ruth Langmore’s questions from the Cellebrite 2020 CTF using only free, open source tools.


Cellebrite just finished up its first Capture the Flag (CTF) event, running from October 26, 2020 through October 29, 2020. The introductory information about our team’s participation in that event can be found here, specifically it links to many of the free, open-source tools we used, which is worth a read to understand the commands you may see below.

This post focuses on the questions relating to Ruth Langmore. It is a guest post written by another member of the “No Tools, Just Right” team who worked on the challenges from a Mac OS environment. Despite the difference in OS, all of the challenges were still solved in the same manner using only the command line and a few open-source tools.

Spoiler Alert

The trick to three of Ruth’s questions relied on you having access to Ruth’s other phone backup. The one she made before wiping it. And shared the password for with Juan. And kept the URL for in an encrypted Note. Whose password was given to Rene. That phone backup.

Application Analysis - 10 points

On what date did Ruth want to be reminded to “Move the product”? (answer MM-DD-YYYY)

The solution to this question is found by examining the native iOS Reminder applications databases in private/var/mobile/Library/Reminders/Container_v1/Stores. After examining these database files, the file Data-D59ABA3F-2A1D-4C16-8674-4C88C65D18A3.sqlite was found to contain a ZREMCDOBJECT table, which contains information about reminders including the reminder content, creator, and date.

Examining this table reveals a row with column ZTITLE1 set to “Move the product”. This analysis could also be performed directly from the command line.

[marocchino@macos]$ sqlite3 private/var/mobile/Library/Reminders/Container_v1/Stores/Data-D59ABA3F-2A1D-4C16-8674-4C88C65D18A3.sqlite \

619138800 (Friday, August 14, 2020 11:00:00 PM, Core Data timestamp)

The ZDUEDATE column for the row with ZTITLE1 set to “Move the product” is 619138800 (Friday, August 14, 2020 11:00:00 PM, Core Data timestamp), yielding the formatted solution 08-14-2020

Browser History - 10 points

Where did Ruth look up weather forecasts for? (answer must include city and state in this format - Washington, DC)

The primary browser utilized by Ruth is Safari. Examining the the Safari browsing history stored in private/var/mobile/Library/Safari/History.db revealed multiple site visits, including a visit to “www.accuweather.com”.

[marocchino@macos]$ sqlitebrowser private/var/mobile/Library/Safari/History.db

The history_items table contains a url column which lists urls visited by the user. The url of relevance is “https://www.accuweather.com/en/us/carolina-beach/28428/weather-forecast/334876”. This url contains the city name “carolina-beach” and zip code “28428”, leading to the solution “Carolina Beach, NC”.

Communications - 10 points

Who is the owner/creator of the group named “OG Crew” across the devices?

Despite the relatively low point value of this question, it proved to be a bit more challenging without an effective tool to parse the Telegram database files1. First, the Telegram database file of interest was identified as private/var/mobile/Containers/Shared/AppGroup/DA4E27EE-A83F-45B7-B81B-D5BC3776D295/telegram-data/account-9382957548618367801/postbox/db/db_sqlite.

Without a tool to parse this database, good old manual analysis of each of the unhelpfully named tables was performed. Each table contains keys which correspond to serialized data structures viewable as unformatted data blobs within an SQL Database viewer.

The table “t2” was found to contain all of the user, contact, and group Telegram ids as keys. The key 4634129633 is the Telegram key for the “OG Crew” group, based on ascii text from within the data blob, shown below:

0000  01 5f 05 51 7d a1 66 ff 00 00 00 01 69 01 e1 34  ...Q}.f.....i..4
0010  37 14 01 00 00 00 01 74 04 07 00 00 00 4f 47 20  7......t.....OG  
0020  63 72 65 77 02 70 68 08 02 00 00 00 7e 87 c9 69  crew.ph.....~..i

I next identified all of the tables which include the “OG Crew” group Telegram id 4634129633 as a key. These are t2, t8, t14, t18, t23, and t27. Without a knowledge of the data serialization process used by Telegram, I searched for indications of a possible group owner within the data blob values associated with the key 4634129633. Searching for any occurrence of known Telegram user ids from t2 within these data blobs revealed multiple data blobs of potential interest. This was performed by converting all of the Telegram user id values to hex, and then using grep to locate Telegram user id hex values within the data blobs associated with “OG Crew”.

For example, “Tony M” was found to have Telegram id 953301191, which converts from decimal to hex value 38d238c7, displayed within hexdump output as 38c7 38d2. While searching for Tony M’s Telegram id within the hexdump of the data blob for “OG Crew” in t18, I noticed that Tony M’s Telegram id occurred more frequently in the data blob than other users.

[marocchino@macos]$ hexdump t18_ogcrew.bin | grep "38c7 38d2"

0000030 b002 0047 0000 0100 0162 38c7 38d2 0000
0000060 0000 0100 0162 38c7 38d2 0000 0000 7401
0000090 0162 38c7 38d2 0000 0000 7401 7d00 bd4a
00000e0 d829 0034 0000 0100 0162 38c7 38d2 0000
0000170 0500 6e69 4276 0179 38c7 38d2 0000 0000

Tony M’s Telegram id occurred six times within this data blob, while other users’ ids appeared a maximum of twice. Interestingly, Tony M’s Telegram id always appeared within the same data sequence:

0000 0100 0162 38c7 38d2 0000 0000 7401 7d00 bd4a de5e 05e4 2456

While there were still unanswered questions as to the meaning of this additional serialized data, we submitted “Tony M” as the owner/creator of the group “OG Crew”, proving to be the correct answer.

Device Identification - 20 points

Which iOS version was running on the device at the time of acquisition? (answer with just the number - i.e. 12.3)

The last installed iOS version can be found within the default system MobileInstallation/LastBuildInfo.plist file. The bplister tool was used to parse this plist file.

[marocchino@macos]$ ruby ~/ruby/bplister/plist_parse.rb \

 "ProductCopyright"=>"1983-2020 Apple Inc.",
 "ProductName"=>"iPhone OS",
 "FullVersionString"=>"Version 13.6 (Build 17G68)"}

The ProductVersion field identifies the latest iOS version at the time of acquisition as 13.6.

Application Analysis - 20 points

What is Ruth’s user_id on TikTok? (answer is the string of numbers, not the user_name).

TikTok contacts are stored in the Documents/AwemeIM.db of the TikTok application folder. This database has the table AwemeContactsV3 which contains the id, nickname, username, and additional information for each TikTok “contact” and the active user. The majority of these “contacts” seem to be popular accounts which Ruth follows, such as Snoop Dogg and Comedy Central. Exploring this table reveals a row with column nickname set to “Ruth Langmore”. The UID column for this row is 6854514343108871173.

Once the structure of the database is known, the solution can easily be found with a simple SQL query, as demonstrated below:

[marocchino@macos]$ sqlite3 private/var/mobile/Containers/Data/Application/314C0D76-AD79-43D9-93F6-5369A847BEE5/Documents/AwemeIM.db \
'SELECT uid FROM AwemeContactsV3 WHERE nickname="Ruth Langmore"''


By examining the relevant TikTok database file, Ruth’s TikTok user_id was found to be 6854514343108871173.

Password Recovery - 20 points

What is the password that can be used to access the link recovered from the locked notes? (answer is caSE SenSITive).

While analyzing the message and note content of the devices this question was always in the back of our minds, as we anticipated that the password may have been sent/received in a chat application, or stored in a note. This answer was found after the “Application Analysis_Notes” question, allowing us to verify potential passwords on the locked DropBox folder link prior to submission.

The correct password was found while investigating the TikTok direct messages database located at private/var/mobile/Containers/Data/Application/314C0D76-AD79-43D9-93F6-5369A847BEE5/Library/Application Support/ChatFiles/6854514343108871173/db.sqlite

[marocchino@macos]$ sqlitebrowser "private/var/mobile/Containers/Data/Application/314C0D76-AD79-43D9-93F6-5369A847BEE5/Library/Application Support/ChatFiles/6854514343108871173/db.sqlite"

The TIMMessageORM table contains a content column with chats. One row with Server message ID value 1674949484956694 has content value {"aweType":0,"text":"Dr3@mT3@m11"}, indicating the user sent that text which in context is in response to the request “Can you Send me what I need to access that link just in case”.

Due to the case sensitivity and special characters in Dr3@mT3@m11, we suspected it to be a potential password and successfully tried it against the password protected DropBox link. Once open, the Dropbox link is another multi-GB rip of Ruth’s phone, from before her wipe, allowing you to answer the other questions.

Device Status - 20 points

When was Ruth’s iPhone last wiped? Provide the date in the following format MM-DD-YYYY)

The creation timestamp of the file /private/var/root/.obliterated indicates the last device reset time. A simple check of the creation timestamp with the command ls -al revealed the solution.

[marocchino@macos]$ ls -al ./private/var/root/.obliterated

-rw-r--r-- 1 marocchino marocchino 0 Jul 27 15:11 ./private/var/root/.obliterated

Based on the creation timestamp of ./private/var/root/.obliterated, the answer is 07-27-2020.

PList Analysis - 20 points

When was the WiFi for “Birchrunville_cafe-Guest” first connected (added) to Ruth’s iPhone? The answer must be provide in localtime for the device. (UTC WILL NOT BE ACCEPTED). Answer must be in the following format MM-DD-YYYY HH:MM:SS (i.e. 12-18-2019 23:52:23)

The trick to this question is you must have Ruth’s previous device backup as the connection occurred prior to her wiping the phone. Previously connected wireless network information and configurations are stored in private/var/preferences/SystemConfiguration/com.apple.wifi.plist. Bplister was used to parse this .plist file and locate the entry for “Birchrunville_cafe-Guest”, which includes an addedAt field indicating the first date of network connection.

[marocchino@macos]$ ruby ~/ruby/bplister/plist_parse.rb \
./var/preferences/SystemConfiguration/com.apple.wifi.plist \
| less

    "addedAt"=>2020-07-09 20:23:07 65711/131072 -0400,

The first date of connection to “Birchrunville_cafe-Guest” was found from the addedAt field to be 2020-07-09 20:23:07 65711/131072 -0400. Formatting this value as specified in the question led to the answer 07-09-2020 20:23:07.

Application Usage - 20 points

How much time did Ruth spend on TikTok on 07-25-2020? (Answer must be in this format 00:05:27)

The application usage time can be found within the iLEAPP output under the Screentime subsection Timed Items, which sources its information from the system database private/var/mobile/Library/Application Support/com.apple.remotemanagementd/RMAdminStore-Local.sqlite. Again the trick is that you need Ruth’s old phone to find this.

Manual analysis of this database reveals a total screentime of 144 seconds, or 2 minutes and 24 seconds on 07/25/2020 for TikTok with Bundle ID com.zhiliaoapp.musically, leading to the formatted solution 00:02:24.

Application Usage - 20 points

How did Ruth listen to the podcast titled “Episode 4: The Importance of Test Data” on this device? (Answer must be just the application name i.e. spotify)

We solved the next question related to the podcast item_pid prior to finding this solution. With that question solved, the item_pid corresponding to the podcast was known to be 239332200929536034. The device media library database private/var/mobile/Containers/Shared/AppGroup/mobile/Media/iTunes_Control/iTunes/MediaLibrary.sqlitedb contains the table item_extra which associates the item_pid 239332200929536034 to the filename 73F14C44-063C-4491-9985-26EA45303A42.mp3. A recursive grep -r was performed on the subdirectories of private/var/ to find any mentions of this mp3 filename within any files related to a specific application.

[marocchino@macos]$ grep -r 73F14C44-063C-4491-9985-26EA45303A42.mp3

Binary file mobile/Media/iTunes_Control/iTunes/MediaLibrary.sqlitedb matches
Binary file mobile/Containers/Shared/AppGroup/8F0BDE92-A885-41C2-9BD6-DA89CF0E413B/Documents/MTLibrary.sqlite-wal matches

This search revealed that the database mobile/Containers/Shared/AppGroup/8F0BDE92-A885-41C2-9BD6-DA89CF0E413B/Documents/MTLibrary.sqlite referenced the filename of interest. To find the application associated with this database, the com.apple.mobile_container_manager.metadata.plist file within the same AppGroup directory as the database was inspected. Bplister was used to parse the file var/mobile/Containers/Shared/AppGroup/8F0BDE92-A885-41C2-9BD6-DA89CF0E413B/com.apple.mobile_container_manager.metadata.plist in search of its associated application.

[marocchino@macos]$ ruby ~/ruby/bplister/plist_parse.rb \


The MCMMetadataIdentifier field includes the “com.apple.podcasts” Bundle ID, suggesting that the application used to listen to the podcast titled “Episode 4: The Importance of Test Data” was Apple’s native “Podcasts” app, leading to the answer “podcasts”.

Application Usage - 20 points

Ruth listened to a podcast titled “Episode 4: The Importance of Test Data” on this device. Once you determine how she listened to it, what is the item_pid for this podcast?

A recursive grep -r for item_pid was executed in the private/var/mobile/Containers/Shared/AppGroup subdirectories to identify any applications which mention item_pid in any of their files.

[marocchino@macos]$ grep -r item_pid private/var/mobile/Containers/Shared/AppGroup

Binary file db/diagnostics/Persist/0000000000000039.tracev3 matches
Binary file db/uuidtext/B3/45379B1A883FC2BC0630920C22299B matches
Binary file db/uuidtext/2A/31BD52FBF83CF9B970D6D73A005126 matches
Binary file db/uuidtext/B0/6E30C6660D3C59AD00458901C6C74C matches
Binary file db/uuidtext/DB/0701665510332B80FCA475A702B147 matches
Binary file db/uuidtext/A1/A1FDCE78F438D78FDE0C43604BDE0C matches
Binary file db/uuidtext/42/F5AA85E61B3AA5A1811F3F19F473EA matches
Binary file db/uuidtext/dsc/59A390C7D5F23C2D991C2F90FE9A5180 matches
Binary file db/uuidtext/dsc/8B461428DA8739899B96B0422D104584 matches
Binary file db/uuidtext/9B/6EACEBCA3035DB9E7D96CFB9AB5EF2 matches
Binary file db/uuidtext/5C/17056FF3213D0595827A5027F86814 matches
Binary file mobile/Media/iTunes_Control/iTunes/MediaLibrary.sqlitedb matches

The results indicate that the database private/var/mobile/Media/iTunes_Control/iTunes/MediaLibrary.sqlitedb likely contains an item_pid column. By manual inspection with sqlitebrowser, it was found that the item_extra table contains an item_pid column.

[marocchino@macos]$ sqlitebrowser mobile/Media/iTunes_Control/iTunes/MediaLibrary.sqlitedb

The corresponding item_pid for the row with title set to “Episode 4: The Importance of Test Data” was found to be 239332200929536034.

Database Analysis - 50 points

What is the link that was found in a locked note? (Hint: it is a good idea to use this link as it’s a hidden flag and it’s safe!)

Once the notes were unlocked, as detailed in the final question for Ruth’s device, this questions simply involved examining the notes decrypted by the Apple Cloud Notes Parser. The note of interest was found to be “Note 27”, displayed below:

Note 27
Account: iCloud
Folder: Notes
Title: Xxxxxxxxx cc xxxxxxxxxxxxxxxxxxxxxxxxxxxxcxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx…
Created: 2020-08-14 12:28:11 -0400
Modified: 2020-08-14 12:44:01 -0400
Password: w3ndy$
CloudKit Last Modified Device: Ruth’s iPhone

Xxxxxxxxx cc xxxxxxxxxxxxxxxxxxxxxxxxxxxxcxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx well done - https://bit.ly/3arhLSK xxxxxxxxxxxxxxxxxxxxxxxxxxxxcxxxxxxxxccxxccxxxxxxxxxccccccxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

This decrypted note included the answer, the shortened URL “https://bit.ly/3arhLSK”, that leads to the locked DropBox folder related to the previous “Password Recovery” question.

Financial Information - 50 points

What is the routing number used by Ruth to make and receive payments for potentially illegal transactions?

My solution for this question during the competition was indirect, as while analyzing Juan’s iPhone, I observed a screenshot of a CashApp Transaction with Routing Number “041215663” saved on Juan’s device at /private/var/mobile/Containers/Data/Application/64F77221-3E98-46DF-A9FA-2B8229652965/Library/SplashBoard/Snapshots/sceneID:com.squareup.cash-default. Making an educated guess, I successfully submitted this routing number, 041215663, as the routing number for Ruth.

Application Analysis_Notes - 100 points

What is the password to unlock the Notes on Ruth’s device? (case sensitive - as all passwords should be!) You won`t find the answer, but can draw clues to it. Google could help once you find the correct hint.

Throughout the analysis of all of the devices, we kept a running list of potential passwords observed in messages and file contents, which was stored in a passwords.txt file. This provided a useful list for brute-forcing the locked Apple Notes. While going through Rene’s phone, an email from Ruth was found which stated “Keep this: w3ndy$”. Due to its curious use of special characters, w3ndy$ was added to the passwords.txt file. Once a substantial list of possible passwords was compiled, we brute-forced the encrypted apple notes with the Apple Cloud Notes Parser.

[marocchino@macos]$ ruby ~/ruby/apple_cloud_notes_parser/notes_cloud_ripper.rb \
-p "ruth_langmore/Apple_iPhone_X_Ruth_Langmore/file_system/" \
-o notes \
-w notes/passwords.txt

[marocchino@macos]$ cat notes/2020_10_26-04_47_26/debug_log.txt \
| grep -i "generated a decrypt"

DEBUG -- : Apple Decrypter: Apple Note: 9 generated a decrypt using password w3ndy$
DEBUG -- : Apple Decrypter: Apple Note: 14 generated a decrypt using password w3ndy$
DEBUG -- : Apple Decrypter: Apple Note: 21 generated a decrypt using password w3ndy$
DEBUG -- : Apple Decrypter: Apple Backup encrypted file generated a decrypt using password w3ndy$
DEBUG -- : Apple Decrypter: Apple Backup encrypted file generated a decrypt using password w3ndy$
DEBUG -- : Apple Decrypter: AppleNotesEmbeddedPublicJpeg 7E279F1B-9DC9-4D93-8E81-950382C632DE generated a decrypt using password w3ndy$
DEBUG -- : Apple Decrypter: Apple Backup encrypted file generated a decrypt using password w3ndy$
DEBUG -- : Apple Decrypter: Apple Note: 27 generated a decrypt using password w3ndy$

The output of Apple Cloud Notes Parser revealed w3ndy$ to be the correct Notes password.


Overall, the challenges involving Ruth’s device emphasized the importance of knowing where to find specific forensic artifacts. Equally important to a base knowledge of iOS device artifacts was recognizing the usefulness of recursive searching to hone in on files of potential interest. Aside from the decryption of the Apple Notes, these challenges could all be solved with only sqlitebrowser, bplister, and grep -r.

The lack of specific tools to parse ugly databases, such as in the case of Telegram, caused some difficulties; however, manual analysis for unique indicators led to success. That challenge revealed our lack of knowledge of adequate open source tools for the analysis of iOS Telegram databases. The development of support for these databases in iLEAPP could prove to be a worthwhile and interesting endeavor. Additionally, a holistic awareness of questions across the multiple devices paid dividends, as the association of the routing number on Juan’s iPhone to Ruth’s “Financial Information” question saved significant time. Finally, Ruth’s challenges highlighted the importance of generating a list of potential passwords throughout the content analysis process, leading to a quick and easy brute force with the collected passwords candidates down the line.


  1. Perhaps not surprisingly, Cellebrite changelogs show Physical Analyzer supports Telegram on iOS. Again, not questioning motives, just noting it is very smart to pick an application that appears to be annoying as all get out to do by hand and providing a free taste of their easy parsing. I’d love to see this handled better in FOSS tools, or be pointed at one that supports it.