React Native Application Analysis

Reading time: 15 minutes

tip

AWSハッキングを学び、実践する:HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する:HackTricks Training GCP Red Team Expert (GRTE) Azureハッキングを学び、実践する:HackTricks Training Azure Red Team Expert (AzRTE)

HackTricksをサポートする

アプリケーションがReact Nativeフレームワークで構築されているか確認するには、以下の手順に従ってください。

  1. APKファイルの名前をzip拡張子に変更し、コマンド cp com.example.apk example-apk.zipunzip -qq example-apk.zip -d ReactNative を使用して新しいフォルダーに抽出します。

  2. 新しく作成されたReactNativeフォルダーに移動し、assetsフォルダーを見つけます。このフォルダー内に、minified形式のReact JavaScriptを含むファイル index.android.bundle があるはずです。

  3. コマンド find . -print | grep -i ".bundle$" を使用してJavaScriptファイルを検索します。

注意: APKの代わりにAndroid App Bundle (.aab) が与えられた場合は、まずユニバーサルAPKを生成し、その後バンドルを抽出してください。

bash
# Get bundletool.jar and generate a universal APK set
java -jar bundletool.jar build-apks \
--bundle=app-release.aab \
--output=app.apks \
--mode=universal \
--overwrite

# Extract the APK and then unzip it to find assets/index.android.bundle
unzip -p app.apks universal.apk > universal.apk
unzip -qq universal.apk -d ReactNative
ls ReactNative/assets/

Javascript Code

index.android.bundleの内容を確認すると、アプリケーションのJavaScriptコード(ミニファイされていても)を見つけることができます。これを分析して機密情報や脆弱性を見つけることができます。

バンドルには実際にアプリケーションのすべてのJSコードが含まれているため、異なるファイルに分割することが可能です(逆コンパイルを容易にする可能性があります)ツール react-native-decompiler を使用して。

Webpack

JavaScriptコードをさらに分析するには、ファイルを https://spaceraccoon.github.io/webpack-exploder/ にアップロードするか、次の手順に従ってください。

  1. 同じディレクトリに index.html という名前のファイルを作成し、次のコードを追加します:
html
<script src="./index.android.bundle"></script>
  1. index.htmlファイルをGoogle Chromeで開きます。

  2. OS Xの場合はCommand+Option+JWindowsの場合はControl+Shift+Jを押してDeveloper Toolbarを開きます。

  3. Developer Toolbarで「Sources」をクリックします。フォルダとファイルに分かれたJavaScriptファイルが表示され、メインバンドルを構成しています。

index.android.bundle.mapというファイルが見つかれば、ソースコードを非圧縮形式で分析できます。マップファイルにはソースマッピングが含まれており、圧縮された識別子をマッピングすることができます。

機密の資格情報やエンドポイントを検索するには、次の手順に従います。

  1. JavaScriptコードを分析するための機密キーワードを特定します。React Nativeアプリケーションは、Firebase、AWS S3サービスエンドポイント、プライベートキーなどのサードパーティサービスを使用することがよくあります。

  2. この特定のケースでは、アプリケーションがDialogflowサービスを使用していることが観察されました。その設定に関連するパターンを検索します。

  3. リコンプロセス中にJavaScriptコード内で機密のハードコーディングされた資格情報が見つかったのは幸運でした。

バンドル内のクイックシークレット/エンドポイントハンティング

これらのシンプルなgrepは、圧縮されたJS内でも興味深い指標を浮かび上がらせることがよくあります:

bash
# Common backends and crash reporters
strings -n 6 index.android.bundle | grep -Ei "(api\.|graphql|/v1/|/v2/|socket|wss://|sentry\.io|bugsnag|appcenter|codepush|firebaseio\.com|amplify|aws)"

# Firebase / Google keys (heuristics)
strings -n 6 index.android.bundle | grep -Ei "(AIza[0-9A-Za-z_-]{35}|AIzaSy[0-9A-Za-z_-]{33})"

