0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

mitmproxy + WireGuardでスマホアプリの通信をキャプチャする方法

0
Posted at

はじめに

スマホアプリのネットワーク通信を解析したい時、ブラウザの通信は簡単に取れても、ネイティブアプリの通信は簡単に見えないことがあります。

ここでは、mitmproxyの基本設定から、プロキシを無視する強固なアプリの通信をWireGuard(VPN)モードで強制的にキャプチャする方法、さらにはPythonスクリプトによるレスポンスの自動保存まで、一連の手順をまとめようと思います。

1. 環境構築(サーバー側の準備)

自分はサーバとしてUbuntu 24.04.4 LTSを使用しました。

mitmproxyのインストール

OSのPython環境を汚さないよう、pipxを使ってインストールします。また、後でQRコードを表示するためのツール(qrencode)も入れておきます。

sudo apt update
sudo apt install pipx qrencode
pipx ensurepath
source ~/.bashrc
pipx install mitmproxy

ファイアウォールの開放

プロキシ用のポート(8080)と、WireGuard VPN用のポート(51820/UDP)を開放します。

sudo ufw allow 8080/tcp
sudo ufw allow 51820/udp
sudo ufw status

2. Wi-Fiプロキシによる通信傍受

ブラウザ(SafariやChrome)や、OSのプロキシ設定に従ってくれるアプリの通信を取得する方法です。

サーバー側の起動

外部(スマホ)からの通信を受け付けるため、0.0.0.0を指定して起動します。

mitmproxy --listen-host 0.0.0.0

※終了する場合は qy を押します。

スマホ側の設定手順

  1. サーバーのIPアドレスを確認
    • ip a コマンド等で確認
    • 例: 192.168.x.x
  2. スマホのWiFi設定から、接続中のWi-Fiのプロキシ設定を「手動」に設定
  3. サーバーのIPアドレス(例: 192.168.x.x)と、ポート8080を入力して保存
  4. スマホのブラウザで http://mitm.itにアクセスし、OSに合ったルート証明書をダウンロード
  5. スマホの設定アプリから証明書を「インストール」し、さらにルート証明書のフルトラスト設定をオンに設定

これでブラウザの通信がターミナル上の mitmproxy 画面に流れてくれば成功です。

3. WireGuardによる強制キャプチャ

アプリが行っているメインの通信が見えない場合、アプリが独自の通信ライブラリ等を使ってOSのプロキシ設定を無視(迂回)している可能性が高いです。

この場合、mitmproxyWireGuardモードを使用して、OSレベルですべての通信を強制的に吸い上げます。

事前準備

  • スマホのWi-Fiプロキシ設定をオフに戻す
  • スマホに公式VPNアプリ「WireGuard」をインストールする

サーバー側の起動

ターミナルで以下のコマンドを実行し、設定用のQRコードを画面に表示させます。

qrencode -t ansiutf8 < ~/.mitmproxy/wireguard.conf

スマホ側の設定とキャプチャ開始

  1. スマホのWireGuardアプリを開き、「QRコードから作成」を選択
  2. ターミナルに表示されたQRコードをスキャンし、適当な名前(mitmproxy等)をつけて保存
  3. 作成したVPNのスイッチをオンに設定
  4. サーバー側でUIモードの mitmproxy を起動
    mitmproxy --mode wireguard
    
  5. 対象のアプリを操作すると、今まで隠れていた通信がキャプチャできる

4. Pythonスクリプトでレスポンスを保存

mitmproxyはPythonスクリプトを読み込ませることで、特定の通信が来た時だけ自動でデータを保存したりできます。

例:特定のURLを含むレスポンスを自動でJSON保存するスクリプト

import time
from mitmproxy import ctx

def response(flow):
    target_keyword = "/api/target_endpoint" # 傍受したいURLの一部

    if target_keyword in flow.request.pretty_url:
        if flow.response and flow.response.status_code == 200:
            timestamp = int(time.time() * 1000)
            filename = f"response_{timestamp}.json"

            with open(filename, "wb") as f:
                f.write(flow.response.content)

            ctx.log.info(f"Saved to {filename} | URL: {flow.request.pretty_url}")

起動方法:

mitmproxy --mode wireguard -s save_target.py

※ログは mitmproxy の画面で Shift + E(イベントログ)を開くと確認できます。

5. 注意点

VPNを繋いだ瞬間、アプリが「通信エラー」になって動かない

アプリ内に「本物のサーバー証明書以外は絶対に拒否する」という強力な防御システム(SSLピンニングなど)が実装されています。これを突破するには、脱獄(Jailbreak)やroot化を行い、Fridaなどのツールでアプリ側の証明書検証ロジックを無効化する高度な技術が必要になります。

WSL2(Windows)上で実行したら繋がらない

WSL2を使う場合、WindowsとWSL間のネットワーク階層が異なるため、スマホから直接WSLにアクセスできません。以下の追加設定が必要です。

  1. ~/.wslconfig ファイルを作成し、networkingMode=mirrored を設定してWSLを再起動(ミラーモードの有効化)
  2. Windows側のPowerShell(管理者)でファイアウォールを開放
    New-NetFirewallRule -DisplayName "Allow mitmproxy" -Direction Inbound -LocalPort 8080 -Protocol TCP -Action Allow
    

ただ、ミラーモードは環境によって不安定な挙動を見せるため、可能であれば純粋なLinux環境に構築することをお勧めします。

解析が終わった後

必ずスマホのWireGuard(VPN)をオフにしてください。オフにし忘れると、サーバーを落とした瞬間にスマホが一切インターネットに繋がらなくなります。

おわりに

スマホアプリが行っている通信を解析してみると色々興味深い事が分かったりするので、おすすめです。

今回はサーバ上で直接wireguardを実行しましたが、Dockerを用いて立てる方法もあります(参考文献参照)。

それではまた。

参考文献

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?