Post

BelkaCTF #6: BogusBill Writeup

Info

Link: https://belkasoft.com/belkactf6/

Problem: A counterfeit bill was found at a corner store, and we’re tasked to investigate leads with only our wits, smarts (assuming we have them), and an iPhone.

1. Ident

Prompt: What is the Apple ID used on the imaged iPhone?

In /private/var/mobile/Library/Accounts/Accounts3.sqlite there’s information about the phone’s accounts in the ZACCOUNT table. Here there are records indicating an iCloud account billthemegakill@icloud.com.

Accounts3.sqlite

Answer: billthemegakill@icloud.com

2. Namedrop

Prompt: What is the iPhone owner’s full name?

In /private/var/mobile/Library/AddressBook/AddressBook.sqlitedb, I stumbled on the owner’s name in the ABPerson table: William Phorger.

AddressBook.sqlitedb

Answer: William Phorger

3. Conspirators

Prompt: Which Telegram accounts did the owner discuss shady stuff with?

I hadn’t heard of Telegram before this competition, so I was hung up on this one for a bit. In /private/var/mobile/Containers/Shared/AppGroup/A667456A-6F8F-48C7-A8CF-37EFCC6BD644/telegram-data/account-112545592466388074/postbox/db/db_sqlite, one can find most Telegram user data, including accounts and messages. Unfortunately, this information is dispersed over 40+ tables. Navigating the database is unintuitive, to say the least.

I finally found my way to a table named t2 that contained what looked to be some usernames. I was able to pull four usernames out of this table that worked: @JesusStreeton1999, @diddyflowers, @locknload771, and @Sm00thOperat0r.

JesusStreeton1999

diddyflowers

locknload771

Sm00thOperat0r

Answer: @JesusStreeton1999, @diddyflowers, @locknload771, @Sm00thOperat0r

4. Visit

Prompt: Where does William live?

In Autopsy, under Data Artifacts -> Installed Programs, I found that William has Uber installed on his phone. I navigated to the Uber user data folder (/private/var/mobile/Containers/Data/Application/279D4B50-A8FC-4F16-86DA-61F3800F1E91) and came across a file database.db in the Documents folder. In here is a table called places, which contains a few addresses. One of note is labeled Home, and corresponds to address 7402 Nottingham Ave, Saint-Louis, MO, 63119.

Uber Address

Answer: 7402 Nottingham Ave, Saint-Louis, MO, 63119

5. Username

Prompt: What is the username of the laptop user?

At this point, I was provided with the password to extract the second image file provided, that of a Windows laptop. Navigating to C:\Users, it’s trivial to see the username is phorger.

Users Folder

Answer: phorger

6. April Paycheck

Prompt: What is the amount of William’s first take in April?

On the iPhone image, I recall seeing some Web history entries (Data Artifacts -> Web History) for Crooked River Bank at https://crbk.org.

CRBK

Navigating to the site, it seems I can recover the password if I have two pieces of information: William’s username, and his card number.

CRBK Forgot Password Page

Back in the Windows image, in Data Artifacts -> Recent Documents, I see a couple LNK files for some PNG files in C:\Users\phorger\Pictures. There, Capture2.png shows some transactions.

Capture2.png

In this folder we also have a Zone.Identifier data stream, which can indicate where files originated. The Zone.Identifier for that PNG indicates it came from Microsoft ScreenSketch.

Zone.Identifier Stream

Maybe there’s something to be found in the AppData folder. In C:\Users\phorger\AppData\Local\Packages\Microsoft.ScreenSketch_8wekyb3d8bbwe\TempState, I find what I’m looking for: cached screenshots, including the full version of Capture2.png, which shows William’s username, card number, and recent transactions.

Full Capture2.png

Putting that information into https://crbk.org/forgot-password gives a new password in plaintext. This is a seriously insecure banking system!

New Password

Oh well, not my problem. I log in with the new password, and see a new transaction for April, a credit for 7012.39.

April Transaction

Answer: 7012.39

7. Party

Prompt: Where did the gang go to celebrate their success together in March?

Back in the Telegram database, there’s a table t7 which seems to contain messages between William and his crew. One message suggests celebrating at a bar downtown.

Celebration Telegram Message

Another message mentions an app Splitwise in relation to a great meal.

Splitwise Telegram Message

