hacktricks/mobile-pentesting/ios-pentesting/frida-configuration-in-ios.md

16 KiB
Raw Blame History

iOS Frida Configuration

{% hint style="success" %} Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Support HackTricks
{% endhint %}

WhiteIntel

WhiteIntel は、ダークウェブ によって駆動される検索エンジンで、企業やその顧客が stealer malwares によって 侵害 されているかどうかを確認するための 無料 機能を提供しています。

WhiteIntel の主な目標は、情報を盗むマルウェアによるアカウント乗っ取りやランサムウェア攻撃と戦うことです。

彼らのウェブサイトを確認し、無料 でエンジンを試すことができます:

{% embed url="https://whiteintel.io" %}


Installing Frida

Jailbroken デバイスに Frida をインストールする手順:

  1. Cydia/Sileo アプリを開く。
  2. Manage -> Sources -> Edit -> Add に移動する。
  3. URL として "https://build.frida.re" を入力する。
  4. 新しく追加した Frida ソースに移動する。
  5. Frida パッケージをインストールする。

Corellium を使用している場合は、https://github.com/frida/frida/releases から Frida リリースをダウンロードする必要があります(frida-gadget-[yourversion]-ios-universal.dylib.gz)そして、展開して Frida が要求する dylib の場所にコピーします。例: /Users/[youruser]/.cache/frida/gadget-ios.dylib

インストール後、PC で frida-ls-devices コマンドを使用してデバイスが表示されることを確認しますPC がデバイスにアクセスできる必要があります)。
また、frida-ps -Uia を実行して電話の実行中のプロセスを確認します。

Frida without Jailbroken device & without patching the app

非 Jailbroken デバイスでアプリをパッチせずに Frida を使用する方法についてのブログ投稿を確認してください: https://mrbypass.medium.com/unlocking-potential-exploring-frida-objection-on-non-jailbroken-devices-without-application-ed0367a84f07

Frida Client Installation

frida tools をインストールする:

pip install frida-tools
pip install frida

Fridaサーバーがインストールされ、デバイスが起動して接続されている状態で、クライアントが 動作しているか 確認します:

frida-ls-devices  # List devices
frida-ps -Uia     # Get running processes

Frida Trace

# Functions
## Trace all functions with the word "log" in their name
frida-trace -U <program> -i "*log*"
frida-trace -U <program> -i "*log*" | swift demangle # Demangle names

# Objective-C
## Trace all methods of all classes
frida-trace -U <program> -m "*[* *]"

## Trace all methods with the word "authentication" from classes that start with "NE"
frida-trace -U <program> -m "*[NE* *authentication*]"

# Plug-In
## To hook a plugin that is momentarely executed prepare Frida indicating the ID of the Plugin binary
frida-trace -U -W <if-plugin-bin> -m '*[* *]'

すべてのクラスとメソッドを取得

  • 自動補完: frida -U <program>を実行するだけです。
  • すべての利用可能なクラスを取得する(文字列でフィルタリング)

{% code title="/tmp/script.js" %}

// frida -U <program> -l /tmp/script.js

var filterClass = "filterstring";

if (ObjC.available) {
for (var className in ObjC.classes) {
if (ObjC.classes.hasOwnProperty(className)) {
if (!filterClass || className.includes(filterClass)) {
console.log(className);
}
}
}
} else {
console.log("Objective-C runtime is not available.");
}

{% endcode %}

  • クラスすべての メソッドを取得する(文字列でフィルタリング)

{% code title="/tmp/script.js" %}

// frida -U <program> -l /tmp/script.js

var specificClass = "YourClassName";
var filterMethod = "filtermethod";

if (ObjC.available) {
if (ObjC.classes.hasOwnProperty(specificClass)) {
var methods = ObjC.classes[specificClass].$ownMethods;
for (var i = 0; i < methods.length; i++) {
if (!filterMethod || methods[i].includes(filterClass)) {
console.log(specificClass + ': ' + methods[i]);
}
}
} else {
console.log("Class not found.");
}
} else {
console.log("Objective-C runtime is not available.");
}

{% endcode %}

  • 関数を呼び出す
// Find the address of the function to call
const func_addr = Module.findExportByName("<Prog Name>", "<Func Name>");
// Declare the function to call
const func = new NativeFunction(
func_addr,
"void", ["pointer", "pointer", "pointer"], {
});

