Akatsuki Hackers Lab | 株式会社アカツキ(Akatsuki Inc.)

Akatsuki Hackers Labは株式会社アカツキが運営しています。

ペンテスターはApple Silicon Macに夢を見るか?

この記事は、Akatsuki Advent Calendar 2021の24日目の記事です。

こんにちは、セキュリティエンジニアの小竹 泰一(aka tkmru)です。 アカツキでは、アプリケーションに対する脆弱性診断や社内ネットワークに対するペネトレーションテスト、ツール開発/検証を担当しています。

Apple Silicon MacをiOSアプリの脆弱性診断に使用する際にどのような利点、欠点があるのか調査した結果を書きたいと思います。2019年のAkatsuki Advent Calendarから続く、大好評企画(?)「ペンテスターは〇〇に夢を見るか」シリーズ第二弾です。 第一弾はこちら

Apple Silicon MacでiOSアプリが動作するように!

M1搭載MacBookが登場して、iOSアプリがエミュレータを使わずともmacOS上で動作するようになりました。

iPhoneおよびiPad向けAppが、Appleシリコン搭載のMac上のMac App Storeでも提供されるようになりました。AppをMac向けに修正する必要はなく、ユーザーとデベロッパの双方にとって新たな可能性が広がります。iPhoneおよびiPad向けAppで利用可能な既存の機能を使って、キーボード、ウインドウ、タッチ入力のジェスチャと連携して動作するようAppを最適化することができます。さらに既存の機能を確認し、必要に応じて機能を有効化/無効化することで、AppのMac上での動作を調整することも可能です。

developer.apple.com

JailbreakしていないiPhoneはAndroidと比べ、プラットフォーム側の制限が厳しく、かゆいところに手が届かないがちです。 そこでApple Silicon Macを使うことでiOSアプリの脆弱性診断が簡単になるのではと考え、検証しました。 この記事はその検証結果をまとめたものです。

iOSアプリのインストール方法

IPAファイルをダブルクリックすることでインストールできます。 Apple Silicon Mac上では、IPAファイルはインストーラとして振る舞います。 どんなIPAファイルでもインストールできるわけではなく、iOSデバイスと同等の制限があり、macOSのUUIDを実行許可している証明書でリザインされたものしかインストールできません。

f:id:TAKEmaru:20211223211535p:plain
インストール画面

tap1000000.appは検証用に作成したアプリの名前です。この記事内では度々tap1000000.appが登場します。

各種Tips

検証する過程で分かった各種Tipsを紹介します。 デスクトップアプリと同じようにiOSアプリを扱えました。

アクティビティモニタが便利

macOSにデフォルトでインストールされているアクティビティモニタを開き、実行しているプロセスを選択することで、プロセスの詳細な情報を取得できます。 PIDや使用しているファイルを確認できます。

f:id:TAKEmaru:20211220152731p:plain
アクティビティモニタの画面例

これはiOSアプリのためのTipsではなく、macOS上で動作する全てのアプリケーションで使えるテクニックです。

メモリマップの取得方法

vmmapコマンドでPIDで指定したプロセスのメモリマップを取得できます。