Back on the iPhone, William has Splitwise installed. In the Splitwise user data folder (/private/var/mobile/Containers/Data/Application/E951DC58-CF30-4518-9482-3E076D89A20B) I come across a database.sqlite file in Library/Application Support that has expense records in a table named SWExpense. One of these records has a description “Get-together at Cunetto,” and the Unix timestamp in the date column corresponds to March 20.

Splitwise Records

Doing a quick search for “cunetto” shows a restaurant in St. Louis named Cunetto House of Pasta, this corresponds to lat/long 38.61034, -90.28030.

Cunetto

Answer: Cunetto House of Pasta

8. Crypto

Prompt: Which file does the guy keep his encrypted container in?

Back in the Window’s image, it doesn’t take too long to stumble on a VHDX container hiding in an alternate data stream at C:\Users\phorger\Documents\desktop.ini.

ADS VHDX

I extract the container and try to mount it, but it asks for a Bitlocker password or recovery key. I remember seeing a recovery key in Autopsy under Data Artifacts -> Recent Documents, but a cursory keyword search doesn’t seem to indicate it’s resident on the Windows image. However, I have better luck on the iPhone. A keyword search reveals the recovery key in an obscure file /private/var/mobile/Library/Spotlight/CoreSpotlight/NSFileProtectionCompleteUntilFirstUserAuthentication/index.spotlightV2/store.db.

Recovery Key

Answer: C:\Users\phorger\Documents\desktop.ini

9. Luxury

Prompt: Which luxurious item did Phorger put his laundered money into?

With the recovery key found in the previous step, I’m able to mount the VHDX. In here there’s an Excel file called Spending.xlsx that contains an entry for a Rolex Submariner Date 126619LB.

Rolex

Answer: Rolex Submariner Date 126619LB

10. Vacation

Prompt: Which concert were Phorger and his girlfriend planning to attend in May?

I wasn’t able to find the answer to this one in the time limit, nor were many people. I recall from the Spending.xlsx file that William bought two round-trip tickets to Paris. So there’s our first clue.

There are some records on the Windows image in Autopsy under Data Artifacts -> Web History that indicate William was talking with his girlfriend (@diddyflowers) on the web version of Telegram, using Microsoft Edge.

Telegram Web

There are a few places in Edge where cached data is stored. One I didn’t know about was in C:\Users\phorger\AppData\Local\Microsoft\Edge\User Data\Default\Service Worker\CacheStorage. In here is a folder ba00623a413aef1be0c65618db85f0b8176e803d which seems to contain some folders with cached data from https://web.telegram.org.

Telegram Cached Data

I extract the folder and run my familiar grep to look at all the URLs.

1
2
3
grep -EIroah 'https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)' \
| sort \
| uniq

From among those URLs, some stand out, mainly JPG files that seem to be associated with Telegram messages.

Telegram Message Cached URLs

These URLs are not functional, but luckily we still have the cached files the URLs were pulled from. A simple grep (grep -r msg6827079691) gives the file names of interest.

Telegram Message Cached Files

A quick look in Autopsy verifies that these files contain the JPEG data; peep the JFIF!

Autopsy Cached File

I pull the first cached file, c6b7544d-4000-44db-9f5d-41a962dfd3ce/341523c8cabb5a2c_0, into HxD. I recall from my experience with file signatures that a JPEG file starts with hex values 0xFFD8, followed closely by a JFIF string, and ends with hex 0xFFD9. The screenshot below shows the first hex data of the cached file. What’s in blue is everything prior to the first 0xFFD8 hex value (highlighted), which is just before the JFIF string (also highlighted). I removed everything prior to FFD8, and followed the same process for everything after the last instance of 0xFFD9 at the end of the hex data. Then, I saved the modified file as a jpeg.

Autopsy Cached File

Opening up the carved jpeg shows that they were planning on going to see Eric Clapton at the Accor Arena in Paris.

Eric Clapton

Answer: Eric Clapton, Accor Arena, Paris

11. Illustrator

Prompt: What’s the name of the person who designed the print template for the bills?

In the t7 table in the Telegram database, William seemingly talked to his girlfriend, first name Drew, about her designing a template for counterfeit bills. She agrees, and sends William a PSD file.

t7 Message 1

t7 Message 2

t7 Message 3

In the mounted VHDX, there’s a file baker/presets/1.psd which shows a template for counterfeit bills.