# AWS access key id heuristic
strings -n 6 index.android.bundle | grep -E "AKIA[0-9A-Z]{16}"

# Expo/CodePush deployment keys
strings -n 6 index.android.bundle | grep -Ei "(CodePush|codepush:\\/\\/|DeploymentKey)"

# Sentry DSN
strings -n 6 index.android.bundle | grep -Ei "(Sentry\.init|dsn\s*:)"

もしOver-The-Airアップデートフレームワークを疑う場合、次のものも探してください:

  • Microsoft App Center / CodePushデプロイメントキー
  • Expo EAS Updates構成(expo-updatesexpo\.io、署名証明書)

JSコードを変更して再構築する

この場合、コードを変更するのは簡単です。アプリの名前を.zip拡張子を使用するように変更し、抽出するだけです。次に、このバンドル内のJSコードを修正してアプリを再構築できます。これで、テスト目的でアプリにコードを注入することができるはずです。

Hermesバイトコード

バンドルにHermesバイトコードが含まれている場合、アプリのJavascriptコードにアクセスできなくなります(ミニファイドバージョンにもアクセスできません)。

バンドルにHermesバイトコードが含まれているかどうかは、次のコマンドを実行して確認できます:

bash
file index.android.bundle
index.android.bundle: Hermes JavaScript bytecode, version 96

ただし、ツール hbctool、新しいバイトコードバージョンをサポートする hbctool の更新されたフォーク、hasmerhermes_rs (Rust ライブラリ/APIs)、または hermes-dec を使用して バイトコードを逆アセンブル し、さらに それを擬似 JS コードにデコンパイル することができます。例えば:

bash
# Disassemble and re-assemble with hbctool (works only for supported HBC versions)
hbctool disasm ./index.android.bundle ./hasm_out
# ...edit ./hasm_out/**/*.hasm (e.g., change comparisons, constants, feature flags)...
hbctool asm   ./hasm_out ./index.android.bundle

# Using hasmer (focus on disassembly; assembler/decompiler are WIP)
hasmer disasm ./index.android.bundle -o hasm_out

# Using hermes-dec to produce pseudo-JS
hbc-disassembler ./index.android.bundle /tmp/my_output_file.hasm
hbc-decompiler   ./index.android.bundle /tmp/my_output_file.js

Tip: オープンソースのHermesプロジェクトは、特定のHermesリリースにhbcdumpなどの開発者ツールも提供しています。バンドルを生成するために使用されたHermesのバージョンに一致するHermesをビルドすると、hbcdumpは関数、文字列テーブル、バイトコードをダンプして、より深い分析が可能になります。

コードを変更して再ビルドする(Hermes)

理想的には、逆アセンブルされたコードを修正(比較の変更、値の変更、または必要な変更)し、その後バイトコードを再ビルドしてアプリを再ビルドできるはずです。

  • 元の**hbctool**は、バンドルを逆アセンブルし、変更後に再構築することをサポートしていますが、歴史的に古いバイトコードバージョンのみをサポートしていました。コミュニティが維持するフォークは、新しいHermesバージョン(ミッド80年代から96まで)へのサポートを拡張しており、現代のRNアプリをパッチするための最も実用的なオプションであることが多いです。
  • ツール**hermes-dec**は、バイトコードの再ビルドをサポートしていません(デコンパイラ/逆アセンブラのみ)が、ロジックをナビゲートし、文字列をダンプするのに非常に役立ちます。
  • ツール**hasmer**は、複数のHermesバージョンの逆アセンブルとアセンブルの両方をサポートすることを目指しています。アセンブルはまだ成熟していませんが、最近のバイトコードで試す価値があります。

hbctoolのようなアセンブラを使用した最小限のワークフロー:

bash
# 1) Disassemble to HASM directories
hbctool disasm assets/index.android.bundle ./hasm

# 2) Edit a guard or feature flag (example: force boolean true)
#    In the relevant .hasm, replace a LoadConstUInt8 0 with 1
#    or change a conditional jump target to bypass a check.

