stuart attacking http2 implementations truefinal-jp

33
HTTP/2実装を攻撃 Stuart Larsen John Villamil Yahoo! ペンテスト チーム

Upload: pacsecjp

Post on 12-Feb-2017

196 views

Category:

Internet


0 download

TRANSCRIPT

Page 1: Stuart  attacking http2 implementations truefinal-jp

HTTP/2実装を攻撃

Stuart Larsen & John Villamil Yahoo! ペンテスト チーム

Page 2: Stuart  attacking http2 implementations truefinal-jp

本日の内容

▪  HTTP2とは ▪  なぜHTTP2は強い? ▪  http2fuzz ▪  ATS ▪  Firefox ▪  NodeJS ▪  まとめ

Page 3: Stuart  attacking http2 implementations truefinal-jp

Stuart Larsen ▪  https://c0nrad.io John Villamil ▪  @day6reak

自己紹介

Page 4: Stuart  attacking http2 implementations truefinal-jp

HTTP/1.1 は1999年に登場

その後に・・・ ▪  HTML と Java Script は進化した ▪  Webサイトは遥かに複雑になった ▪  ISPの回線速度は改善されてより広い帯域幅が提供されている ▪  Web上では遥かに多くのコンテンツが提供されている ▪  SSL は今ではより当たり前に使われている

Page 5: Stuart  attacking http2 implementations truefinal-jp

▪  “HTTP/2よこんにちは、さようならSPDY” http://blog.chromium.org/2015/02/hello-http2-goodbye-spdy-http-is_9.html

▪  HTTP/2 はSPDYおよびSPDY/2から進化したもの ▪  機能:

›  TCP使用の改善 ›  バイナリプロトコル

•  フレームとストリーム ›  マルチプレキ゚シング (ストリーム)

•  かねてから認識されていた遅延を緩和 ›  サーバからのプッシュ (PUSH_PROMISE) ›  データ圧縮 (HPACK) ›  フレーム ›  その他いろいろ

▪  大きな攻撃の可能性

HTTP/2 はパフォーマンスのため

Page 6: Stuart  attacking http2 implementations truefinal-jp

HTTP/1.1からのアップグレード

▪  http:// および https:// というURIのスキームを維持 ▪  TLS はオプションとしての位置づけ

›  Chrome と Firefox では必須としている ›  Internet Explorer と curlを含む他のクライアントはオプションのまま

▪  http:// のヘッダーをアップグレード ›  ラウンドトリップの原因になるが、HTTP/2 接続はより安定している

▪  マイナーバージョン番号は無し

HTTP/1.1 101 Switching Protocols Connection: Upgrade Upgrade: h2c

GET /index.html HTTP/1.1 Host: example.com Connection: Upgrade, HTTP2-Settings Upgrade: h2c HTTP2-Settings: <SETTINGS payload>

Page 7: Stuart  attacking http2 implementations truefinal-jp

HPACK

▪  HTTP はステートレス ›  リクエストのサイズ (cookies その他のヘッダー) は大きな影響を与える ›  圧縮は自然な解決策

▪  “Hpack was designed to make it difficult for a conforming implementation to leak information, to make encoding and decoding very fast/cheap, to provide for receiver control over compression context size, to allow for proxy re-indexing (i.e. shared state between frontend and backend within a proxy), and for quick comparisons of huffman-encoded strings.”

›  Roberto Peon, http://lists.w3.org/Archives/Public/ietf-http-wg//2014AprJun/1044.html

▪  レシーバが使用メモリサイズの最大値をコントロール ›  最少が0 で最大が 2^32 ›  SETTINGS フレームで指定

▪  SPDY は圧縮アルゴリズムを使用 ›  CRIME(Compression Ratio Info-leak Made Easy)攻撃に対して脆弱

Page 8: Stuart  attacking http2 implementations truefinal-jp

HPACK ▪  name:value のペアをインデックスに割り付け

›  双方のエンドポイントにおいてダイナミックテーブルを作成

▪  差分符号化 ›  スピードとサイズ圧縮に大きく寄与 ›  リファレンス・テーブルはヘッダーのためにつくられる

›  現在のヘッダーと直前のものの差分のみが符号化される

›  無駄を除去

▪  ハフマン符号化 ›  固定ハフマンテーブル ›  文字列リテラル

Page 9: Stuart  attacking http2 implementations truefinal-jp

HPACK 攻撃の可能性

▪  インデックス・テーブルのサイズとオフセット ▪  文字列リテラルの例

›  1つのビットがハフマン符号化されているかどうかを決定 ›  整数はサイズを示す ›  文字列データが続く ›  オクテットの境界まで積み重ねていく