PSD Template

Running a strings/grep combo against this file for Drew (strings 1.psd | grep Drew) reveals her full name to be Drew Linesworth.

Drew Linesworth

Answer: Drew Linesworth

12. Homebrew Lab

Prompt: Where is the makeshift lab where they printed the cash located?

In the Telegram database, William talks with his crew about a “secure location,” and seemingly sends them an address via “secret chat,” though I’m unable to find any traces of the address in the Telegram folders.

t7 Message 1

t7 Message 2

However, there are a few places to find location data on the iPhone. One of them is in /private/var/root/Library/Caches/locationd/consolidated.db. In the GeoFences table, there’s one entry for 38.5924436, -90.057325.

consolidated.db

This location corresponds to address 900 N 88th St, East St Louis, IL 62203.

Address

Answer: 900 N 88th St, East St Louis, IL 62203

13. Largest Batch

Prompt: What is the precise moment their largest printing batch was completed?

There’s a python script on the VHDX at baker/bot.py that reveals how the bot works. It seems William provides the bot with a “recipe number,” a “cake size,” and finally the “number of cakes.” The prompts from the bot are highlighted in the screenshot below.

Bot.py

The bot seems to have been hosted in Telegram, as these same messages are present throughout the t7 table. This also means that William’s specifications for each batch are present as well.

Bot Message 1

Bot Message 2

Bot Message 3

Bot Message 4

Bot Message 5

Of the numbers William seemingly sent over Telegram, 160 was the largest.

Largest Batch Size

After spending some time in Telegram, I figured out how to pull timestamps from each message in the t7 table from the key column. I take 4 bytes starting at 12 bytes in, and plug it into https://epochconverter.com. The 160 message was sent at 2024-04-01 11:22:38 UTC.

Timestamp in Hex

Epoch Converter

Using this same method, I look through the t7 table and decode timestamps for the batch completed messages; the closest one I could find to that timestamp was 2024-04-02 22:44:30 UTC.

Answer: 2024-04-02 22:44:30 UTC

14. Device

Prompt: What’s the printer model they used to print money?

On the Windows image in Autopsy, there are entries under Data Artifacts -> USB Device Attached for an HP LaserJet M1132 MFP; this information was pulled from the SYSTEM registry hive.

USB Device Attached

Answer: HP LaserJet M1132 MFP

15. Night Shift

Prompt: Which ATM did Phorger test his bills on recently?

In the Telegram database t7 table, messages seem to indicate that there was a problem with one of the ATMs, and William went to check it out.

t7 Message 1

t7 Message 2

t7 Message 3

Using the same process of decoding the timestamps as in task 13, the timestamps of these messages seem to indicate William visited the ATM between the night of April 1st and the morning of April 3rd; this is also verified in the task description.

On the iPhone, in /private/var/preferences/com.apple.wifi.known-networks.plist, there’s an entry for a Wi-Fi network added on the morning of April 3rd, with SSID UCPLPublicWireless.

Known Networks Plist

There’s a site https://wigle.net that keeps a record of SSIDs discovered around the world. Using the SSID and BSSID from the plist, I can see if there are any hits for those values over St. Louis. Luckily, there’s one.

Wigle.net

This location turns out to be the University City Public Library at 6701 Delmar Blvd, University City, MO 63130. The closest ATM is the Regions Bank ATM on Delmar Blvd.

ATM

Answer: Regions Bank ATM on Delmar Blvd

16. Mole

Prompt: Who leaked the technical data on the bill validator to the gang?

This one was the last one that I was able to solve, and also the most satisfying! On the Windows image, in Autopsy under Data Artifacts -> Recent Documents, I noticed a LNK file for the technical documentation in question. This documentation seemed to have been resident on the VHDX at one point; the 776AR-04U.PDF file referenced in the LNK record just above is on the VHDX. The technical documentation is not there anymore, though.

ATM Documentation LNK File

At some point I realized that maybe the file data hadn’t been overwritten yet. So I loaded the mounted VHDX as a logical drive into FTK Imager, which can detect deleted files. Sure enough, the ATM documentation pops up.

Deleted ATM Documentation

I export the PDF from FTK Imager and open it up with Adobe Acrobat. The moment I open it, a warning pops up saying a signature is invalid. Interesting. I open up Signature Panel and we have our mole: Kenneth Leek.

