# ワンクリックパケットキャプチャ

中間者（Man-in-the-middle）ワンクリックパケットキャプチャ機能は、デバイス上でグローバルな中間者攻撃を全自動で開始できます。この機能が**一般的なツールと異なる点**は、**証明書のインストール**や**プロキシの設定**といった問題を気にする必要がなく、また、システムのバージョンによるキャプチャ方法の違いを心配する必要もないことです。Android 6.0から14までシームレスに適用可能で、私たちはすべての問題を処理済みです。ユーザーは具体的な業務に集中するだけで済みます。
さらに、リアルタイムでのパケット改ざんや傍受もサポートしており、一般的なGUIインターフェースのプログラムよりも、「ちょっとパケットを覗いてみる」だけでなく、実際の業務での使用に適しています。

これに加えて、**キャプチャできないパケットはない**（証明書ピニングを除く）ことを保証でき、キャプチャ成功率も通常のソフトウェアの方法より高いです。アプリケーションのhttp/sトラフィックを傍受できます。中間者攻撃の適用と解除は自動的に行われ、スクリプトを終了するとデバイスとネットワークは元の状態に戻ります。ユーザーが他の設定を行う必要はありません。また、スクリプトは**国際的**な中間者パケットキャプチャもサポートしており（アップストリームプロキシ経由で実現）、海外のソフトウェアのパケットも簡単にキャプチャできます。

```{attention}
どのOSをご利用の場合でも、パケットキャプチャを開始する前に、一度で正確に完了させるため、一時的に**ネットワークファイアウォール**を完全に無効にしてください。
```

## 事前準備

まず、現在のPCとデバイスが同じネットワークセグメントにあること、またはUSBで接続されていることを確認してください。以降では、FIRERPAを実行しているモバイルデバイスのIPを `192.168.0.2` と仮定します。次に、プロジェクトのツールコードを正常にクローンし、関連する依存関係をインストール済みであることを確認し、コマンドラインでmitmproxyが正常にインストールされていることを検証してください（コマンドラインで `mitmdump` を入力して検証できます）。

Pythonがインストールされておらず、クローンや依存関係に不慣れな場合は、リリースページから `startmitm.exe` をダウンロードできます。これは `startmitm.py` をパッケージ化したもので、Pythonをインストールせずにパケットキャプチャを実行できます。これはコンソールプログラムであり、コマンドライン引数は `startmitm.py` と同じです（このファイルはウイルスとして検出される可能性がありますので、使用するかどうかはご自身で判断してください）。

## 基本的なパケットキャプチャ

```{hint}
キャプチャ対象のアプリケーションがSSL PINNING（証明書ピニング）やQUICプロトコルを使用している場合、キャプチャの効果に影響を与える可能性があります。私たちは自動的にQUICを強制的にダウングレードしますが、フォールバック時間が発生する可能性があるため、アプリケーションのネットワークが非常に遅く感じられることがあります。しばらくお待ちください。証明書ピニングが有効なアプリケーションは直接キャプチャできません。リバースエンジニアリングによってFridaスクリプトを作成し、SSL PINNINGのロジックをバイパスする必要があります。
```

以下のコマンドで迅速にパケットキャプチャを開始できます。これが最も簡単な使用方法です。

```bash
python3 -u startmitm.py 192.168.0.2
```

```{important}
**`startmitm`コマンドを実行した後は、必ずキャプチャ対象のアプリを完全に終了させてから再起動してください。タスクバーからアプリを閉じるだけでは不十分です。APIを使用して閉じるか、`kill -9`コマンドでアプリ関連の全PIDを強制終了してください。そうしないと、正常にキャプチャできません。**
```

`CONTROL` + `C`キーを一度押すとキャプチャを終了できます。連続して何度も押さないでください。

## キャプチャの共有

LAN内の他のメンバーと一緒に分析したい場合は、以下のコマンドを実行してください。その後、他のメンバーにブラウザで `http://あなたのIPアドレス:7890` を開いてもらうと、あなたと同じキャプチャ画面が表示され、一緒に楽しく分析できます。

```bash
python3 -u startmitm.py 192.168.0.2 --web-port 7890 --web-host 0.0.0.0
```

## 特定アプリのキャプチャ

システム全体のトラフィックではなく、特定のアプリケーションのトラフィックのみを傍受したい場合は、以下の方法でIPアドレスの後に `:パッケージ名` を追加することで、特定のアプリのトラフィックデータをキャプチャできます。以下の例では `com.some.package` のトラフィックのみを傍受します。

```bash
python3 -u startmitm.py 192.168.0.2:com.some.package
```

## リアルタイムでの改ざん