▪  コンテキスト更新 ▪  ヘッダーテーブルのサイズ変更

›  デフォルトでは、動的テーブルのサイズは4k ▪  https://tools.ietf.org/html/rfc7541

Page 10: Stuart  attacking http2 implementations truefinal-jp

ATSで手始め

▪  Yahoo ペンテストチームはATS (Apache Traffic Server)を見ることに決定した

Http2ConnectionState.cc

Page 11: Stuart  attacking http2 implementations truefinal-jp

ATS 2 ▪  RFCより - http://tools.ietf.org/html/rfc7541#section-4.3

›  4.3. 動的テーブルサイズ変更時のエントリの削除 動的テーブルの最大サイズが減少するたびに、動的テーブルのサイズが最大サイズ以下になるまで動的テーブルの末尾からエントリが削除されます。

▪  予期しないパケットの順序のために、 headers テーブルが空の時にテーブルサイズを更新するバグが発生

Page 12: Stuart  attacking http2 implementations truefinal-jp

▪  HTTP/1.1はパイプライン化で複数のリクエストを送ることができる▪  ヘッドオブラインブロッキング

›  レスポンスは送信された順に行われなくてはならない

クライアント

サーバ

HTTP/1.1

クライアント

サーバ

HTTP/2

1 34 2

12 3 4

12 3 4

1 2 3 4

マルチプレキ゚シング

Page 13: Stuart  attacking http2 implementations truefinal-jp

フレーム

▪  通信の基本ユニット

Length (24 bits)

Type (8 bits) Flags (8 bits)

R Stream Identifier (31 bits)

Payload (0+ bits)

▪  フレームタイプ ›  Headers ›  Data ›  Priority ›  Reset ›  Settings ›  Push ›  Ping ›  Goaway ›  Update ›  Continuation

Page 14: Stuart  attacking http2 implementations truefinal-jp

サーバプッシュ

▪  リソースをクライアントにプッシュする新機能 ▪  例えば、もし、クライアントが index.html をWebサーバへリクエストしたら、Webサーバは「クライアントは恐らく logo.png も欲しがるだろう」と推測する

›  クライアントが logo.png を要求するのを待つ代わりに、サーバは先回りして logo.png をプッシュするので、ユーザはリクエスト全てを待つ必要が無い

Page 15: Stuart  attacking http2 implementations truefinal-jp

HTTP/2 の新しい攻撃の可能性

▪  HPACK▪  アップグレード・ダウングレード▪  つじつまの合わないマルチプレキ゚シング▪  不正なフォーマットのフレーム▪  クライアントに任意のデータをプッシュ▪  サーバに任意のデータをプッシュ▪  ストリーム依存▪  無効なフレームの記述

Page 16: Stuart  attacking http2 implementations truefinal-jp

ファジング

▪  ランダムなデータ(バイナリ・アスキー)をアプリケーションに送信して、予期せぬ動きをしないかをモニターする behavior

Page 17: Stuart  attacking http2 implementations truefinal-jp

HTTPをファジング

メソッド

ホスト

パス クエリー フラグメント

ヘッダー

ボディ

Page 18: Stuart  attacking http2 implementations truefinal-jp

http2fuzz ▪  最初に公開された http2 ファジングツール

▪  golangで開発されている ▪  クライアント・サーバ両方で使用可能

•  テストケースの最小化のためのリプレイモード

•  高度なコンカレント機能

Page 19: Stuart  attacking http2 implementations truefinal-jp

http2fuzz: クライアントモード

1. クライアントはWebサーバにhttp接続を確立 2. ALPN セクションでは h2 もしくは h2-14 を指定 3. 初期設定フレームはクライアント・サーバ間を往復する 4. ランダムに生成されたフレームがサーバに送信される 5. テスト対象のサーバがクラッシュしてもリスタートさせてテストを継続

Page 20: Stuart  attacking http2 implementations truefinal-jp

http2fuzz: サーバモード

1. サーバはローカルホストの証明書鍵をTLSようにロード 2. サーバはポートをバインドして接続を待つ 3. コネクションが確立されると、ランダムに生成されたフレームを、ブラウザが接続を終了するまで送信し続ける

▪  ブラウザのファジングに使うスクリプトの例:

