Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Stuart attacking http2 implementations truefinal-jp

PacSec2015 slides

  • Login to see the comments

  • Be the first to like this

Stuart attacking http2 implementations truefinal-jp

  1. 1. HTTP/2実装を攻撃 Stuart Larsen & John Villamil Yahoo! ペンテスト チーム
  2. 2. 本日の内容 ▪  HTTP2とは ▪  なぜHTTP2は強い? ▪  http2fuzz ▪  ATS ▪  Firefox ▪  NodeJS ▪  まとめ
  3. 3. Stuart Larsen ▪  https://c0nrad.io John Villamil ▪  @day6reak 自己紹介
  4. 4. HTTP/1.1 は1999年に登場 その後に・・・ ▪  HTML と Java Script は進化した ▪  Webサイトは遥かに複雑になった ▪  ISPの回線速度は改善されてより広い帯域幅が提供されている ▪  Web上では遥かに多くのコンテンツが提供されている ▪  SSL は今ではより当たり前に使われている
  5. 5. ▪  “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 はパフォーマンスのため
  6. 6. 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>
  7. 7. 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)攻撃に対して脆弱
  8. 8. HPACK ▪  name:value のペアをインデックスに 割り付け ›  双方のエンドポイントにおいてダイナミッ クテーブルを作成 ▪  差分符号化 ›  スピードとサイズ圧縮に大きく寄与 ›  リファレンス・テーブルはヘッダーのため につくられる ›  現在のヘッダーと直前のものの差分のみが 符号化される ›  無駄を除去 ▪  ハフマン符号化 ›  固定ハフマンテーブル ›  文字列リテラル
  9. 9. HPACK 攻撃の可能性 ▪  インデックス・テーブルのサイズとオフセット ▪  文字列リテラルの例 ›  1つのビットがハフマン符号化されているかどうかを決定 ›  整数はサイズを示す ›  文字列データが続く ›  オクテットの境界まで積み重ねていく ▪  コンテキスト更新 ▪  ヘッダーテーブルのサイズ変更 ›  デフォルトでは、動的テーブルのサイズは4k ▪  https://tools.ietf.org/html/rfc7541
  10. 10. ATSで手始め ▪  Yahoo ペンテストチームはATS (Apache Traffic Server)を見ることに 決定した Http2ConnectionState.cc
  11. 11. ATS 2 ▪  RFCより - http://tools.ietf.org/html/rfc7541#section-4.3 ›  4.3. 動的テーブルサイズ変更時のエントリの削除 動的テーブルの最大サイズが減少するたびに、動的テーブルのサイズが最大サイズ以下になるまで動的テーブルの末尾 からエントリが削除されます。 ▪  予期しないパケットの順序のために、 headers テーブルが空の時に テーブルサイズを更新するバグが発生
  12. 12. ▪  HTTP/1.1 はパイプライン化で複数のリクエストを送ることができる ▪  ヘッドオブラインブロッキング ›  レスポンスは送信された順に行われなくてはならない クライ アント サーバ HTTP/1.1 クライ アント サーバ HTTP/2 1 3 4 2 1 2 3 4 1 2 3 4 1 2 3 4 マルチプレキ゚シング
  13. 13. フレーム ▪  通信の基本ユニット 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
  14. 14. サーバプッシュ ▪  リソースをクライアントにプッシュする新機能 ▪  例えば、もし、クライアントが index.html をWebサーバへリクエス トしたら、Webサーバは「クライアントは恐らく logo.png も欲しが るだろう」と推測する ›  クライアントが logo.png を要求するのを待つ代わりに、サーバは先回りして logo.png をプッシュするので、ユーザはリクエスト全てを待つ必要が無い
  15. 15. HTTP/2 の新しい攻撃の可能性 ▪  HPACK ▪  アップグレード・ダウングレード ▪  つじつまの合わないマルチプレキ゚シング ▪  不正なフォーマットのフレーム ▪  クライアントに任意のデータをプッシュ ▪  サーバに任意のデータをプッシュ ▪  ストリーム依存 ▪  無効なフレームの記述
  16. 16. ファジング ▪  ランダムなデータ(バイナリ・アスキー)をアプリケーションに送信 して、予期せぬ動きをしないかをモニターする behavior
  17. 17. HTTPをファジング メソッド ホスト パス クエリー フラグメント ヘッダー ボディ
  18. 18. http2fuzz ▪  最初に公開された http2 ファ ジングツール ▪  golangで開発されている ▪  クライアント・サーバ両方で 使用可能 •  テストケースの最小化のための リプレイモード •  高度なコンカレント機能
  19. 19. http2fuzz: クライアントモード 1. クライアントはWebサーバにhttp接続を確立 2. ALPN セクションでは h2 もしくは h2-14 を指定 3. 初期設定フレームはクライアント・サーバ間を往復する 4. ランダムに生成されたフレームがサーバに送信される 5. テスト対象のサーバがクラッシュしてもリスタートさせてテストを 継続
  20. 20. http2fuzz: サーバモード 1. サーバはローカルホストの証明書 をTLSようにロード 2. サーバはポートをバインドして接続を待つ 3. コネクションが確立されると、ランダムに生成されたフレームを、ブ ラウザが接続を終了するまで送信し続ける ▪  ブラウザのファジングに使うスクリプトの例: ›  setInterval(function() { $.get(‘https://localhost:8000’) }, 2000)
  21. 21. ▪  正常なフレームと、半分正常 なものと、完全に異常なもの を混ぜる ▪  各々のストラテジは異なった フレームを生成する ▪  ストラテジは組み合わせると 「ミニ・ファジングツール」 になる ストラテジ http2fuzz ファジング ツール ファジング ツール ファジング ツール ストラテジ 1 ストラテジ 2 ストラテジ 3 ストラテジ 1 ストラテジ 3 ストラテジ 4 ストラテジ 2 ストラテジ 3 ストラテジ 4
  22. 22. ストラテジ SettingsFuzzer: ▪  0から5の間のランダムな値を選ぶ ▪  ランダムな値で構成された多くのランダムな設定をSettingsFrameに 付け加える HeaderFuzzer: ▪  0から5の間のランダムな値を選ぶ ▪  ランダムな値で構成された多くのランダムなHTTPヘッダーを HeadersFrameに付け加える
  23. 23. ストラテジ PriorityFuzzer: ▪  PriorityフレームにランダムなstreamDependencysteamId、weight、 および、 exclusive valueを設定して送信する PingFuzzer: ▪  pingフレームにランダムな8 バイトペイロードを設定して送信する ResetFuzzer: ▪  RSTフレームにランダムな streamIdとerrorCodeを設定して送信する
  24. 24. ストラテジ WindowUpdateFuzzer: ▪  Window Update Frameにランダムな streamId とincr valueを設定して 送信する RawFrameFuzzer: ▪  ランダムなframeType (0-12)、randomFlags (0-256)、 streamId(2**31)、および、 0から10000までの長さのランダムなバイ 配列を生成 ▪  上記によって構成された異常なフレームを送信
  25. 25. ストラテジ DataFuzzer: ▪  Data Frameにランダムな streamIdとendStream bool、そして、0か ら10000バイトのランダムな長さのペイロードを設定して送信 PushPromiseFuzzer: ▪  PushPromise Frameに0から10000バイトのランダムな長さのペイロ ード、streamId、promiseId、endHeaders bool、およびpadLengnth (0-256)を設定して送信
  26. 26. ストラテジ ContinuationFuzzer: ▪  Continuation Frameにランダムな streamIdとendStream bool、そして、 0から10000バイトのランダムな長さのペイロードを設定して送信 RawTCPFuzzer: ▪  TLS接続を確立して完全なガーベージを送信。ぺイロードは0から 10000バイトのランダムな長さの配列。
  27. 27. リプレイモード ▪  ファジングツールがクラッシュを検出したら原因を突き止めなくては ならない ▪  ファジングに使われた各々のペイロードはreplay.jsonに保存される ▪  クラッシュするとファジングツールは停止してファイルも閉じられる ▪  ./http2fuzzを実行 –リプレイはフレームを同じ順序でサーバに送信 ▪  そのため、いくつかのフレームを削除してそれでもなおサーバがクラ ッシュするかどうかを確かめたり、必要なフレームを見つけ出すまで フレームのセットを絞り込んだりすることができる。
  28. 28. FireFoxにおける不正なHTTP2ヘッダーフレームによるDoS ▪  不正なhttp2ヘッダーフレームがブラウザに送られる ▪  通常は、ヘッダーフレームはpad length、steam dependency identifier、weight、header block fragmentそしてpaddingによって構 成される ▪  しかし、たったの1バイトのみが送信される ▪  これによって整数値のアンダーフローが発生し、結果として nsCStringが約2^32バイトのメモリ割り当てを試みることになる
  29. 29. FireFoxにおける不正なHTTP2ヘッダーフレームによるDoS Http2Session.cppの1226行目において、圧縮から復元されたフレームを 圧縮から復元されたフレームバッファに追加するコールが行われる:
  30. 30. FireFoxにおける不正なPushPromiseアンダーフローによる DoS Http2Session.cppの1634行目において、圧縮から復元されたフレームを 圧縮から復元されたフレームバッファに追加するコールが行われる: = 4294967292
  31. 31. node-http2 ▪  バグは見つかったが、状態を確定させるのが難しい ›  どのフレームをいつ送るのか ▪  全てのフィールドを検証する必要がある ›  値と大きさ
  32. 32. まとめ ▪  HTTP2とは ▪  なぜHTTP2は強い? ▪  http2fuzz ▪  ATS ▪  Firefox ▪  NodeJS
  33. 33. 終わり 質問?

×