アプリケーションのリクエストデータとレスポンスデータをリアルタイムで改ざんできます。この機能はmitmproxyのイベントフックに基づいています。mitmproxy関連のAPIに従って、ご自身でフックスクリプトを作成する必要があります。フックスクリプトの作成方法については、mitmproxyの公式ドキュメント [docs.mitmproxy.org/stable/addons-examples](https://docs.mitmproxy.org/stable/addons-examples/) およびサンプルコード [mitmproxy/examples/contrib](https://github.com/mitmproxy/mitmproxy/tree/9.0.0/examples/contrib) を参照してください。

作成したフックスクリプトが `http_flow_hook.py` であると仮定し、以下の方法でフックスクリプトを適用します。

```bash
python3 -u startmitm.py 192.168.0.2 -s http_flow_hook.py
```

## 異なるネットワーク環境

お使いのスマートフォンとPCが同じネットワーク上にない場合でも、デバイスに物理的にアクセスできる場合は、USB ADB経由でパケットキャプチャを行うことができます。現在のデバイスがUSB ADBでPCに接続され、正しく承認されていることを確認してください。


PCにADBデバイスが1台だけ接続されている場合は、以下のコマンドでキャプチャを行います。`localhost` はADBデバイスを使用することを意味します。

```bash
python3 -u startmitm.py localhost
```

PCに複数のADBデバイスが接続されている場合は、ADBシリアル番号を指定する必要があります。`adb devices` コマンドの出力から探してください。

```bash
python3 -u startmitm.py localhost --serial bfde362
```

さらに厳しい環境、例えばスマートフォンとPCが同じネットワークになく、物理的にもアクセスできないが、FIRERPAのポートにアクセスできる場合は、中間者攻撃を行うことが可能です。これは通常、内蔵のfrpサービスを使用してFIRERPAをリモートサーバーに転送した場合や、何らかの方法でFIRERPAの65000ポートをどこかに転送した場合に該当します。この状況では、あなたとFIRERPAの間で直接通信できるのはこのポートだけで、他のポートは相互にアクセスできません。この場合、スマートフォンはローカルマシンのどのポートにもアクセスできず、ローカルマシンもスマートフォンのFIRERPAポートにしかアクセスできません（または、スマートフォンがパブリックIPを持ち、ローカルマシンがプライベートネットワーク内にある場合）。このような場合は、以下の方法で行う必要があります。（OpenVPNによるネットワーク相互接続は、上記の場合には該当しません）

この場合、以下の組み合わせで実行する必要があります。まず、`adb_pubkey.py` を使用するか、APIを直接呼び出して自身のADB公開鍵をデバイスにインストールします。インストール完了後、以下の手順に進みます。ここで `x.x.x.x` は65000ポートに接続できるIPまたは `127.0.0.1` であり、実際の状況に応じて変更してください。

```bash
adb connect x.x.x.x:65000
```

最後に、上記と同じ方法で、USB経由のパケットキャプチャ操作を行います。

```bash
python3 -u startmitm.py localhost
```

または、以下のようにします。ここでのserialは `adb connect` のアドレスであり、16進数のシリアル番号ではありません。

```bash
python3 -u startmitm.py localhost --serial x.x.x.x:65000
```

## アップストリームプロキシ / 国際的なパケットキャプチャ

`startmitm` は `mitmproxy` をプロキシサービスとして起動します。デフォルトでは、トラフィックは `mitmproxy` からローカルマシンのネットワークカード経由で送信されます。トラフィックをローカルマシンからではなく、アップストリームプロキシ経由で送信したい場合は、以下の方法でアップストリームプロキシを指定できます。アップストリームプロキシとしては**HTTP**プロトコルのプロキシのみがサポートされています。同時に、DNSポイズニングを避けるために、TCPクエリをサポートするアップストリームDNSを指定する必要があります。

```{tip}
アップストリームプロキシモードを使用するには、mitmproxyのバージョンが9.0.0以上（かつPythonが3.9以上）である必要があります。
```

```bash
python3 -u startmitm.py 192.168.0.2 --upstream http://127.0.0.1:7890 --proxy-dns 8.8.8.8
```

アップストリームHTTPプロキシがログイン認証を必要とする場合は、以下のコマンドに従い `USER:PASSWORD` を置き換えてください。

```bash
python3 -u startmitm.py 192.168.0.2 --upstream http://USER:PASSWORD@x.x.x.x:8080 --proxy-dns 8.8.8.8
```

上記のすべてのコマンドは、デバイストラフィックをupstreamプロキシ経由で送信し、ローカルマシンのすべてのDNSクエリをプロキシ経由で8.8.8.8に送信します。