Signature Invalid

Answer: Kenneth Leek

17. Financial Institution

Prompt: Which offshore financial institution did the gang bank with?

In the t7 table in the Telegram databse, William seems to receive a Shortcut from Chase that encrypts messages with a secret key. There seems to be some of these messages in the table as well.

t7 Message 1

t7 Message 2

t7 Message 3

t7 Message 4

On the iPhone, there’s a Shortcuts.sqlite database in /private/var/mobile/Library/Shortcuts. In the ZSHORTCUTACTIONS table there are some interesting code snippets in the ZDATA column. The first entry contains logic for encoding data, and the second for decoding data.

ZDATA Decode Logic

I pull out the decode logic into Notepad. It seems we would need a key, but really, we only need two integers a and b. The modulo operators indicate that a would initially be less than 137, and b would be less than or equal to 89.

Decoding Logic

Those numbers are easy to brute force. I nest the decoding logic into two for loops, and add a regex check to see if the decoded text contains printable ASCII characters. The full script is below.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
var hexEncodedText = "addaf04dc94ddaf04ddfc980661fc91e7caac9f0dadac94df1664d0c";

for(let a_mod = 0; a_mod < 137; a_mod++) {
	for(let b = 1; b <= 89; b++) {
		a = 2*a_mod + 1;

		let decodedText = '';

		let modInverseA = 0;

		for (let i = 0; i < 256; i++) {
			if ((a*i)%256 === 1) {
				modInverseA = i;
				break;
			}
		}

		let encodedText = '';

		for (let i = 0; i < hexEncodedText.length; i+= 2) {
			let charCode = parseInt(hexEncodedText.substr(i, 2), 16);
			encodedText += String.fromCharCode(charCode);
		}

		for (let i = 0; i < encodedText.length; i++) {
			var tt = encodedText.charCodeAt(i) - b;
			if(tt < 0) {
				tt += 256;
			}
			let charCode = (modInverseA * tt) %256;
			decodedText += String.fromCharCode(charCode);
		}
		if(/^[\x20-\x7F]*$/.test(decodedText) == true) {
			console.log(decodedText);
		}
	}
}

I compile and run it, and I get my first printable ASCII strings, one of which looks like something a human might come up with.

Decoded Hex

Yes I can see that, William. I start decoding the rest of the hex messages from the t7 table. One of them contains the SWIFT code for the offshore bank: CRVBPA2P.

Decoded SWIFT Code

Answer: CRVBPA2P

18. Statement

Prompt: Paste Phorger’s entire bank statement here, containing all his offshore transactions.

Back at https://crbk.org, there seems to be an option to download all of William’s transactions. Unfortunately, this requires a one-time password.

CRBK 2FA

On the iPhone, I came across a screenshot of the Google Authenticator app (/private/var/mobile/Media/DCIM/100APPLE/IMG_0032.png), which William seemingly used to authenticate to CRBK.

IMG_0032

To do the same, one would need a QR code or setup key for CRBK. On the Windows image, there’s an iPhone backup in C:\Users\phorger\AppData\Roaming\Apple Computer\MobileSync\Backup\46803e574938af07acaf4ff465b25360e9680067. I’m learning that Apple is never going to make it easy for me, because the backup is spread over 250+ folders. I didn’t have the time or patience to look through them all during the CTF, but the QR code is at 15\15eb410a07be50b098db1d43758d7d71a91d757d.

QR Code

I download Google Authenticator on my phone and scan the QR Code. I then use the one-time password to download all the transactions from CRBK into a CSV file.

Google Authenticator

CRBK 2FA

I open the CSV in Notepad and paste the statement into the CTF site.

Debrief

My first live CTF!!! What a thrill! I worked 30 of the 48 hours the CTF was live, and by the end my eyes were basically bleeding. I placed 15th, and am a little miffed at myself because I had two answers correct, but I didn’t format them correctly. I think I would’ve needed at least a couple more days to solve task 17, and if I had spent more time going through the iPhone backup, I definitely could’ve gotten task 18. So all in all, I don’t feel too bad about where I’m at skill-wise. I really appreciated this timely opportunity to evaluate my skill level and see how much I’ve grown over the past couple of years, and I’m so excited to start my new job and put all this knowledge to use!

This post is licensed under CC BY 4.0 by the author.