ZhgChg.Li

HTTPS通信でもデータ漏洩|iOS・MacOSでのmitmproxy中間者攻撃対策

iOSとMacOSユーザー向けに、mitmproxyによる中間者攻撃でAPI通信が盗聴される問題を解説。HTTPS利用時の盲点を明確化し、効果的な防御策でデータ保護を強化します。

HTTPS通信でもデータ漏洩|iOS・MacOSでのmitmproxy中間者攻撃対策
本記事は AI による翻訳です。お気づきの点があればお知らせください。

APPはHTTPSで通信しているが、それでもデータが盗まれた。

iOS+MacOSでmitmproxyを使った中間者攻撃(Man-in-the-middle attack)によるAPI通信データの傍受方法と防御策の解説

はじめに

先日、会社で内部のCTF競技会を開催しました。問題を考える際に、大学時代にPHPでバックエンドを担当していたプロジェクトを思い出しました。あるポイント集めのアプリで、タスクリストがあり、条件を達成するとAPIを呼び出してポイントを取得する仕組みです。上司は「API呼び出しはHTTPSで暗号化されているから安全だ」と考えていましたが、私が中間者攻撃を実演し、通信データを直接盗聴してAPI呼び出しを偽造しポイントを取得できることを示しました…。

さらに近年のビッグデータの台頭により、ウェブクローラーが飛び交い、クローラー攻防戦はますます激化しています。 クローラー対策のさまざまな工夫 を見ると、まさに「技術が一歩進めば、対策も一歩進む」という状況です。

スクレイピングのもう一つのターゲットはAPPのAPIです。防御がなければほぼ門戸が開いた状態で、操作も簡単でフォーマットも整っており、識別やブロックされにくいです。したがって、ウェブ側であらゆる対策をしてもデータが繰り返しスクレイピングされる場合は、APPのAPIに脆弱性がないか確認してみるとよいでしょう。

このテーマはCTF大会でどのように出題すればよいかわからなかったため、記録として記事を単独でまとめました。本記事はあくまで概念を簡単に紹介するものです — HTTPSは証明書の差し替えにより通信内容を復号可能、およびセキュリティ強化の方法について。実際のネットワーク理論は得意分野ではなく先生にお任せしているため、すでにこの分野に詳しい方は時間をかけて読む必要はありません。もしくは記事の最後までスクロールしてAPPの保護方法をご覧ください!

実際の操作

環境: MacOS + iOS

Androidユーザーは直接Packet Capture(無料)をダウンロードできます。iOSユーザーはSurge 4有料)でMITM機能をアンロックできます。MacOSでは別の有料ソフトCharlesも利用可能です。

本記事ではiOSで無料のmitmproxyを使った操作方法を解説します。もし上記の環境があれば、わざわざ面倒なことをせず、直接スマホのAPPでVPNを起動し、証明書を差し替えるだけで中間者攻撃が可能です!(同様に、一番下までスクロールして保護方法もご確認ください!)

[2021/02/25 更新]: Macには新しい無料のグラフィカルインターフェースツール(Proxyman)があり、こちらの記事の第一部と組み合わせて使えます。

mitmproxy のインストール

brew を使った直接インストール

brew install mitmproxy

インストール完了!

p.s brew: command not found が表示された場合は、まず brew パッケージ管理ツールをインストールしてください

/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

(コード内のコメントはありませんので、翻訳は不要です)

mitmproxy の使用方法

インストールが完了したら、Terminalで以下のコマンドを入力して起動します:

mitmproxy

起動成功

起動成功

携帯電話とMacを同じローカルネットワークに接続し、MacのIPアドレスを取得する

方法(1) MacをWiFiに接続し、スマホも同じWiFiを使用する
MacのIPアドレス = 「システム環境設定」->「ネットワーク」->「Wi-Fi」->「IPアドレス」

方法(2) Macで有線ネットワークを使用し、インターネット共有を有効にする;スマホをそのホットスポットに接続する:

「システム環境設定」-> 「共有」->「イーサネット」を選択->「Wi-Fi」にチェック-> 「インターネット共有」を有効化

「システム環境設定」-> 「共有」->「イーサネット」を選択->「Wi-Fi」にチェック-> 「インターネット共有」を有効化

MacのIPアドレス = 192.168.2.1 (️️注意⚠️ イーサネットのIPではなく、Macがネットワーク共有ホットスポットとして使うIPです)

携帯ネットワーク設定WiFi — プロキシサーバー情報

「設定」-> 「WiFi」-> 「HTTP プロキシサーバー」-> 「手動」-> 「サーバーに **MacのIPアドレス** を入力」-> 「ポートに **8080** を入力」-> 「保存」

