2011年8月27日土曜日

Apache killerは危険~Apache killerを評価する上での注意~

Apacheの脆弱性(CVE-2011-3192)いわゆるApache killerが話題になっていますが、その脅威については一部誤解があるようです。

以下は、非常に脅威とする報告の例です。
一方今回のはプロセスの肥大化を伴うので、実メモリ消費して更にスワップも使い尽くしてOS毎激重になったあげくLinuxとかの場合はOOM Killer発動と、他のプロセスや場合によってはOSを巻き込んで逝ってしまいます。
CVE-2011-3192 Range header DoS vulnerability Apache HTTPD 1.3/2.xより引用
以下は、それほど脅威でなかったとする報告の例です。
pooh.gr.jp は結構頑丈だったので 60 並列でやっと CPU idle 30% まで減らせた。
Apache Killer (CVE-2011-3192) 対策 for CentOS 5.6より引用
この差はなんでしょうか。サーバーが「結構頑丈だった」せいでしょうか。

それだけではありません。Apache killerを評価する上で重要なパラメータが2つあります。以下に示します。
  • ダウンロード指定するコンテンツのバイト数
  • ApacheのMaxClients設定

なぜコンテンツのバイト数が重要か

既に報告されているように、Apache killerはRangeヘッダに多くのパラメータを指定することにより、Apacheの使用メモリを増大させます。現在出回っているPoCの生成するRangeヘッダを以下に示します。
Range: bytes=0-,5-0,5-1,5-2,5-3,5-4,5-5,5-6,5-7,5-8,5-9,5-10,5-11,5-12,5-13,5-14,5-15,
5-16,5-17,5-18,5-19,5-20,5-21,5-22,5-23,5-24,5-25,5-26,5-27,5-28,5-29,5-30,5-31,5-32,

--CUT--

5-1281,5-1282,5-1283,5-1284,5-1285,5-1286,5-1287,5-1288,5-1289,5-1290,5-1291,5-1292,
5-1293,5-1294,5-1295,5-1296,5-1297,5-1298,5-1299
ご覧のように、5-1,5-2,5-3,…,5-1299 までのRange指定が含まれます。このため、URLで指定するコンテンツのデータサイズが1299バイト以上ないと、このPoCの「真価」が発揮されないと予想されます。
これを実験で試してみました。killapache.plをN=1で走らせ、URLで指定されるコンテンツ(/index.html)を0バイトから2000バイトまで変化させて、apacheのプロセスのメモリサイズを測定しました(追記:MaxClientsは3としました。理由は後述)。まずは生データです。

以下は、グラフにしたものです。

予想通り、コンテンツサイズが1300バイトまではプロセスサイズが大きくなりますが、それ以上ではプロセスサイズは変わりません。すなわち、Apache killerを評価する上では、コンテンツのサイズを1300バイト以上にすることが重要なポイントとなります。

pooh.gr.jpの評価では、robots.txt(約30バイト)を指定していたため、Apache killerはまったく真価を発揮しておらず、単なるF5攻撃と変わらない状況だったと予想されます。


MaxClients設定が重要な理由

ここまで説明すると、Apache killerの評価をする上でMax Clientsが重要である理由を説明することも容易になります。Apache killerのリクエストを受け付けると、元々24メガバイトだったApacheプロセスの消費メモリが96メガバイトと4倍になります。しかし、MaxClientsが十分余裕を持って設定されていれば、プロセスメモリが増大しても処理を継続することができます。

徳丸の評価結果

私も最初上記をよく理解しておらず、「あれ、Apache killer大したことない?」と誤解しかかったり、「評価環境が非力なので差が出ないのかな」と思ったりしました。上記に気がついた後、以下の条件で評価してみました。

VMのメモリ割りあて: 2ギガバイト
swap:512メガバイト
コンテンツのサイズ:約50Kバイト(一般的なコンテンツのサイズを想定)
MaxClients: 50
OS:CentOS5.6(32ビット)


上記条件でApache killerを走らせた場合、必要なメモリサイズは96 * 50 = 4800メガバイトとなり、メモリ+swapがまったく不足する状況となります。
結果は、ping以外はまったく応答しなくなりまりした。sshからコマンドを打つことも、VMwareのコンソールからログインすることもできなくなり、リセットするしかない状態でした。

このエントリを読んだ皆様、Apache killerはやはり凶悪です。くれぐれも油断なきよう、至急の対策をお勧めします。
私は、Apache2.2を使っていましたので、アドバイザリに従い、httpd.confに以下を追加しました。

# Drop the Range header when more than 5 ranges.
# CVE-2011-3192
SetEnvIf Range (?:,.*?){5,5} bad-range=1
RequestHeader unset Range env=bad-range
# We always drop Request-Range; as this is a legacy
# dating back to MSIE3 and Netscape 2 and 3.
RequestHeader unset Request-Range

3 件のコメント:

  1. s/デーサイズ/データサイズ/g;
    s/swap:512バイト/swap:512メガバイト/g;
    # かな?
    # Dan the Apache Killer Killer

    返信削除
  2. ご指摘ありがとうございます。修正します

    返信削除
  3. コメントとして追記します。
    本文のメモリ見積もりは、Apacheの共有メモリの寄与を考慮していないので、その分過大になっています。記事の特性上、大ざっぱな見積もりができれば十分ということでご了承ください。

    返信削除

フォロワー