← Back to Writeups
CUSTOMEasyForensics

Zip

XESXOR9/2/20262 min read
#forensics#custom#easy#app_data_extraction#ios_sandbox_analysis#plist_parsing#linux

Zip

Platform: spbctf | Category: Forensics | Type: Challenge | Difficulty: Easy | OS: Linux | Author: XESXOR | Date: 2026-07-05 | Status: Solved Techniques: app_data_extraction, ios_sandbox_analysis, plist_parsing

Summary

Task: iOS app GimmeFlag with app_data.zip containing the app's sandbox container dump. Solution: Extract app_data.zip, read the Preferences plist at Library/Preferences/xyz.jayfromfuture.GimmeFlag.plist to find the flag stored in NSUserDefaults.

Zip — spbctf

Description

Now look at the zip

The challenge provides several files related to an iOS app called "GimmeFlag":

  • GimmeFlag.ipa — the iOS app package
  • GimmeFlag.zip — the same app in zip form
  • classdump.txt — Objective-C class dump of the app
  • gimme_flag_preview.png — preview screenshot
  • second_task_demo.mov — demo video
  • app_data.zip — dump of the iOS app's sandbox container

The task hint says "Now look at the zip" — directing attention to the app_data.zip file which contains the app's runtime data from an iOS device. ‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

Analysis

The challenge provides both the app binary (GimmeFlag.ipa/zip) and a dump of the app's sandbox container (app_data.zip). The hint "Now look at the zip" points us toward app_data.zip rather than the app binary itself.

iOS apps store their runtime data in a sandboxed container with a standard structure:

  • Documents/ — user-facing files
  • Library/ — app support data, caches, preferences
  • Library/Preferences/ — NSUserDefaults plist files
  • tmp/ — temporary files
  • SystemData/ — system-managed data ‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

The GimmeFlag app computes a flag and stores it in NSUserDefaults (the standard iOS key-value persistence mechanism). Since we have the container dump, we can read this value directly without needing to reverse engineer or run the binary.

Solution

Step 1: Extract app_data.zip

bash
unzip app_data.zip

This reveals the full iOS sandbox structure:

app_data/
├── Documents/
├── Library/
│   ├── Caches/
│   ├── Preferences/
│   │   └── xyz.jayfromfuture.GimmeFlag.plist
│   ├── Saved Application State/
│   ├── SplashBoard/
│   └── WebKit/
├── SystemData/
└── tmp/

‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

Step 2: Read the Preferences plist

bash
plutil -p app_data/Library/Preferences/xyz.jayfromfuture.GimmeFlag.plist

Output:

{
  "F7A9" => "spbctf{REDACTED}"
}

The flag is stored under the key "F7A9" in the app's NSUserDefaults preferences plist.

python
#!/usr/bin/env python3
"""
Solve script for spbctf Zip challenge.
Extracts flag from iOS app sandbox Preferences plist.
"""
import plistlib
import zipfile
import os

# Extract app_data.zip
with zipfile.ZipFile("app_data.zip", "r") as z:
    z.extractall(".")
‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

# Read the preferences plist
plist_path = "app_data/Library/Preferences/xyz.jayfromfuture.GimmeFlag.plist"
with open(plist_path, "rb") as f:
    plist = plistlib.load(f)

print(f"Plist contents: {plist}")
for key, value in plist.items():
    if "spbctf{" in str(value):
        print(f"Flag: {value}")

‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