›  setInterval(function() { $.get(‘https://localhost:8000’) }, 2000)

Page 21: Stuart  attacking http2 implementations truefinal-jp

▪  正常なフレームと、半分正常なものと、完全に異常なものを混ぜる

▪  各々のストラテジは異なったフレームを生成する

▪  ストラテジは組み合わせると「ミニ・ファジングツール」になる

ストラテジ http2fuzz

ファジング ツール

ファジング ツール

ファジング ツール

ストラテジ 1

ストラテジ 2

ストラテジ 3

ストラテジ 1

ストラテジ 3

ストラテジ 4

ストラテジ 2

ストラテジ 3

ストラテジ 4

Page 22: Stuart  attacking http2 implementations truefinal-jp

ストラテジ

SettingsFuzzer: ▪  0から5の間のランダムな値を選ぶ ▪  ランダムな値で構成された多くのランダムな設定をSettingsFrameに付け加える

HeaderFuzzer: ▪  0から5の間のランダムな値を選ぶ ▪  ランダムな値で構成された多くのランダムなHTTPヘッダーを

HeadersFrameに付け加える

Page 23: Stuart  attacking http2 implementations truefinal-jp

ストラテジ PriorityFuzzer: ▪  PriorityフレームにランダムなstreamDependencysteamId、weight、および、 exclusive valueを設定して送信する

PingFuzzer: ▪  pingフレームにランダムな8 バイトペイロードを設定して送信する

ResetFuzzer: ▪  RSTフレームにランダムな streamIdとerrorCodeを設定して送信する

Page 24: Stuart  attacking http2 implementations truefinal-jp

ストラテジ WindowUpdateFuzzer: ▪  Window Update Frameにランダムな streamId とincr valueを設定して送信する

RawFrameFuzzer: ▪  ランダムなframeType (0-12)、randomFlags (0-256)、

streamId(2**31)、および、 0から10000までの長さのランダムなバイ配列を生成

▪  上記によって構成された異常なフレームを送信

Page 25: Stuart  attacking http2 implementations truefinal-jp

ストラテジ

DataFuzzer: ▪  Data Frameにランダムな streamIdとendStream bool、そして、0から10000バイトのランダムな長さのペイロードを設定して送信

PushPromiseFuzzer: ▪  PushPromise Frameに0から10000バイトのランダムな長さのペイロード、streamId、promiseId、endHeaders bool、およびpadLengnth (0-256)を設定して送信

Page 26: Stuart  attacking http2 implementations truefinal-jp

ストラテジ

ContinuationFuzzer: ▪  Continuation Frameにランダムな streamIdとendStream bool、そして、

0から10000バイトのランダムな長さのペイロードを設定して送信 RawTCPFuzzer: ▪  TLS接続を確立して完全なガーベージを送信。ぺイロードは0から

10000バイトのランダムな長さの配列。

Page 27: Stuart  attacking http2 implementations truefinal-jp

リプレイモード

▪  ファジングツールがクラッシュを検出したら原因を突き止めなくてはならない

▪  ファジングに使われた各々のペイロードはreplay.jsonに保存される ▪  クラッシュするとファジングツールは停止してファイルも閉じられる ▪  ./http2fuzzを実行 –リプレイはフレームを同じ順序でサーバに送信 ▪  そのため、いくつかのフレームを削除してそれでもなおサーバがクラッシュするかどうかを確かめたり、必要なフレームを見つけ出すまでフレームのセットを絞り込んだりすることができる。

Page 28: Stuart  attacking http2 implementations truefinal-jp

FireFoxにおける不正なHTTP2ヘッダーフレームによるDoS

▪  不正なhttp2ヘッダーフレームがブラウザに送られる ▪  通常は、ヘッダーフレームはpad length、steam dependency

identifier、weight、header block fragmentそしてpaddingによって構成される

▪  しかし、たったの1バイトのみが送信される ▪  これによって整数値のアンダーフローが発生し、結果として

nsCStringが約2^32バイトのメモリ割り当てを試みることになる

Page 29: Stuart  attacking http2 implementations truefinal-jp

FireFoxにおける不正なHTTP2ヘッダーフレームによるDoS

Http2Session.cppの1226行目において、圧縮から復元されたフレームを圧縮から復元されたフレームバッファに追加するコールが行われる:

Page 30: Stuart  attacking http2 implementations truefinal-jp

FireFoxにおける不正なPushPromiseアンダーフローによるDoS Http2Session.cppの1634行目において、圧縮から復元されたフレームを圧縮から復元されたフレームバッファに追加するコールが行われる:

= 4294967292

Page 31: Stuart  attacking http2 implementations truefinal-jp

node-http2

▪  バグは見つかったが、状態を確定させるのが難しい

›  どのフレームをいつ送るのか

▪  全てのフィールドを検証する必要がある ›  値と大きさ

Page 32: Stuart  attacking http2 implementations truefinal-jp

まとめ

▪  HTTP2とは ▪  なぜHTTP2は強い? ▪  http2fuzz ▪  ATS ▪  Firefox ▪  NodeJS

Page 33: Stuart  attacking http2 implementations truefinal-jp

終わり

質問?