diosra2’s blog

iOSのJailbreak、ダウングレード

iOS 8.4.1のuntethered jailbreakを作成。(別アプローチ)



iOS 8.4.1の(untethered) JailbreakはtihmstarによるEtason JBがありますね。

今回は違う方法を用いてuntethered jailbreakを作成してみましたので記事にまとめておきたいと思います。

 

iOS 8.4.1

iOS 8.4.1は、2015年公開のiOS 8の最終バージョンです。TaiGで使用されたexploitが修正されたため、長い間脱獄できませんでした。このバージョンの脱獄可能になるのはiOS 9.3.5で修正されたPegasusと呼ばれるexploitが公開されてからになります。

iOS 8.4.1はiPhone 5c以外のA5-A6デバイスではiOS 6.0-7.0.6からのOTA updateのためにまだAppleにより署名されているため、誰でも手にすることができる環境となります。要するに、これらのデバイスで条件なしにuntethered jailbreakを手にすることができる最終バージョンです。

 

iOS 8は5年前の古いファームウェアです。普段使いには危ないので最新バージョンにアップデートしてください。この記事はかつてはるか昔に存在した脆弱性を見てみようというものなので、不正利用等を助長するものではありません。

 

脱獄する

今回のuntethered jailbreakは3つの部品により成り立ちます。

一つはカーネルエクスプロイト。最重要ですね。

もう一つはコード署名を回避する方法

最後はデバイスのサンドボックス外にアクセスして任意のコードを実行する方法です。

 

Etason JBでは、カーネルエクスプロイトはCVE-2016-4655, CVE-2016-4656の2つ、コード署名はAppleにより署名されているjscによりCVE-2016-4657をトリガーして回避。最後はAppleの開発者用署名を悪用し、PegasusでJailbreakすることで達成されます。

 

今回は、カーネルエクスプロイトは同じですが残り2つを別のアプローチで行いました。

 

Exploit

exploitは、benjamin氏により公開されているTridentを使用することができます。

CVE-2016-4655のkernel information leakによりKASLRを破り、CVE-2016-4656でカーネル権限を取得してカーネルにパッチを当てて脱獄します。

脱獄したあとは、/Library/LaunchDeamonsにあるデーモンをロードし、substrateをInjectします。

*Kernel Patch

f:id:diosra2:20200131163620p:plain

*proc_enforce: 0に書き換え

*cs_enforcement_disable_amfi: 1をセット

*PE_i_can_has_debugger: 1をセット

*vm_map_enter: NOP, CMP R0, R0

*vm_map_protect: BICNE.WをNOP out

*mount_common: rootfsのマウント制限を回避

*mapForIO: WriteProtectを回避

*substrate: ITTT NEをNOP out

*sandbox call i_can_has_debugger: BLをNOP out

*sb_evaluate: payloadを空き領域に書き込みsb_evaluateをhook

 

Codesignature

コード署名の回避にはPangu9で使用されたdyldの脆弱性を使用します。

The iPhone Wikiより: dyld exploit in dyld shared cache handling to override MISValidateSignature in libmis.dylib for persistency (CVE-2015-7079)

このバグはこちらでPangu Teamのスライドにより解説されています。

https://blog.pangu.io/wp-content/uploads/us-16-Pangu9-Internals.pdf

要するに、偽のヘッダーでdyld shared cacheのmappingを制御可能なので、これを使用してlibmis.dylib内の"_MISValidateSignature"を0で返すようにしてやれば、コード署名検証が常に成功することになります。

 

r-- / rw-メモリは操作できます。libmis.dylib内のexport tabelを変更し、_MISValidateSignatureがreturn 0で返すようにします。32-bitの場合、movs r0, 0; bx lrとなるアドレスを探し、_MISValidateSignatureのポイントをここに変更します。

コード署名は常に成功するようになりました。

 

dyld shared cache

jtoolを使用することでheaderを見ることができます。

Original

 

これを、偽のヘッダーと先ほどの変更を適用させるために、このように変更します。

先ほどの変更がマップされ、コード署名は常に0を返すようになります。これで未署名のexploitを実行できます。

 

untether

untethered jailbreakのためのパーツは整いました。あとはこれを起動時に実行させるだけです。

まず、Tridentのバイナリ(untether)を以下のentitlementを含むようにldidで署名します。

そして、デバイス内を操作してuntetherを設置します。

 

デバイスに書き込む

書き込む方法はいくつかあります。一番簡単なのはcheckm8を使用してSSH ramdiskを送り込んでデバイス内を操作することかなと思います。Xcodeを使用してAppベースでインストールさせても良し、yaluの手法を借りてきても良し、CFWで復元しても良いです。(当時利用できたものだとyaluの手法に限りますね。)

デバイスをDFU modeにしてcehckm8を実行し、pwned DFU modeとなったデバイスにramdiskを送り込んでtethered Bootを行います。このramdiskにはsshを含めておくことで、デバイス内を自由に操作可能となります。/dev/disk0s1s1を/mnt1にマウントし以下の操作をします。

*untether

dyld_shared_cacheを改変したものに置き換える。

Tridentをバイナリ(untether)を/mnt1/trident8に設置する。

"/mnt1/System/Library/LaunchDaemons" 内のplistを、以下のものを除いて全て"/mnt1//Library/LaunchDaemons"に移動する。

*除外リスト

bootps.plist

com.apple.CrashHousekeeping.plist

com.apple.jetsamproperties.XX.plist

com.apple.mDNSResponder.plist

com.apple.MobileFileIntegrity.plist

"/mnt1/usr/libexec/CrashHousekeeping"を"/mnt1/usr/libexec/CrashHousekeeping_"にリネームする

/mnt1/usr/libexec/CrashHousekeepingを"/trident8"のsymlinkに変える

 

*Jailbreak

Cydiaをインストールする。

/mnt1/etc/fstabを操作し、データパーティションからnosuid,nodevを削除する。

 

再起動すると、untethered jailbreakになります。

 


Copyright (C) 2017-2018 Diosra2. All Rights Reserved.