MacOS全体のプロキシ設定をローカルで起動したmitmproxyにセットして、iOS Simulator のHTTP/HTTPS通信を採取・変更するメモ。
mitmproxy の基本設定
mitmproxyをインストール (version 0.17.1):
$ brew install mitmproxy
初回起動時に ~/.mitmproxy/
以下にCA証明書が生成される:
$ mitmproxy # Ctrl-C で抜ける
Macのプロキシ設定をON/OFFする定型処理を足した下のスクリプトを mitmproxy-wrap
などの名前で保存して実行できるようにする:
#!/bin/sh
# save as mitmproxy-wrap
sudo networksetup -setwebproxy Wi-Fi localhost 8080
sudo networksetup -setsecurewebproxy Wi-Fi localhost 8080
sudo networksetup -setwebproxystate Wi-Fi on
sudo networksetup -setsecurewebproxystate Wi-Fi on
mitmproxy "$@"
sudo networksetup -setwebproxystate Wi-Fi off
sudo networksetup -setsecurewebproxystate Wi-Fi off
iOS Simulator の証明書設定
XcodeでiOS Simulatorで1つ以上のデバイス(OS)を起動&終了しておく。
ADVTrustStoreにある iosCertTrustManager.py
を使ってmitmproxyのCA証明書をiOS Simulatorの各デバイスにインストール:
$ ./iosCertTrustManager.py -a ~/.mitmproxy/mitmproxy-ca-cert.pem
subject= CN = mitmproxy, O = mitmproxy
Import certificate to iPhone 6 v10.0 [y/N] y
Importing to /Users/...(snip).../Library/Developer/CoreSimulator/Devices/...(snip).../data/Library/Keychains/TrustStore.sqlite3
Existing certificate replaced
...(snip)...
mitmproxyでHTTP応答を書換える
フィルタのスクリプトを準備:
新しいmitmproxyの場合 (2.0.2で動作確認):
# Usage: -s "replace_response_body.py <url_prefix> <file>"
import argparse
class Replacer:
def __init__(self, url_prefix, file_name):
self.url_prefix, self.file_name = url_prefix, file_name
def response(self, flow):
flow.response.replace(self.url_prefix, self.file_name)
if flow.request.pretty_url.startswith(self.url_prefix):
with open(self.file_name, "r") as file:
flow.response.text = file.read()
def start():
parser = argparse.ArgumentParser()
parser.add_argument("url_prefix", type=str)
parser.add_argument("file_name", type=str)
args = parser.parse_args()
return Replacer(args.url_prefix, args.file_name)
古いmitmproxyの場合 (0.17で動作確認):
# Usage: -s "replace_response_body.py <url_prefix> <file>"
from mitmproxy.models import decoded
def start(context, argv):
if len(argv) != 3:
raise ValueError('Usage: -s "replace_response_body.py <url_prefix> <file>"')
context.url_prefix, context.file = argv[1], argv[2]
def response(context, flow):
if flow.request.pretty_url.startswith(context.url_prefix):
with decoded(flow.response):
with open(context.file, "r") as file:
flow.response.content = file.read()
書換結果のファイルを準備:
// save as sample.js
alert('hello mitmproxy');
下は https://www.google-analytics.com/analytics.js
で始まるURLのHTTPSの応答bodyを sample.js
で書換えるサンプル:
$ mitmproxy-wrap -s "replace_response_body.py https://www.google-analytics.com/analytics.js sample.js"
iOS Simulatorを起動しSafariなどのブラウザで該当URLへのリクエストが発生すると、sample.jsが返却・実行されて下のダイアログが出る: