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

2実装を攻撃 - PacSec › psj15 › PSJ2015_Stuart_Attacking-HTTP2-Impleme… · HTTP2とは なぜHTTP2は強い? http2fuzz ATS Firefox NodeJS まとめ. Stuart Larsen John

Jun 29, 2020

Download

Documents

dariahiddleston
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: 2実装を攻撃 - PacSec › psj15 › PSJ2015_Stuart_Attacking-HTTP2-Impleme… · HTTP2とは なぜHTTP2は強い? http2fuzz ATS Firefox NodeJS まとめ. Stuart Larsen John

HTTP/2実装を攻撃

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

Page 2: 2実装を攻撃 - PacSec › psj15 › PSJ2015_Stuart_Attacking-HTTP2-Impleme… · HTTP2とは なぜHTTP2は強い? http2fuzz ATS Firefox NodeJS まとめ. Stuart Larsen John

本日の内容

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

Page 3: 2実装を攻撃 - PacSec › psj15 › PSJ2015_Stuart_Attacking-HTTP2-Impleme… · HTTP2とは なぜHTTP2は強い? http2fuzz ATS Firefox NodeJS まとめ. Stuart Larsen John

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

自己紹介

Page 4: 2実装を攻撃 - PacSec › psj15 › PSJ2015_Stuart_Attacking-HTTP2-Impleme… · HTTP2とは なぜHTTP2は強い? http2fuzz ATS Firefox NodeJS まとめ. Stuart Larsen John

HTTP/1.1 は1999年に登場

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

Page 5: 2実装を攻撃 - PacSec › psj15 › PSJ2015_Stuart_Attacking-HTTP2-Impleme… · HTTP2とは なぜHTTP2は強い? http2fuzz ATS Firefox NodeJS まとめ. Stuart Larsen John

▪  “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: 2実装を攻撃 - PacSec › psj15 › PSJ2015_Stuart_Attacking-HTTP2-Impleme… · HTTP2とは なぜHTTP2は強い? http2fuzz ATS Firefox NodeJS まとめ. Stuart Larsen John

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: 2実装を攻撃 - PacSec › psj15 › PSJ2015_Stuart_Attacking-HTTP2-Impleme… · HTTP2とは なぜHTTP2は強い? http2fuzz ATS Firefox NodeJS まとめ. Stuart Larsen John

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: 2実装を攻撃 - PacSec › psj15 › PSJ2015_Stuart_Attacking-HTTP2-Impleme… · HTTP2とは なぜHTTP2は強い? http2fuzz ATS Firefox NodeJS まとめ. Stuart Larsen John

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

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

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

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

›  無駄を除去

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

Page 9: 2実装を攻撃 - PacSec › psj15 › PSJ2015_Stuart_Attacking-HTTP2-Impleme… · HTTP2とは なぜHTTP2は強い? http2fuzz ATS Firefox NodeJS まとめ. Stuart Larsen John

HPACK 攻撃の可能性

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

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

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

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

Page 10: 2実装を攻撃 - PacSec › psj15 › PSJ2015_Stuart_Attacking-HTTP2-Impleme… · HTTP2とは なぜHTTP2は強い? http2fuzz ATS Firefox NodeJS まとめ. Stuart Larsen John

ATSで手始め

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

Http2ConnectionState.cc

Page 11: 2実装を攻撃 - PacSec › psj15 › PSJ2015_Stuart_Attacking-HTTP2-Impleme… · HTTP2とは なぜHTTP2は強い? http2fuzz ATS Firefox NodeJS まとめ. Stuart Larsen John

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

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

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

Page 12: 2実装を攻撃 - PacSec › psj15 › PSJ2015_Stuart_Attacking-HTTP2-Impleme… · HTTP2とは なぜHTTP2は強い? http2fuzz ATS Firefox NodeJS まとめ. Stuart Larsen John

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

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

クライアント

サーバ

HTTP/1.1

クライアント

サーバ

HTTP/2

1 34 2

12 3 4

12 3 4

1 2 3 4

マルチプレキ゚シング

Page 13: 2実装を攻撃 - PacSec › psj15 › PSJ2015_Stuart_Attacking-HTTP2-Impleme… · HTTP2とは なぜHTTP2は強い? http2fuzz ATS Firefox NodeJS まとめ. Stuart Larsen John

フレーム

▪  通信の基本ユニット

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: 2実装を攻撃 - PacSec › psj15 › PSJ2015_Stuart_Attacking-HTTP2-Impleme… · HTTP2とは なぜHTTP2は強い? http2fuzz ATS Firefox NodeJS まとめ. Stuart Larsen John

サーバプッシュ

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

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

Page 15: 2実装を攻撃 - PacSec › psj15 › PSJ2015_Stuart_Attacking-HTTP2-Impleme… · HTTP2とは なぜHTTP2は強い? http2fuzz ATS Firefox NodeJS まとめ. Stuart Larsen John

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

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

Page 16: 2実装を攻撃 - PacSec › psj15 › PSJ2015_Stuart_Attacking-HTTP2-Impleme… · HTTP2とは なぜHTTP2は強い? http2fuzz ATS Firefox NodeJS まとめ. Stuart Larsen John

ファジング

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