$ vmmap 10299
Process:         tap1000000 [10299]
Path:            /Volumes/VOLUME/*/tap1000000.app/tap1000000
Load Address:    0x1025e8000
Identifier:      jp.hoge.tap1000000
Version:         0.1 (0)
Code Type:       ARM64
Platform:        iOS
Parent Process:  ??? [1]
...

==== Non-writable regions for process 10299
REGION TYPE                    START - END         [ VSIZE  RSDNT  DIRTY   SWAP] PRT/MAX SHRMOD PURGE    REGION DETAIL
__TEXT                      1025e8000-1025f0000    [   32K    16K     0K     0K] r-x/r-x SM=COW          /var/folders/*/tap1000000.app/tap1000000
__LINKEDIT                  1025f4000-1025fc000    [   32K     0K     0K     0K] r--/r-- SM=COW          /var/folders/*/tap1000000.app/tap1000000
VM_ALLOCATE                 102604000-102608000    [   16K    16K    16K     0K] r--/rwx SM=PRV  
shared memory               102608000-10260c000    [   16K    16K    16K     0K] r--/r-- SM=SHM  
MALLOC metadata             10260c000-102610000    [   16K    16K    16K     0K] r--/rwx SM=COW          MallocHelperZone_0x10260c000 zone structure
MALLOC guard page           102614000-102618000    [   16K     0K     0K     0K] ---/rwx SM=ZER  
MALLOC guard page           102620000-102624000    [   16K     0K     0K     0K] ---/rwx SM=ZER  
MALLOC guard page           102624000-102628000    [   16K     0K     0K     0K] ---/rwx SM=NUL  
MALLOC guard page           102630000-102638000    [   32K     0K     0K     0K] ---/rwx SM=NUL  
...

これもiOSアプリのためのTipsではなく、macOS上で動作する全てのアプリケーションで使えるテクニックです。

中間者攻撃の方法

システム環境設定からネットワーク -> 詳細設定 を開き、使用しているネットワークを選択した後、 詳細 -> プロキシの順にメニューを開くことでプロキシの設定画面を開けます。 HTTP/HTTPS通信を取得するには構成するプロトコルにWebプロキシ(HTTP)保護されたWebプロキシ(HTTPS)を選択し、プロキシツールが動いているアドレス/ポートを指定してください。

f:id:TAKEmaru:20211220153633p:plain
プロキシ設定例

ただ、PCから出る全ての通信が指定したプロキシツールを通るようになるので、プロキシツール側でうまくフィルタしてあげる必要があります。 この辺りもiPhoneの場合と変わりませんが、PC上では診断対象のアプリと並行してブラウザなども動かすと思うのでフィルタリングがより大切になります。

各種パス

インストールされたアプリは次のパスに配置されます。

  • /Applications/tap1000000.app/Wrapper/tap1000000.app

また、用途は特定できていませんが、アプリの実行中は次のパスにもアプリが配置されます。

  • /private/var/folders/hc/XXXXXXXXnsfn1_c9n20jxw40000gq/X/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX/d/Wrapper/tap1000000.app

アプリが使用するアプリケーションコンテナは次のパスに配置されます。

  • /Users/taichi.kotake/Library/Containers/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX/Data/

このあたりのパスは前述のアクティビティモニタから確認できるので、興味がある方は見てみてください。

欠点

現状、Apple Silicon Mac上でWindows VMを動かせないのは欠点です。 ゲームアプリの脆弱性診断では、Unity製アプリのバイナリのシンボルを復元するIl2CppDumperというツールを動かすためにWindows VMをしばしば使います。

github.com

まず、VMware FusionがApple Silicon Mac上では動作しません。 VMware FusionのApple Silicon Mac対応は進んでいるようですが、Intel版のOSをサポートはしないようで、Apple Silicon Mac対応VMware Fusionがリリースされたとしても、Intel版Windowsは実行できない見込みです。 Microsoftは仮想環境向けにARM版Windowsを販売しないようで、当分はApple Silicon Mac上でWindows VMを動かせなさそうです。

news.mynavi.jp

内製メモリ改ざんツールをApple Silicon Macに対応させた話

アカツキのセキュリティチームでは脆弱性診断のためのツールをいくつか内製し、OSSとして公開しています。 その中の一つにipa-meditというiOSアプリ向けのメモリ改ざんツールがあります。 このツールをApple Silicon Mac上で動作するiOSアプリに対応させました。ここでは、その解説をしたいと思います。

github.com

Apple Silicon Macに対応する以前のバージョンのipa-meditは以前、Black Hat USA 2021 Arsenalで発表しました。 この記事はApple Silicon Macの解説のための記事なので、iPhone、iPad上で動作するiOSアプリに対してメモリ改ざんするロジックの解説はここではしません。興味がある方は次のスライドをご覧ください。

speakerdeck.com

メモリ改ざんとは

チートの方法の1つにUI上に表示されている値を端末のメモリ上から検索し、見つけた値を改ざんする、「メモリ改ざん」という手法があります。 これはゲームへのチート方法の中で最も簡単な方法で、脆弱性診断の際には実際にメモリ上のデータを改ざんをすることでチートできるかどうか確認しています。 対策としては、XOR等を使ってメモリ上ではエンコードされた状態で値を保持し、UI上に表示されている値を検索されても見つからないようにする方法があります。 ipa-meditでは次のようにメモリ改ざんを行えます。

LinuxとmacOSの違いに困惑...

要はmacOS上で動作するアプリケーションをデバッグすればいいだけなので、シュッと対応できるのではと開発時には考えていました。 しかし、慣れ親しんでいたLinux環境でのシステムプログラミングとは違い、macOS固有の知識が要求されるため、いくつか戸惑うことがありました。

Linuxとの違いに戸惑う....

apk-meditというAndroid向けのメモリ改ざんツールを以前作成したことがあったので、このツールと同じロジックで作れるのではないかと考えていましたが、かなり勝手が違いました。 LLDBやGolang製デバッガのDelveなどのmacOSでも動作するデバッガのコードが実装の参考になりました。

hackerslab.aktsk.jp

/proc がない....

Linux系OSの場合は/proc/$pid/mapsから、特定のプロセスのメモリマップを取得し、/proc/$pid/memよりメモリを読み書きできます。 しかし、macOSには/procがありません。 そのため、専用のAPIを用いて、メモリマップの取得とメモリの読み書きを行う必要があります。 ipa-meditではメモリマップの取得には前述のvmmapコマンドを使っていますが、 メモリの読み込みにはmach_vm_readを、メモリへの書き込みにはmach_vm_writeを使っています。

ptraceでメモリの読み書きができない....

ptraceは、デバッガを実装する際によく用いられるシステムコールで、第一引数にrequestという動作モードを表す定数を指定することで動作を切り替えられます。 Linux系OSの場合はptraceを使ってプロセスへアタッチし、プロセスを停止させたり、メモリを読み書きできます。

ptrace(int request, pid_t pid, caddr_t addr, int data);

しかし、macOSの場合はメモリの読み書きがサポートされておらず、第一引数にメモリを読むためのPTRACE_PEEKDATA、メモリへ書き込むためのPTRACE_POKEDATAを指定できません。そのため、前述のmach_vm_readmach_vm_writeを使ってメモリの読み書きを行っています。 macOSでもアタッチ/デタッチにはptraceを使えるので、ipa-meditではアタッチ/デタッチにのみptraceを使っています。

署名まわりで戸惑う....

macOSでは、署名されていないプログラムをデバッガとして使うことはできません。 デバッガとして使うプログラムには、com.apple.security.cs.debuggerという属性を有効にするようentitlements.plistで指定し、署名しておく必要があります。 ipa-meditではmake buildコマンドでビルドする際に署名の処理も行っています。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>com.apple.security.cs.debugger</key>
    <true/>
</dict>
</plist>

また、デバッグ対象のアプリではcom.apple.security.get-task-allow属性を有効にしておく必要があります。 この属性はデバッガによるアタッチを許可します。 Apple Silicon Macを使ってiOSアプリの脆弱性診断をする際には、リザインの際にこの属性を有効にしておかないとメモリ改ざんを行えません。 デバック対象のアプリでcom.apple.security.get-task-allow属性が有効になっているかどうかはcodesignコマンドで確認できます。

$ codesign -d --entitlements :- 47071
Executable=/private/var/folders/hc/XXXXXXXXnsfn1_c9n20jxw40000gq/X/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX/d/Wrapper/tap1000000.app/tap1000000
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>application-identifier</key>
    <string>XXXXXXXXXX.jp.hoge.tap1000000</string>
    <key>com.apple.developer.team-identifier</key>
    <string>XXXXXXXXXX</string>
    <key>get-task-allow</key>
    <true/> <-- ここがtrueになっている必要がある
    <key>keychain-access-groups</key>
    <array>
        <string>XXXXXXXXXX.jp.hoge.tap1000000</string>
    </array>
</dict>
</plist>

まとめ

検証の結果、Apple Silicon Mac上で動作するiOSアプリに対しても問題なく脆弱性診断ができそうだと分かりました。 Apple Silicon Mac上のiOSアプリに対して脆弱性診断っぽいことを行うまとまったドキュメントは、インターネット上にまだなく(多分)、MITMする方法すら検索しても出てこないので、公開する意義のあるいいドキュメントになったかなと思います。

また、PC上で動作しているため、アプリケーションコンテナ内のファイルへの操作をXcodeを介さず行える点や、デバッガのアタッチをデスクトップアプリと同じ方法で行える点から、一部の診断は実機のiPhoneを使うよりやりやすくなる印象を受けました。 iPhoneをJailBreakしなくとも、ターミナルが動作している環境でiOSアプリを動かせるのは便利かなーと思います。 今後、Apple Silicon Mac環境特有の何かを用いたiOSアプリへのハック方法が出てくると面白いなと思います。

関連情報

Apple Silicon Macには、Intel Mac向けにビルドされたアプリケーションをApple Silicon Mac上で動作させるRosetta 2という仕組みが搭載されています。 この動作を明らかにするProject ChampollionというリサーチをFFRIが行っており面白いです。 iOSアプリとは関係ないですが、Apple Silicon Mac特有の仕組みに興味がある方はこちらもおすすめです。

github.com