var arg0 = null;

// In this case to call this function we need to intercept a call to it to copy arg0
Interceptor.attach(wg_log_addr, {
onEnter: function(args) {
arg0 = new NativePointer(args[0]);
}
});

// Wait untill a call to the func occurs
while (! arg0) {
Thread.sleep(1);
console.log("waiting for ptr");
}


var arg1 = Memory.allocUtf8String('arg1');
var txt = Memory.allocUtf8String('Some text for arg2');
wg_log(arg0, arg1, txt);

console.log("loaded");

Frida Fuzzing

Frida Stalker

From the docs: StalkerはFridaのコードトレースエンジンです。スレッドを追跡し、実行されるすべての関数すべてのブロック、さらにはすべての命令キャプチャすることができます。

Frida Stalkerを実装した例はこちらです。

これは、関数が呼び出されるたびにFrida Stalkerをアタッチする別の例です

console.log("loading");
const wg_log_addr = Module.findExportByName("<Program>", "<function_name>");
const wg_log = new NativeFunction(
wg_log_addr,
"void", ["pointer", "pointer", "pointer"], {
});

Interceptor.attach(wg_log_addr, {
onEnter: function(args) {
console.log(`logging the following message: ${args[2].readCString()}`);

Stalker.follow({
events: {
// only collect coverage for newly encountered blocks
compile: true,
},
onReceive: function (events) {
const bbs = Stalker.parse(events, {
stringify: false,
annotate: false
});
console.log("Stalker trace of write_msg_to_log: \n" + bbs.flat().map(DebugSymbol.fromAddress).join('\n'));
}
});
},
onLeave: function(retval) {
Stalker.unfollow();
Stalker.flush();  // this is important to get all events
}
});

{% hint style="danger" %} デバッグの目的では興味深いですが、ファジングにおいては、常に .follow().unfollow() を行うのは非常に非効率です。 {% endhint %}

Fpicker

fpicker は、AFL++ モードやパッシブトレースモードなど、プロセス内ファジングのためのさまざまなファジングモードを提供する Fridaベースのファジングスイート です。Fridaがサポートするすべてのプラットフォームで動作するはずです。

# Get fpicker
git clone https://github.com/ttdennis/fpicker
cd fpicker

