MIMEデリミタ注入攻撃

Preview:

DESCRIPTION

マルチパートMIMEを返すWebアプリケーションにおける脆弱性

Citation preview

マルチパート MIME を返す Web アプリケーションにおける脆弱性

マルチパート MIME 境界注入攻撃とその対策Vulnerability on web application returns multipart MIME content

Attack and defense method for Multipart MIME delimiter Injection

multipart な MIME コンテンツの仕様(RFC2046)

 Content-type: multipart/*; boundary=”boundary text”

と書くと[CRLF]--boundary text(スペース)* [CRLF]

 がボディの各パートの区切りとなる 各パートはこの区切を含んではいけない(MUST NOT)。

含んでいるとどうなるのかContent-type: multipart/x-mixed-replace; boundary=AAA--AAAContent-type: text/plain; charset=UTF-8プレーンテキスト部その1--AAAContent-type: text/plain; charset=UTF-8プレーンテキスト部その2--AAA--

ここで 「その2」を

「--AAA[CRLF]

Content-type: text/html; charset=UTF-8 [CRLF][CRLF]

<html><script>alert(1)</script></html>[CRLF]」

に変えたら?

こうなります。Content-type: multipart/x-mixed-replace; boundary=AAA

--AAAContent-type: text/plain; charset=UTF-8

プレーンテキスト部その1--AAAContent-type: text/plain; charset=UTF-8

プレーンテキスト部--AAAContent-type: text/html; charset=UTF-8

<html><script>alert(1)</script></html>--AAA--

2 パート目が分割されて JavaScript 入りの HTML が注入されてしまいました。

Content-type: text/plain; charset=UTF-8

プレーンテキスト部

Content-type: text/html; charset=UTF-8

<html><script>alert(1)</script></html>

これがマルチパート MIME デリミタの注入によるコンテンツの改竄です。

これは、Web サーバのレスポンスで発生すれば HTTP レスポンス分割、E メールに使用すればメールの改竄となります。

問題への対策

(1)エスケープやサニタイズは本質的な対策ではない

  ・コンテンツの各パートの種類によってはエスケープする方法がない(text/plain など)。

・Content-Transfer-Encoding: base64 や US-ASCII の上位互換ではないエンコーディングを使えば HTML 等のエスケープを迂回できる

(2)本質的な対策 

絶対に delimiter をコンテンツ本体部に注入できないようにする。

具体的には以下のいずれかを行う

(1) 事前に全てのパートに delimiter が含まれないことを確認する(事前に全パートの内容が確定している場合に有効な方法。静的ページならこれで十分)

(2) 各パートを Content-Transfer-Encoding: base64 として base64 でパート本体をエンコードにする(delimiter 先頭の”--”の注入が不可能になる)。

(3) boundary をランダムにすることで攻撃者が実用的なコストで故意に衝突させることが出来ない様にする

(4) Animation GIF や動画などの代替技術を使う

実用的な攻撃が成功する条件の検証

1. delimiter の注入が成功する条件

--boundary textとその前後の[CRLF]の間が空白文字だけであること

※RFC と違って Gecko は --boundary text の前にスペースがあっても構わない

   

2. 注入された body-part を攻撃者にとって有効なものにするための条件

以下のいずれかが出来る必要がある・ body part の Content-* ヘッダ注入できる・ multi part の終端が注入できる・ 攻撃者の注入した文字列の後ろに意味のある文字列が

全く存在しない

安全なライブラリの使い方(Web ブラウザへ返す応答の場合)

(1) CGI.pm の multipart_init()・毎回同じ boundary 指定で呼んでいるとバージョンに関

係なく危険。・を予測不能な boundary を指定して呼べば安全・boundary 指定無しで使う場合は、Ver.3.50 以降では自

動でランダムな boundary が採用されるので安全だが、Ver.3.49 以前は毎回同じ boundary なので危険

(2) CGI.pm の CGI:Push・比較的古くから安全(自動でランダムな boundary を生

成)・念のためソースを確認して boundary がランダムである

ことを確認する

(3) CGI:Simple の multipart_init()・boundary 指定がある場合の条件は CGI.pm と同じ・github の 2010 年 11 月 13 日の更新を含むバージョン以

降は boundary 指定無しでも安全

安全なライブラリの使い方(E メールの動的な生成)

すいません、未調査です。ソースを確認して適切な実装のライブラリを使って下さい。

まとめ

・HTTP レスポンス分割は HTTP ヘッダインジェクション だけじゃない。

・MIME の boundary は中身が予想できないならランダム にするのが正しいあり方。実際、メールクライアントはほとんどがそのように実装されている。

・安全なサンプルコードが少ないので注意。

Recommended