- 2007年の初代iPhoneは米国AT&Tへの加入なしにはアクティベートできず、iPhone Dev Teamはソフトウェアだけで他キャリアで使う方法を公然と探っていった
- 作業は、ファームウェアの解読、アクティベーション回避、書き込み権限の獲得、ARM/Mach-O ツールチェーンの構築、サードパーティアプリの実行、キャリアロック解除へと続く6つのマイルストーンに整理される
- 初期の突破口は、
.ipsw内のramdiskと暗号化されたDMGの解析、そしてlockdowndのアクティベーション検証におけるリプレイの抜け穴を利用したホーム画面へのアクセスだった
- 書き込み権限は、Recovery Modeでramdiskとkernelcacheをロードした後、
fstabとServices.plistを変更し、/root/Mediaに閉じ込められたafcdの代わりにルートファイルシステムを扱えるようにすることで獲得された
- 最終的なアンロックは、basebandファームウェアをダンプ・パッチ・再アップロードし、
AT+CLCK="PN",0,"00000000"を実行するanySIMで自動化され、Appleは2007年9月27日にfirmware v1.1.1で対応した
2007年のiPhoneとDevTeamの目標
- Appleは2007年6月29日にiPhoneを発売し、当時の価格は4GBモデルが**$499**、8GBモデルが**$599**だった
- 箱から取り出したiPhoneは
Connect to iTunes画面だけが表示される非アクティベート状態で、ユーザーはiTunesでAT&Tメンバーシップに加入する必要があった
- 加入後もデバイスはAT&Tにロックされたままだった
- カナダでは初期iPhoneの発売予定がなく、Appleは2008年7月11日にiPhone 3GとともにRogersと合意した
- iPhone Dev Teamはソフトウェアだけで、どのキャリアでもデバイスを使えるようにすることを目標に集まり、iphone.fiveforty.netブログで進捗を頻繁に公開した
- 2007年7月3日には、0時から21時までに8件のアップデートが投稿された
DevTeamの6つのマイルストーン
- ロックされたデバイスを通常のスマートフォンのように使うには、次の段階が必要だった
- システム理解のための読み取りアクセス: Break DMG Password
- 非アクティベート状態からの脱出: Bypass Activation
- システム変更のための書き込みアクセス: Get Write Access
- カスタム実行ファイル生成のためのWorking Toolchain
- basebandがどのキャリアにも接続できるようにするUnlock
- 全体のプロセスを自動化するアプリ: Enable Third-Party Applications
- Wayback Machineによれば、2007年7月6日時点で6つのうち2つのマイルストーンが完了しており、この道のりは2007年9月12日に終わった
- 2007年9月25日にクロールされたステータスページでは、
Decrypt Firmware、Bypass Activation、Get Write Access、Get Working Toolchain、Enable Third-party Applications、Unlock Phoneが完了状態として表示されている
.ipsw解析とファイルシステムの読み取り
- iTunesはデバイス復元用に
.ipsw拡張子のiPhone Softwareアーカイブをダウンロードしており、このファイルはzip形式だった
iPhone1,1_1.0_1A543a_Restore.ipswの中には、img2復旧イメージ、baseband関連のFirmwareフォルダ、iOSカーネルであるkernelcache、2つの大きなDMGファイルが入っていた
- iOS復元アーカイブ全体のサイズは約105MiBだった
- 1つ目のDMGである
694-5259-38.dmgは復元時に使うramdiskで、暗号化されていなかったためddでマウントできた
- ramdiskはiOS全体のファイルシステムではなかったが、
/private/etc/master.passwdから、アプリ実行ユーザーのmobileと、その他のプロセスを実行するrootのパスワードを確認できた
- 2つ目のDMGである
694-5262-39.dmgは通常実行時に使うiOSファイルシステムで、暗号化されていた
- ramdiskの
/usr/sbin/asr内でキーが見つかった
- パスフレーズではなくキーだったため
hdiutilは使えず、DevTeamは独自の復号ツールvfdecrypt.cを作成した
- 復号後、ランタイムファイルシステム全体への読み取りアクセスを得た
アクティベーション回避
- 通常のアクティベーションには、iTunes、Appleサーバー
albert.apple.com、iPhoneのlockdowndが関与する
- iTunesがデバイスの
DeviceID、IMEI、ICCIDを収集する
- 3つの値をトークンにまとめてAppleサーバーへ送る
- Appleサーバーが秘密鍵でトークンに署名して返す
- USBで待機している
lockdowndがApple公開鍵でトークンを検証する
- トークンがAppleから来たものでデバイス情報と一致すれば、状態がActivatedに変わる
- dvdjonの
PhoneActivationServerはiTunesにパッチを当て、HTTPSではなくHTTPでアクティベーションサーバーにアクセスさせ、リクエストを独自サーバーへ回した
- 核心は、署名済みトークンを新しく作るのではなく、成功したアクティベーションからキャプチャした同じsigned tokenを、入力に関係なく返すリプレイ方式だった
- George Hotzの発表によると、
lockdowndは応答内のDeviceID、IMEI、ICCIDが実際の値と一致するか確認していなかった
- DevTeamはハードコードされたsigned tokenをplistから読み取ってiPhoneへ送るCLI
toolsを作り、その後iTunesなしで動作するiPhoneInterfaceへ改善した
書き込み権限と脱獄
- アクティベート済みのiPhoneはiTunesから音楽や写真のようなファイルをアップロードできたが、アップロード担当プロセス
afcdは/root/Mediaにchroot jailで閉じ込められていた
- ユーザーパーティションだけが読み書き可能(
rw)でマウントされ、システムパーティションは読み取り専用(r)だった
- 目標はchroot jailを抜け出してシステムパーティションまで書き込めるようにすることで、ここからjailbreakingという言葉が出てきた
- iPhoneの起動は通常モードとRecovery Modeに分かれる
- 通常モードはBootROM → LLB → iBoot → Kernel → Normal Modeへと続き、各段階が次の段階の署名を確認する
- Recovery ModeはiBoot段階で止まり、iTunesがramdiskやkernelcacheなどをRAMへロードして復元モードに入る
- DevTeamは
iTunesMobile.dll内で、iTunesが復元中にファイルシステムへ書き込む方法を調査し、mount、umount、dittoのようなコマンドを確認した
iPHUCはiTunesMobile.dllの非公開メソッドでRecovery Modeのデバイスと通信するCLIツールだった
- ユーザーがデバイスをRecovery Modeに入れる
- ramdiskをデバイスへ転送し、RAMにロードする
- kernelcacheを送り、ramdiskを指すようにカーネルを起動する
- デバイスがRestore Modeに入る
- 実際の脱獄手順は、
fstabとServices.plistの修正で行われた
fstabでシステムパーティションを読み取り専用ではなくrwでマウントするよう変更する
Services.plistに、/root/Mediaではなく/を基準とする2つ目のafcdサービスを作る
- 再起動後、iTunesは
afcd2経由でファイルシステム全体を見ることができ、システムとユーザーパーティションの両方が読み書き可能になった
- その後、アクティベーションと書き込みアクセスはMac OS XデスクトップアプリINdependenceで自動化された
ツールチェーンとサードパーティアプリ
- ツールチェーンとサードパーティアプリ実行の過程について公開情報は多くないが、少なくとも12人が作業に参加した
- 2007年7月19日にはARMをターゲットとするbinutils toolchainが完成し、DevTeamが自作したプログラムをiPhoneで実行できるようになった
- Nightwatchの
ARM/Mach-O Toolchainにより、最初の独立したHello Worldアプリケーションがコンパイルされ、iPhoneで実行された
- GeoHotzは、Appleの外ではMach-OとARMの組み合わせは以前にはなく、自分たちで作成する必要があったと説明している
- ツールチェーンのもう一つの目標は、
iTunesMobile.soの非公開関数を公開するMobileTerminal.hを再構築し、iTunesを起動せずにafcと通信することだった
- いくつかの発表では、カーネルが
execlの前に実行ファイル署名を確認すると述べているが、初代iPhoneはそうしておらず、v1.1.1で導入されたものとみられる、と整理されている
basebandアンロックとanySIM
- iPhoneは、iOSが動くスマートフォン部分と、電話・モデムの役割を担うbaseband部分に分かれている
- 2つのシステムはそれぞれRAM、CPU、ストレージ、ファームウェア、オシレーターを持つ
- 両者は
/dev/tty.basebandにマウントされたUARTラインでATコマンドをやり取りする
- アンロックに必要なATコマンドは初期から知られていた
AT+CLCK="PN",0,"xxxxxxxx"
xxxxxxxxはNetwork Control KeyであるNCKで、デバイスごとに固有だと考えられていた
- 試行回数は3〜10回に制限され、その後ファームウェアがAT&Tにハードロックされる可能性があった
- basebandにもBootROMと信頼の連鎖があり、署名検証が適用されていた
- MuscleNerdは、basebandにはDFU/Recovery Modeのような安全網がないため、NORやイメージを誤って触るとデバイスを永久に壊す可能性があると説明した
- 2007年7月、DevTeamは
.ipsw内のbasebandをリバースエンジニアリングし、ramdisk内の/usr/local/bin/bbupdaterも解析して、新しいbasebandをアップロードするコマンドを把握した
- 最初のCLI
iUnlockには、ダンプされたファームウェアnorやICE03.12.06_G.flsなど複数のファイルが必要だった
- その後、より簡単な
anySIMアプリが登場し、携帯電話に入れた後、ボタン1つで実行できるようになった
anySIMは次の順序で動作する
/dev/tty.basebandを開き、モデムパラメーターを設定する
- 4MiBサイズのbaseband、つまりNORを
/tmpへダンプする
- basebandをRAMにロードする
- ramdiskから得た
ICE03.12.06_G.fls secpackをロードする
- RAM内のbasebandコマンドにパッチを当て、どのNCKでもアンロックを許可するようにする
- パッチ済みのbasebandを再アップロードする
AT+CLCK="PN",0,"00000000"とAT+CLCK="PN",2を実行する
-0x400トリック
- パッチ済みのbasebandファームウェアは、本来なら署名検査に通らずアップロードが失敗するのが正常だ
- 回避にはminus 0x400オフセットを利用した
- GeoHotzは、最初の
0x400バイトは署名が検証されるまで使われないため、0x400バイト手前から書き始めればよいと説明した
- その後のHacker News読者の説明によれば、basebandは新しいファームウェアを最大
0x800バイトのチャンクで受け取る
- 4MiB全体をRAMに保存してからチェックサムを確認し、フラッシュへ書く構造ではない
- 受信したバイトはすぐにフラッシュへ記録されるが、最初の
0x400バイトだけはRAMにバッファリングされる
- アップロードが終わるとbasebandがチェックサムを検査する
- 失敗すると、バッファリングされた最初の
0x400バイトはフラッシュに記録されず破棄される
-0x400方式は、まず本来のファームウェア位置より0x400バイト手前にごみデータを書き、続けて4MiBのファームウェアを送る方式である
- チェックサムは失敗し、ごみの
0x400バイトは破棄される
- しかし残りの新しいファームウェアは、正しい位置にすでにフラッシュされている
完了とその後のいたちごっこ
- ソフトウェアアンロック全体の手順は、2007年9月12日に公開された
- あわせて大陸別の成功事例が公開され、カナダの事例も含まれていた
- Appleは2007年9月27日にiPhone firmware v1.1.1を素早くリリースした
- DevTeamの進捗バーは、
Decrypt 1.1.1、Get Write Access 1.1.1、Activate 1.1.1、Unlock 1.1.1、Enable Third-party Applications 1.1.1へリセットされた
- この時からAppleとiPhoneハッキングコミュニティの間のいたちごっこが始まり、その後も続いていった
1件のコメント
Hacker News のコメント
ヘッダーがなければコード実行につながらないので安全で、最後に全体の署名を検証し、通ればヘッダーを書いてイメージ全体を有効にします
ここでのトリックは、書き込みたい位置より 0x400バイト前に、まずゴミの 0x400バイトを書き込むことです。この部分はヘッダーとして扱われ、バッファリングされるだけで実際には書き込まれず、残りの送信データは目的の位置に実際に書き込まれます。その後の署名検証は失敗し、もともと望んでいなかった最初の 0x400バイトは書き込まれないので成功、というわけです
データ書き込み前に適用した -0x400 の移動についても、誰かがもう少し説明してくれれば完全に腑に落ちそうです
Seek(fd, 0xA0020000 - 0x400);でデータを書き込むべき位置より 0x400 前にシークし、SendWrite(fd, foo, 0x400, false);で書き込みたい最初の 0x400バイトを 0 で埋めます続いて
SendWrite(fd, fw, fwsize, true);で残りのバイトを実データで埋め、SendEndSecpack(fd);を呼び出します。iPhone は 0x400バイト以降のデータ、つまり書き込みたかった全データをコピーした後、署名検証を試みて失敗します。署名検証に成功していれば、0 のまま残しておいた最初の 0x400バイトもその時点でコピーされていたはずですおそらく PSP をアンロックした PDF か TIFF のエクスプロイトも彼が担当していたと記憶しています。南米のどこか、おそらく大学で働きながら暮らしていたようですが、私が知っているのはそこまでです
本当に面白い時期で、多くを学びました。ただ、George Hotz が、日本語文書へのアクセスを手伝ってくれた何人かの人たちの安全を、そうしないでほしいという度重なる要請にもかかわらず危険にさらし、それが非常にもどかしく、最終的に dev team がプロジェクトを離れる理由になりました
lockdowndが Apple の公開鍵で検証して「Activated」状態に変える仕組みは、今でいう OAuth の前身のように聞こえます/root/Mediaディレクトリを/にシンボリックリンクすることでしたこのリンクはアップグレード中も維持され、その後ファームウェアを更新すると
rootfsにアクセスできました。当時の名前は iOS ではなく iPhone OS でした自動車メーカーにも似ています。新製品や新プラットフォームの初期数年式は買わない方がよいものです
通常「S」は、基本モデルに対する小幅なアップグレードを示す印でした