「設定」-> 「WiFi」-> 「HTTPプロキシ」-> 「手動」-> 「サーバーにMacのIPアドレスを入力」-> 「ポートに8080を入力」-> 「保存」

この時点でウェブページが開けず、証明書エラーが出るのは正常です;続けて進めましょう…

mitmproxy カスタム HTTPS 証明書のインストール

上述のように、中間者攻撃の実現方法は通信中に自分の証明書を使ってデータの暗号化・復号を差し替えることです。そのため、スマートフォンにもこのカスタム証明書をインストールする必要があります。

1.携帯のSafariで http://mitm.it を開く

左側に表示されるとProxy設定✅ / 右側に表示されるとProxy設定に誤りがあります🚫

左側に「->Proxy設定✅」が表示される場合は正しく設定されています。
右側に表示される場合はProxy設定に誤りがあります🚫。

「Apple」->「プロファイルをインストール」->「インストール」

「Apple」->「プロファイルをインストール」->「インストール」

⚠️ここで終わりではありません。次にプロファイルの有効化について説明します

「一般」->「情報」->「証明書信頼設定」->「mitmproxy」有効化

「一般」->「情報」->「証明書信頼設定」->「mitmproxy」を有効化

完了!これでブラウザに戻ると正常にウェブページを閲覧できます。

Macに戻ってmitmproxyを操作する

mitmproxyのターミナルでスマホのデータ通信記録を確認できます

mitmproxyのターミナル上で、先ほどのスマホのデータ通信記録を確認できます。

嗅ぎたい記録を見つけてRequest(送信したパラメータ)/Response(返された内容)を確認する

嗅探したい記録を見つけて、Request(送信されたパラメータ)やResponse(返された内容)を確認します。

よく使う操作キーセット:

「 ? 」= キー操作一覧を表示
「 k 」/「⬆」= 上へ
「 j 」/「⬇」= 下へ
「 h 」/「⬅」= 左へ
「 l 」/「➡️」= 右へ
「 space 」= 次のページへ
「 enter 」= 詳細を表示
「 q 」= 前のページに戻る/終了
「 b 」= レスポンスボディを指定パスのテキストファイルにエクスポート
「 f 」= 記録のフィルター条件
「 z 」= すべての記録をクリア
「 e 」= リクエスト編集(cookie、headers、params...)
「 r 」= リクエストを再送信

CLIに慣れていない?大丈夫、Web GUIに切り替えられます!

mitmproxy の起動方法以外に、以下のように変更できます:

mitmweb

新しい Web GUI を使って操作を観察できます

mitmweb

mitmweb

メインイベント、APPデータのスニッフィング:

上述の環境がすべて整い、操作に慣れたら、いよいよ本題に入ります;APPのAPIデータ通信内容をスニッフィングしましょう!

これはある不動産アプリを例にしており、悪意はなく純粋な学術交流のための使用です!

オブジェクトリストのAPIがどのようにリクエストされ、どのような内容を返すのか知りたいです!

まず「z」を押してすべての記録をクリアします(混乱を避けるため)

まず「z」を押してすべての記録をクリアします(混乱を避けるため)。

ターゲットAPPを開く

ターゲットアプリを起動する

ターゲットのAPPを開き、「プルダウンリフレッシュ」や「次のページを読み込む」操作を試してください。

🛑ターゲットのAPPが起動しない、または接続できない場合;申し訳ありませんが、そのAPPには対策が施されており、この方法での解析はできません。直接「保護方法」の章までスクロールしてください🛑

mitmproxy 記録

mitmproxyの記録

mitmproxyに戻って記録を確認し、探偵のような精神でどのAPIリクエストが欲しいものか推測して詳細を確認しましょう!

Request

リクエスト

Request 部分でどのパラメータが送信されたか確認できます。

「e」で編集し、「r」で再送信して、レスポンスを確認すれば各パラメータの用途が推測できます!

Response

Response

Response も直接元の返却内容を取得できます。

🛑もしResponseの内容が大量にエンコードされている場合;申し訳ありませんが、APPが独自に再度暗号化・復号している可能性があり、この方法での解析はできません。直接「保護方法」の章までスクロールしてください🛑

読みづらい?文字化けしている?大丈夫です。ここで「b」を使ってテキストファイルとしてデスクトップに書き出し、その内容を Json Editor Online にコピーして解析してください!

**または直接 mitmweb を使って Web GUI で直接閲覧・操作*

mitmweb

mitmweb