# Get Frida core devkit and prepare fpicker
wget https://github.com/frida/frida/releases/download/16.1.4/frida-core-devkit-16.1.4-[yourOS]-[yourarchitecture].tar.xz
# e.g. https://github.com/frida/frida/releases/download/16.1.4/frida-core-devkit-16.1.4-macos-arm64.tar.xz
tar -xf ./*tar.xz
cp libfrida-core.a libfrida-core-[yourOS].a #libfrida-core-macos.a

# Install fpicker
make fpicker-[yourOS] # fpicker-macos
# This generates ./fpicker

# Install radamsa (fuzzer generator)
brew install radamsa
  • FSを準備する:
# From inside fpicker clone
mkdir -p examples/wg-log # Where the fuzzing script will be
mkdir -p examples/wg-log/out # For code coverage and crashes
mkdir -p examples/wg-log/in # For starting inputs

# Create at least 1 input for the fuzzer
echo Hello World > examples/wg-log/in/0
  • ファズァースクリプト (examples/wg-log/myfuzzer.js):

{% code title="examples/wg-log/myfuzzer.js" %}

// Import the fuzzer base class
import { Fuzzer } from "../../harness/fuzzer.js";

class WGLogFuzzer extends Fuzzer {

constructor() {
console.log("WGLogFuzzer constructor called")

// Get and declare the function we are going to fuzz
var wg_log_addr = Module.findExportByName("<Program name>", "<func name to fuzz>");
var wg_log_func = new NativeFunction(
wg_log_addr,
"void", ["pointer", "pointer", "pointer"], {
});

// Initialize the object
super("<Program nane>", wg_log_addr, wg_log_func);
this.wg_log_addr = wg_log_addr; // We cannot use "this" before calling "super"

console.log("WGLogFuzzer in the middle");

// Prepare the second argument to pass to the fuzz function
this.tag = Memory.allocUtf8String("arg2");

// Get the first argument we need to pass from a call to the functino we want to fuzz
var wg_log_global_ptr = null;
console.log(this.wg_log_addr);
Interceptor.attach(this.wg_log_addr, {
onEnter: function(args) {
console.log("Entering in the function to get the first argument");
wg_log_global_ptr = new NativePointer(args[0]);
}
});

while (! wg_log_global_ptr) {
Thread.sleep(1)
}
this.wg_log_global_ptr = wg_log_global_ptr;
console.log("WGLogFuzzer prepare ended")
}


// This function is called by the fuzzer with the first argument being a pointer into memory
// where the payload is stored and the second the length of the input.
fuzz(payload, len) {
// Get a pointer to payload being a valid C string (with a null byte at the end)
var payload_cstring = payload.readCString(len);
this.payload = Memory.allocUtf8String(payload_cstring);

// Debug and fuzz
this.debug_log(this.payload, len);
// Pass the 2 first arguments we know the function needs and finally the payload to fuzz
this.target_function(this.wg_log_global_ptr, this.tag, this.payload);
}
}

const f = new WGLogFuzzer();
rpc.exports.fuzzer = f;

{% endcode %}

  • ファズァーをコンパイルする:
# From inside fpicker clone
## Compile from "myfuzzer.js" to "harness.js"
frida-compile examples/wg-log/myfuzzer.js -o harness.js
  • **radamsa**を使用してfuzzer **fpicker**を呼び出します:

{% code overflow="wrap" %}

# Indicate fpicker to fuzz a program with the harness.js script and which folders to use
fpicker -v --fuzzer-mode active -e attach -p <Program to fuzz> -D usb -o examples/wg-log/out/ -i examples/wg-log/in/ -f harness.js --standalone-mutator cmd --mutator-command "radamsa"
# You can find code coverage and crashes in examples/wg-log/out/

{% endcode %}

{% hint style="danger" %} この場合、私たちは各ペイロードの後にアプリを再起動したり、状態を復元したりしていません。したがって、Fridaがクラッシュを見つけた場合、そのペイロードの後の次の入力アプリをクラッシュさせる可能性があります(アプリが不安定な状態にあるため)、たとえ入力がアプリをクラッシュさせるべきでない場合でもです。

さらに、FridaはiOSの例外信号にフックするため、Fridaがクラッシュを見つけた場合、おそらくiOSクラッシュレポートは生成されません

これを防ぐために、たとえば、各Fridaクラッシュの後にアプリを再起動することができます。 {% endhint %}

ログとクラッシュ

macOSコンソールまたは**log** CLIを使用してmacOSのログを確認できます。
また、**idevicesyslogを使用してiOSのログも確認できます。
一部のログは情報を省略し、
<private>**を追加します。すべての情報を表示するには、https://developer.apple.com/bug-reporting/profiles-and-logs/からいくつかのプロファイルをインストールして、そのプライベート情報を有効にする必要があります。

何をすべきかわからない場合:

vim /Library/Preferences/Logging/com.apple.system.logging.plist
<?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>Enable-Private-Data</key>
<true/>
</dict>
</plist>

killall -9 logd

クラッシュは以下で確認できます:

  • iOS
  • 設定 → プライバシー → 分析と改善 → 分析データ
  • /private/var/mobile/Library/Logs/CrashReporter/
  • macOS:
  • /Library/Logs/DiagnosticReports/
  • ~/Library/Logs/DiagnosticReports

{% hint style="warning" %} iOSは同じアプリのクラッシュを25件しか保存しないため、これをクリアする必要があります。さもなければ、iOSはクラッシュの作成を停止します。 {% endhint %}

Frida Android チュートリアル

{% content-ref url="../android-app-pentesting/frida-tutorial/" %} frida-tutorial {% endcontent-ref %}

参考文献

WhiteIntel

WhiteIntelは、ダークウェブを利用した検索エンジンで、企業やその顧客がスティーラーマルウェアによって侵害されているかどうかを確認するための無料機能を提供しています。

WhiteIntelの主な目標は、情報を盗むマルウェアによるアカウント乗っ取りやランサムウェア攻撃と戦うことです。

彼らのウェブサイトを確認し、無料でエンジンを試すことができます:

{% embed url="https://whiteintel.io" %}

{% hint style="success" %} AWSハッキングを学び、練習するHackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、練習するHackTricks Training GCP Red Team Expert (GRTE)

HackTricksをサポートする
{% endhint %}