# 3) Reassemble into a new bundle
hbctool asm ./hasm assets/index.android.bundle

# 4) Repack the APK and resign
zip -r ../patched.apk *
# Align/sign as usual (see Android signing section in HackTricks)

注意してください、Hermesバイトコード形式はバージョン管理されており、アセンブラはディスク上の形式と正確に一致する必要があります。形式エラーが発生した場合は、更新されたフォーク/代替に切り替えるか、一致するHermesツールを再構築してください。

動的分析

アプリを動的に分析するための方法として、Fridaを使用してReactアプリの開発者モードを有効にし、**react-native-debugger**を使用してそれに接続することが考えられます。ただし、これにはアプリのソースコードが必要なようです。これに関する詳細はhttps://newsroom.bedefended.com/hooking-react-native-applications-with-frida/で確認できます。

Fridaを使用してリリースでDev Supportを有効にする(注意点)

一部のアプリは、Dev Supportを切り替え可能にするクラスを誤って出荷することがあります。存在する場合は、getUseDeveloperSupport()を強制的にtrueを返すように試みることができます:

javascript
// frida -U -f com.target.app -l enable-dev.js
Java.perform(function(){
try {
var Host = Java.use('com.facebook.react.ReactNativeHost');
Host.getUseDeveloperSupport.implementation = function(){
return true; // force dev support
};
console.log('[+] Patched ReactNativeHost.getUseDeveloperSupport');
} catch (e) {
console.log('[-] Could not patch: ' + e);
}
});

警告: 適切に構築されたリリースビルドでは、DevSupportManagerImpl および関連するデバッグ専用クラスが削除され、このフラグを切り替えるとアプリがクラッシュするか、効果がない場合があります。これが機能する場合、通常はデバッガーやインスペクターを接続してデベロッパーメニューを表示できます。

RNアプリにおけるネットワークインターセプション

React Native Androidは通常、内部でOkHttpに依存しています(Networkingネイティブモジュールを介して)。非ルートデバイスで動的テスト中にトラフィックをインターセプト/観察するには:

  • システムプロキシを使用し、ユーザーCAを信頼するか、他の一般的なAndroid TLSバイパステクニックを使用します。
  • RN特有のヒント: アプリがリリース時に誤ってFlipperをバンドルしている場合(デバッグツール)、Flipper Networkプラグインがリクエスト/レスポンスを公開できます。

一般的なAndroidインターセプションおよびピンニングバイパステクニックについては、以下を参照してください:

Make APK Accept CA Certificate

Objection Tutorial

人気のRNライブラリにおける最近の問題(注意すべき点)

JSバンドルやネイティブライブラリに表示されるサードパーティモジュールを監査する際は、既知の脆弱性を確認し、package.json/yarn.lockのバージョンを検証してください。

  • react-native-mmkv (Android): バージョン2.11.0以前は、オプションの暗号化キーをAndroidログに記録していました。ADB/logcatが利用可能な場合、秘密が回収される可能性があります。2.11.0以上を確保してください。指標: react-native-mmkvの使用、暗号化を伴うMMKV初期化に関するログステートメント。CVE-2024-21668。
  • react-native-document-picker: バージョン< 9.1.1は、Androidでのパストラバーサルに対して脆弱でした(ファイル選択)、9.1.1で修正されました。入力とライブラリのバージョンを検証してください。

クイックチェック:

bash
grep -R "react-native-mmkv" -n {index.android.bundle,*.map} 2>/dev/null || true
grep -R "react-native-document-picker" -n {index.android.bundle,*.map} 2>/dev/null || true
# If you also have the node_modules (rare on release): grep -R in package.json / yarn.lock

参考文献

tip

AWSハッキングを学び、実践する:HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する:HackTricks Training GCP Red Team Expert (GRTE) Azureハッキングを学び、実践する:HackTricks Training Azure Red Team Expert (AzRTE)

HackTricksをサポートする