嗅探、観察、フィルタリング、テストを行うことで、APPのAPIの動作方法が分かり、それを利用してクローラーでデータを取得できます。

必要な情報を収集し終えたら、mitmproxyを終了し、スマホのネットワークのプロキシ設定を自動に戻してから正常にインターネットを利用してください。

APP はどうやって自衛すべきか?

mitmproxyを設定した後にAPPが使えなくなったり、返される内容がエンコードされている場合は、APPが保護を施していることを示しています。

方法(1):

大まかに言うと、証明書情報をAPP内に入れておき、現在のHTTPSで使用されている証明書がAPP内の情報と一致しなければアクセスを拒否します。詳しくはこちらSSL Pinningの関連資料をご覧ください。欠点は証明書の有効期限に注意が必要なことです。

<https://medium.com/@dzungnguyen.hcm/ios-ssl-pinning-bffd2ee9efc>

https://medium.com/@dzungnguyen.hcm/ios-ssl-pinning-bffd2ee9efc

方法(2):

APP側はデータを送信する前にまずエンコードと暗号化を行い、APIのバックエンドは受信後に復号して元のリクエスト内容を取得します。APIの返却内容も同様にエンコードと暗号化が行われ、APP側は受信後に復号して返却内容を取得します。手順は面倒でパフォーマンスも消費しますが、確かに有効な方法です。私の知る限り、あるデジタル銀行がこの方法で保護を行っています。

しかし….

方法1には依然として回避方法があります:iOS 12でSSL Pinningをバイパスする方法

方法2、リバースエンジニアリングを通じて暗号化に使用されるキーを取得することも可能です

⚠️100%の安全はありません⚠️

あるいは穴を掘って這わせて、様々な証拠を集めてから法務に任せる(?

やはり同じ言葉:

「クライアントを決して信用しない」

mitmproxy のさらなる活用方法:

1.mitmdumpの使用方法

mitmproxymitmweb に加えて、mitmdump はすべての記録を直接テキストファイルにエクスポートできます。

mitmdump -w /log.txt

(この部分はコマンドなので翻訳不要です)

そして、玩法(2) のPythonプログラムを使って、トラフィックの設定やフィルタリングが可能です:

mitmdump -ns examples/filter.py -r /log.txt -w /result.txt

(コードコメントがないため翻訳不要)

2.pythonプログラムを使ったリクエストパラメータ設定、アクセス制御、リダイレクト:

from mitmproxy import http

def request(flow: http.HTTPFlow) -> None:
    # pretty_hostはリクエストの「Host」ヘッダーを考慮します。
    # これは通常IPしかない透過モードで便利です。
    
    # リクエストパラメータ設定例:
    flow.request.headers['User-Agent'] = 'MitmProxy'
    
    if flow.request.pretty_host == "123.com.tw":
        flow.request.host = "456.com.tw"
    # 123.com.twへのアクセスをすべて456.com.twにリダイレクト

転送の例

mitmproxyを起動するときにパラメータを付ける:

mitmproxy -s /redirect.py
or
mitmweb -s /redirect.py
or
mitmdump -s /redirect.py

(コード部分は翻訳不要のためそのままです)

穴埋め

mitmproxy を使って HTTP 1.1 および Accept-Ranges: bytes、Content-Range の長い接続で断片的にリソースを継続取得するリクエストを観察する場合、レスポンスがすべて返ってくるまで表示されず、分割表示や持続接続での継続ダウンロードは表示されません。

ここでハマった

関連記事

あとがき

ドメイン権限がないためSSL証明書情報を取得できず、実装はできませんでした。コードを見る限り難しくはなさそうです。100%安全な方法はありませんが、一つ防御を追加するだけでもかなり安全になります。さらに攻撃を続けるには多くの時間が必要なので、90%のスクレイピングは防げると思います!

この記事は少し内容が薄いかもしれません。mediumはしばらく放置していました(ミラーレス一眼をいじっていたため)。主に今週末(2019/09/21–2019/09/22)のiPlayground 2019に向けて、事前に書き慣らしをしています。今年のプログラムを楽しみにしています🤩。戻ってきたら、もっと質の高い記事をたくさん書けるようにしたいです!

[2019/02/22 更新記事] iPlayground 2019 はどんな体験?

Post は Medium から ZMediumToMarkdown によって変換されました。

GitHub で編集
この記事を改善
本記事は Medium で初公開
オリジナルを読む
この記事をシェア
リンクをコピー · SNS でシェア
ZhgChgLi
著者

ZhgChgLi

An iOS, web, and automation developer from Taiwan 🇹🇼 who also loves sharing, traveling, and writing.

コメント