Burpの透過プロキシサポートにより、プロキシ非対応クライアントが直接Proxyリスナーに接続できるようになります。対象アプリケーションが、ブラウザ外で動作するシッククライアントコンポーネントを採用している場合や、ブラウザのフレームワーク外で独自のHTTPリクエストを行うブラウザプラグインの場合に便利です。多くの場合これらのクライアントは、HTTPプロキシをサポートしていない、または使用するための簡単な設定方法を提供していません。
プロキシ非対応のクライアントを強制的にBurpに接続させられます。関連するホスト名のDNS名前解決を変更し、アプリケーションが使用するポートで透過プロキシを設定しておきます。
たとえば、アプリケーションがexample.org
ドメインを使い、HTTPとHTTPSを標準ポートで使っている場合、ローカルマシン宛てにリダイレクトするようhostsファイルにエントリを追加します:
127.0.0.1 example.org
リダイレクトされたリクエストを受信するには、透過Burp Proxyリスナーを127.0.0.1:80
と127.0.0.1:443
に作成します。プロキシ非対応クライアントは、ドメイン名をローカルIPアドレスに名前解決し、そのインタフェースに直接リクエストを送信します。
DNSを使ってクライアントリクエストをローカルリスナーにリダイレクトするのは簡単ですが、そのリクエストはHTTPプロキシが期待する形式のリクエストではないため、特別な透過プロキシモードが必要になります。
普通のHTTPを使う場合、プロキシスタイルのリクエストは次のようになります:
GET http://example.org/foo.php HTTP/1.1 Host: example.org
非プロキシスタイルのリクエストは次のようになります:
GET /foo.php HTTP/1.1 Host: example.org
Webプロキシは通常、リクエストの最初の行にある完全なURLを使用して、宛先ホストを決定します。宛先の決定にHostヘッダは使いません。透過プロキシを有効にすると、Burpは非プロキシスタイルのリクエストを受信した場合に、Hostヘッダの内容を解析します。そしてリクエストの宛先としてHostヘッダを使用します。
プロキシでHTTPSを使用するとき、クライアントは宛先ホストを特定するCONNECTリクエストを送信し、TLSネゴシエーションを実行します。しかしプロキシ非対応クライアントは、宛先ホストと直接通信していると思い込み、いきなりTLSネゴシエーションを実行します。透過プロキシが有効な場合、Burpはクライアントと直接TLSネゴシエーションを行い、復号したリクエストからHostヘッダを解析します。
透過モードの場合、Burpはそれぞれのリクエストから解析されたHostヘッダのホスト宛にリクエストを転送します。しかし、関連するドメインはhostsファイルで変更しているため、Burpもそのホスト名をローカルリスナーに名前解決してしまいます。別の方法で設定しない限りリクエストが自分自身に転送されます。これは無限ループになってしまいます。
この問題を解決するためには 2 つの方法があります:
関連して、プロキシ非対応クライアントのリクエストにHostヘッダが含まれていない場合に問題が発生します。このヘッダがなく非プロキシスタイルのリクエストを処理すると、リクエストを転送する宛先ホストを判断できません。
この問題を解決するためには 2 つの方法があります。すべてのリクエストを同じ宛先ホストに転送する場合は、Proxyリスナーのリダイレクトオプションを使って、正しいIPアドレスにトラフィックが行くよう強制させられます。
異なるリクエストを異なるホストに転送する場合は、複数のProxyリスナーを使う必要があります:
Burpリスナーが使用するサーバTLS証明書には、さまざまな設定があります。デフォルトの設定では、宛先ホストごとに証明書を自動生成します。透過プロキシではこれがうまくいかない場合があります。プロキシ非対応クライアントは、宛先ホストを特定するためのCONNECTリクエストヘッダを付けずに、リスナーと直接TLSネゴシエーションをします。
ブラウザを含む多くのクライアントはClient Helloメッセージの"server_name"拡張をサポートしています。これで、クライアントがネゴシエートしようとしている宛先ホストを特定できます。この拡張が存在している場合、Burpは通常通りそのホスト名を証明書の生成に使用します。その拡張がない場合は、Burpはフェイルオーバーとして静的な自己署名証明書を使用します。
この問題を解決するためには 2 つの方法があります: