メインコンテンツへスキップ

FCSC 2025 - iOS フォレンジック

·4 分· loading · loading · ·
Jaybird1291
著者
Jaybird1291
目次
⚠️ この文章は ChatGPT で作成しました(日本語はまだ N4 レベルです)。

シナリオ
#

入国審査を通過する際、税関職員があなたにスマホと…そのアンロックコードの提出を求める。数時間後に端末は返却される…

不審に思ったあなたは、ANSSI の CERT-FR に端末を送って解析…依頼する。CERT-FR のアナリストは sysdiagnose とバックアップの収集を行った。

iForensics - iDevice iForensics - iWiFi iForensics - iTreasure iForensics - iNvisible iForensics - iBackdoor 1/2 iForensics - iBackdoor 2/2 iForensics - iC2 iForensics - iCompromise

論理バックアップの backup.tar.xz(logical)に 加えてsysdiagnose とクラッシュ関連のファイルセットもある!

セットアップ
#

このシリーズ全体では、以下を使った:

  • DB Browser for SQLite
  • EC-DIGIT-CSIRC/sysdiagnose
  • iLEAPP
  • Autopsy

便利な参照資料:

もちろん重火器(Plaso とか)も持ち込めるけど、夜遅くに CTF を解いてたので、今回は速いルートを選んだ。🤠

Intro - iForensics - iCrash
#

どうやらフラグが「端末内のクラッシュが保存される場所」に隠れているようだ…

超イージー枠。クラッシュは sysdiagnose_and_crashes.tar.xz に入ってるので:

tar -xf sysdiagnose_and_crashes.tar.xz 

あとは grep -r "FCSC{" で探してもいいし、クラッシュフォルダを手で眺めてもいい。

sysdiagnose_and_crashes/private/var/mobile/Li.../CrashReporter/ の中を見ると、fcsc_intro.txt が見つかる — そこにフラグがある。

Flag : FCSC{7a1ca2d4f17d4e1aa8936f2e906f0be8}

⭐ - iForensics - iDevice
#