Page 17: 2実装を攻撃 - PacSec › psj15 › PSJ2015_Stuart_Attacking-HTTP2-Impleme… · HTTP2とは なぜHTTP2は強い? http2fuzz ATS Firefox NodeJS まとめ. Stuart Larsen John

HTTPをファジング

メソッド

ホスト

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

ヘッダー

ボディ

Page 18: 2実装を攻撃 - PacSec › psj15 › PSJ2015_Stuart_Attacking-HTTP2-Impleme… · HTTP2とは なぜHTTP2は強い? http2fuzz ATS Firefox NodeJS まとめ. Stuart Larsen John

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

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

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

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

Page 19: 2実装を攻撃 - PacSec › psj15 › PSJ2015_Stuart_Attacking-HTTP2-Impleme… · HTTP2とは なぜHTTP2は強い? http2fuzz ATS Firefox NodeJS まとめ. Stuart Larsen John

http2fuzz: クライアントモード

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

Page 20: 2実装を攻撃 - PacSec › psj15 › PSJ2015_Stuart_Attacking-HTTP2-Impleme… · HTTP2とは なぜHTTP2は強い? http2fuzz ATS Firefox NodeJS まとめ. Stuart Larsen John

http2fuzz: サーバモード

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

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

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

Page 21: 2実装を攻撃 - PacSec › psj15 › PSJ2015_Stuart_Attacking-HTTP2-Impleme… · HTTP2とは なぜHTTP2は強い? http2fuzz ATS Firefox NodeJS まとめ. Stuart Larsen John

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

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

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

ストラテジ http2fuzz

ファジング ツール

ファジング ツール

ファジング ツール

ストラテジ 1

ストラテジ 2

ストラテジ 3

ストラテジ 1

ストラテジ 3

ストラテジ 4

ストラテジ 2

ストラテジ 3

ストラテジ 4

Page 22: 2実装を攻撃 - PacSec › psj15 › PSJ2015_Stuart_Attacking-HTTP2-Impleme… · HTTP2とは なぜHTTP2は強い? http2fuzz ATS Firefox NodeJS まとめ. Stuart Larsen John

ストラテジ

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

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

HeadersFrameに付け加える

Page 23: 2実装を攻撃 - PacSec › psj15 › PSJ2015_Stuart_Attacking-HTTP2-Impleme… · HTTP2とは なぜHTTP2は強い? http2fuzz ATS Firefox NodeJS まとめ. Stuart Larsen John

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

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

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

Page 24: 2実装を攻撃 - PacSec › psj15 › PSJ2015_Stuart_Attacking-HTTP2-Impleme… · HTTP2とは なぜHTTP2は強い? http2fuzz ATS Firefox NodeJS まとめ. Stuart Larsen John

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

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

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

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

Page 25: 2実装を攻撃 - PacSec › psj15 › PSJ2015_Stuart_Attacking-HTTP2-Impleme… · HTTP2とは なぜHTTP2は強い? http2fuzz ATS Firefox NodeJS まとめ. Stuart Larsen John

ストラテジ

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

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

Page 26: 2実装を攻撃 - PacSec › psj15 › PSJ2015_Stuart_Attacking-HTTP2-Impleme… · HTTP2とは なぜHTTP2は強い? http2fuzz ATS Firefox NodeJS まとめ. Stuart Larsen John

ストラテジ

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

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

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

Page 27: 2実装を攻撃 - PacSec › psj15 › PSJ2015_Stuart_Attacking-HTTP2-Impleme… · HTTP2とは なぜHTTP2は強い? http2fuzz ATS Firefox NodeJS まとめ. Stuart Larsen John

リプレイモード

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

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

Page 28: 2実装を攻撃 - PacSec › psj15 › PSJ2015_Stuart_Attacking-HTTP2-Impleme… · HTTP2とは なぜHTTP2は強い? http2fuzz ATS Firefox NodeJS まとめ. Stuart Larsen John

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

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

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

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

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

Page 29: 2実装を攻撃 - PacSec › psj15 › PSJ2015_Stuart_Attacking-HTTP2-Impleme… · HTTP2とは なぜHTTP2は強い? http2fuzz ATS Firefox NodeJS まとめ. Stuart Larsen John

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

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

Page 30: 2実装を攻撃 - PacSec › psj15 › PSJ2015_Stuart_Attacking-HTTP2-Impleme… · HTTP2とは なぜHTTP2は強い? http2fuzz ATS Firefox NodeJS まとめ. Stuart Larsen John

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

= 4294967292

Page 31: 2実装を攻撃 - PacSec › psj15 › PSJ2015_Stuart_Attacking-HTTP2-Impleme… · HTTP2とは なぜHTTP2は強い? http2fuzz ATS Firefox NodeJS まとめ. Stuart Larsen John

node-http2

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

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

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

Page 32: 2実装を攻撃 - PacSec › psj15 › PSJ2015_Stuart_Attacking-HTTP2-Impleme… · HTTP2とは なぜHTTP2は強い? http2fuzz ATS Firefox NodeJS まとめ. Stuart Larsen John

まとめ

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

Page 33: 2実装を攻撃 - PacSec › psj15 › PSJ2015_Stuart_Attacking-HTTP2-Impleme… · HTTP2とは なぜHTTP2は強い? http2fuzz ATS Firefox NodeJS まとめ. Stuart Larsen John

終わり

質問?