まず、端末に関する情報をいくつか特定せよ: iOS バージョンと端末の model identifier。 フラグ形式は FCSC{|<build n…e 14 Pro Max running iOS 18.4 (22E240): FCSC{iPhone15,3|22E240}。

この問題に答えるには、まず「iOS のバックアップが何で構成されているか」を知っておく必要がある。前に「logical」バックアップと言ったけど、これが重要で、バックアップの中身をそのまま覗くと、変な名前のフォルダしか見えない:

意味のあるパスに戻すには Manifest.db(iOS 10 から導入)を使って実パスを復元する必要がある。Manifest.db は fileID を元の RelativePath に対応付けている DB。

幸い、ルート直下には人間が読めるファイルも残っていて、その一つが Info.plist。Apple はここに端末メタデータの要点を入れている:

  • product Type(model identifier、例: iPhone12,3)
  • product Version(iOS バージョン、例: 16.0)
  • build Version(例: 20A362)
  • IMEI、シリアル、GUID、最終バックアップ日時、インストール済みアプリ etc.

フラグに必要な情報が全部そろってる!

Flag : FCSC{iPhone12,3|20A362}

ツリー(arbo)を復元するのに興味がある人向けに、軽くデモも載せておく:

まず Manifest.db の中身を確認する:

構造はかなり素直なので、ちょいスクリプトでツリーを復元できる:

#!/bin/bash
BACKUP="/mnt/hgfs/backup/backup"
OUT="/mnt/hgfs/backup/reconstructed-backup"

mkdir -p "$OUT"

sqlite3 -separator '|' "$BACKUP/Manifest.db" "SELECT fileID, domain, COALESCE(relativePath,'') FROM Files;" | while IFS="|" read -r FILEID DOMAIN RELPATH; do

  [[ -z "$RELPATH" ]] && continue

  DEST_DIR="$OUT/$DOMAIN/$(dirname "$RELPATH")"
  DEST_PATH="$OUT/$DOMAIN/$RELPATH"

  mkdir -p "$DEST_DIR"
  ln -s "$BACKUP/$FILEID" "$DEST_PATH" 2>/dev/null || true
done

で、完成!

⭐ - iForensics - iWiFi
#

続いて、端末に関する情報をいくつか特定せよ: 端末が接続している Wi-Fi の SSID と BSSID、そして端末に紐づく iCloud アカウント。

フラグ形式は FCSC{||<iCloud acco…xample.com: FCSC{example|00:11:22:33:44:55|example@example.com}。

Wi-Fi と iCloud 情報の抽出を速くするために、iLEAPP(iOS Logs, Events, and Protobuf Parser)を使う。大量のアーティファクトを自動で回収・整理してレポートにまとめてくれるので便利。

iLEAPP を走らせたあと、Wi-Fi セクションから SSID と BSSID をそのまま読める:

iCloud アカウントは探し方がいろいろあるけど、手っ取り早いのは「どの Apple ID がアプリをインストールしたか」を見る方法。

Flag : FCSC{FCSC|66:20:95:6c:9b:37|robertswigert@icloud.com}

⭐⭐ - iForensics - iTreasure
#

税関にスマホを渡す前、所有者は「宝物」を送る時間があったらしい。この宝物を見つけよ。

ショートカットできる入口はいくつかある。文面は 送った(sent)ことを示唆してるので、まずはベタに SMS / iMessage を見る。

iLEAPP が sms.db を解析してくれるので、レポートを開いてメッセージテーブルに直行できる:

Autopsy にも「Logical File Analysis」モジュールで食わせられる。Autopsy はファイルヘッダ(マジックバイト)を見てメディア(JPEG, PNG など)をまとめてくれて、Access PathHomeDomain/Media/DCIM/... にあるものを「ユーザー生成コンテンツ(撮影/インポートされた写真など)」として “User Content Suspected” タブに集約したりする。

Flag : FCSC{511773550dca}

⭐⭐ - iForensics - iNvisible
#

メッセージが送信できなかったようだ… このメッセージの宛先を特定せよ。 フラグ形式は FCSC{}。例: 宛先が example@example.com の場合 FCSC{example@example.com}。

この問題は速い。DB sms.db を直接見ればいい。ここには iMessage と SMS の会話が全部入っていて、主なテーブルは message(ヘッダ、ステータス、本文など)と handle(相手の一覧、電話番号/アドレス)あたり。

message だけをクエリしてハマらないように注意。プレーンな SMS の場合は chat テーブルが必要になる。

Flag : FCSC{kristy.friedman@outlook.com}

⭐⭐ - iForensics - iBackdoor 1/2
#

解析を続けてバックドアを探す。やがて、あるアプリケーションが改ざんされており、収集時点で端末が感染していたことに気づく… 侵害されたアプリの identifier と、マルウェアのプロセス ID(PID)を特定せよ。

フラグ形式は FCSC{|<P…ample (com.example) and the PID is 1337: FCSC{com.example|1337}。

ここは sysdiagnose を使う必要がある(/sysdiagnose_and_crash...sysdiagnose_2025.04.07_08-06-18-0700_iPhone-OS_iPhone_20A362)。

その前に sysdiagnose とは何か。iOS が生成するアーカイブで、収集時点のシステムログ、クラッシュレポート、ネットワーク状態、設定情報などを自動でまとめた「端末のスナップショット」。本来は性能/安定性の診断用途だけど、侵害後のフォレンジックでもかなり役に立つ。

効率を落とさないために、優秀な EC-DIGIT-CSIRC/sysdiagnose ツールキットを使った: https://github.com/EC-DIGIT-CSIRC/sysdiagnose

┌──(venv)(kali㉿kali)-[~/sysdiagnose]
└─$ sysdiag create /mnt/hgfs/backup/sysdiagnose_and_crashes/...iagnose_2025.04.07_08-06-18-0700_iPhone-OS_iPhone_20A362.tar.gz 

Sysdiagnose file has been processed: /mnt/hgfs/backup/sysdia...diagnose_2025.04.07_08-06-18-0700_iPhone-OS_iPhone_20A362.tar.gz
Case 'C39ZL6V1N6Y6_20250407_080618' created successfully fro...iagnose_2025.04.07_08-06-18-0700_iPhone-OS_iPhone_20A362.tar.gz'

Case の作成に成功:

今回は “ps” パーサを直で使う。ps パーサを走らせると、収集時点のプロセス一覧が全部出る。これは本当に重要なダンプで、理由はこう:

  • 全体の見通し:

ps.txt は端末上で動いているものを丸ごとスナップショットしてくれる。怪しいプロセスはもちろん、名前が紛らわしい/標準外ディレクトリにいる、といった異物も拾える。

  • 権限の違和感:

user/uid と ppid を見るだけで、公式の仕組みを経ずに異常な権限レベルで動いているプロセスを素早くあぶり出せる。

  • 怪しいコマンド / 引数:

command フィールドには実行ファイルと引数が出る。Base64 っぽい文字列(URL や IPv4 など)が引数に混ざっていればすぐ気付けるし、デコードして中身も確認できる。

  • 時間軸の手がかり:

date/time(started, datetime)とパフォーマンス系の値(%CPU など)を合わせると、「いつ起動し」「何をしたか」を推測できる。たとえば CPU が 0% のままでも、裏でデータを抜いている(あるいは活動を隠すために 0% に見せている)可能性はある。

  • 相関:

ps.txt は他のダンプ(network、open files、fslisting など)と統合されている。だから “X が Y に接続” + “Z にファイル作成” みたいに繋げて攻撃のスレッドを組み立てられる。

で、何が目立つか?

root     …   279     1  … /var/containers/Bundle/Application/…/Signal.app/mussel dGNwOi8vOTguNjYuMTU0LjIzNToyOTU1Mg==
root     …   330     1  … /var/containers/Bundle/Application/…/Signal.app/mussel dGNwOi8vOTguNjYuMTU0LjIzNToyOTU1Mg==
root     …   345   344  … /var/containers/Bundle/Application/…/Signal.app/mussel dGNwOi8vOTguNjYuMTU0LjIzNToyOTU1Mg==

1. “mussel” バイナリ – Signal の中に同梱されている。iOS の標準デーモンではない。

2. root で動いてる – UID 0(root)で動くサードパーティ要素は、普通にかなり怪しい。

3. Base64 引数dGNwOi8vOTguNjYuMTU0LjIzNToyOTU1Mg== は Base64。デコードすると tcp://98.66.154.235:29552。外部 IP に向かう TCP、つまり C2 っぽい。

4. ありがちなスパイウェア挙動 – 正体不明の root デーモン + 外向きの C2 通信 = 赤信号。笑

Answer : FCSC{org.whispersystems.signal|345}

⭐⭐ - iForensics - iBackdoor 2/2
#

侵害されたアプリが分かったので、次は「感染前の正規アプリ」がどこで取得されたかを探せ。以下を特定する必要がある:

  • 正規アプリを取得するのに使われたアプリの identifier
  • 正規アプリを保存するのに使われたパス
  • 正規アプリがアンインストールされた日時(ローカル時間)

フラグ形式は FCSC{|<p…FCSC{com.example|/private/var/tmp/test.xyz|2025-01-01 01:00:00}。

状況を整理すると:

  • 対象アプリは Signal
  • 起動はだいたい 7:47AM ごろ
  • アプリのパス、正規アプリを「取得/インストール」したもの、そしてアンインストール日時を特定する必要がある

ここでは mobileinstallation のログに直行した。

mobileinstallation は iOS で install / update / uninstall の全部を司るサブシステム。

JSON 形式の unified log からは:

  • 正確なタイムスタンプ(timestamp + datetime)
  • bundle ID
  • 詳細なアンインストールイベント
  • たまに「なぜ消されたか」の理由(エラー)
    が取れる。

ビンゴ:

// at 07:40:47-07:00, first uinstall of Signal
{
  "datetime": "2025-04-07T07:40:47.000000-07:00",
  "event_type": "MIClientConnection _uninstallIdentities",
  "message": "Uninstall requested by installcoordinationd ... for identity [org.whispersystems.signal]"
}
// at the same second, destruction of its containers:
"message": "Destroying container org.whispersystems.signal ... at /private/var/containers/Bundle/Application/1EC20F02-..."

// at 07:43:55, uninstall of com.fiore.trolldecrypt
{
  "datetime": "2025-04-07T07:43:55.000000-07:00",
  "message": "Uninstalling identifier com.fiore.trolldecrypt"
  // then destroy the corresponding bundle container
}

これで、攻撃者が TrollDecrypt を使ったことが分かる。オープンソ…スなツールで、脱獄なしで端末上のアプリをダンプ/復号できる。具体的には:

  • TrollStore 経由で iDevice にインストールされているアプリ一覧をスキャン
  • 対象アプリの FairPlay バイナリを復号
  • 結果を解析/再インストール/サイドロード等に使える .ipa にパッケージ

TrollStore は CoreTrust の欠陥を悪用して、任意の IPA…署名できる(要するに「何でもインストールできる」系)。その結果、/Library/TrollDecrypt/decrypted/ に復号済み IPA が吐かれる。

正直、もっと賢いやり方は山ほどあるけど(ログの回転を追ったり、状態をちゃんと相関させたり)…、今回は速い手を選ぶ。CTF ではそれが正義なときもある。

要するに .ipa を探せ ばいい。

ここから超ざっくりのタイムラインが引ける:

  1. 07h40m47s: Signal アンインストール(MI log)
  2. 07h40-42m: dump → Signal_7.53_decrypted.ipa(fslisting)
  3. 07h43m55s: TrollDecrypt のアンインストール(MI log)
  4. 07h47mxxs: リパックされた IPA の起動(unified log)

フラグ生成に必要な材料が全部そろった。

Flag : FCSC{com.fiore.trolldecrypt|/private/var/mobile/Li...crypt/decrypted/Signal_7.53_decrypted.ipa|2025-04-07 07:40:47}


⭐⭐⭐ - iForensics - iC2
#

端末に展開された悪性ツール名と…C2 サーバへの通信プロトコル、IP アドレス、ポートを特定せよ。

フラグ形式は FCSC{|||…0.0.1 and the port 1337: FCSC{Cobalt Strike|TCP|127.0.0.1|1337}。

そこで TrollStore まわりと関連する話をもう少し調べた。参考になったのがこれ: https://www.welivesecurity.com/en/eset-research/trollware-trollstore-abuse-leads-to-monitoring-file-extraction-remote-control-on-ios-14-ios-17/

プロトコル、IP、ポートはすでに前の問題で取れてるので、あとは簡単:

Flag : FCSC{SeaShell|TCP|98.66.154.235|29552}