変わったXSSを2つ紹介します。ToolbarがインストールされているIEでしか動作しません。上に用意されたUIから、ツールバーを操作するコマンドを実行できるようになります。このコマンドを利用することでXSSに繋げるという点が、よくあるものとは異なります。上の次のページをみると、こんなコードを発見できます。menu">このページでは、ツールバーの設定をリセットできるようになっています。ページ内のボタンを押すと、fixmenu()→command('&fixmenu=1')と関数が呼ばれます。command()関数では、window.location="http://toolbar.google.com/command?key="...に対してナビゲーションしようとしているようにみえますが、実はこれがコマンド実行操作です。対するナビゲーション操作が、ページ遷移ではなく、コマンドの実行と解釈されるようになります。このURLにつけられたクエリが実行したいコマンド操作に対応しています。fixmenu=1に対応しています。document.googleTokenの部分は、外部から勝手にコマンドを実行させないためのCSRFトークンの役割をしています。設定したランダムな値が入ります。この値が正しくないと、コマンドは実行されません。上のみで参照可能です。こんな作りになっています。いう特殊な実装部分にはいかにも脆弱性がありそうです。Toolbarをインストールして詳しくみてみることにしました。上に書かれたコマンドをみてまわったり、Toolbarのバイナリを覗いてみたりしました。見ていく中で、navigatetoというコマンドがあることがわかりました。このコマンドは、名前の通り、ナビゲーションをするためのコマンドでした。対してナビゲーションが起きました。Toolbarではこのコマンドは無くなっているようです。)location="http://toolbar.google.com/command?key="+document.googleToken+"&navigateto=http://example.com/"ナビゲーションとわかれば、httpなURL以外でもナビゲーションできるか試してみたくなります。この部分をjavascript:のURLに変えて試してみます。location="http://toolbar.google.com/command?key="+document.googleToken+"&navigateto=javascript:alert(1)"すると、アラートが実行されました!おお!でも、まだ喜ぶところではありません。document.googleTokenの値が外からはわからないため、このコマンドを誰かに罠リンクを踏ませて実行させるようなことはできないからです。逆に言えば、document.googleTokenの値をどうにかして取得できれば、スクリプトを実行させられるかもしれません。ページをみてまわっていると、次のようなページをみつけました。(現在はページが無くなっています。--></script>最初の例と同様に、ボタンを押すと、コマンドが実行されるようなページです。"dcuninstalled.html");で、コマンドの実行をしています。繋げると複数のコマンドを一度に指定できるみたいです。コマンドの詳細はさておき、注目すべきはここに含まれているpathという変数です。pathは直前で定義されています。1);location.hrefからコマンドに含む文字列を受け取っている様子です。1で、URLの最後に出てくるスラッシュまでをsubstring()で切り取っています。このコードを書いた人が取り出したいのは、以下の太字部分の、ファイル名をのぞいたパスまででしょう。https://toolbar.google.com/dc/dcuninstall.htmlでも、この切り出し方は雑すぎます。余分なスラッシュをもっと後ろに入れられたら予想外のURLを切り取ることになります。https://toolbar.google.com/dc/dcuninstall.html?xxx/yyyこの切り取った文字列はnavigateto=に連結されるので、ナビゲーションに使いたいようです。ここではlocation.hrefの先頭から切り取っているため、いくら切り出すURLを間違えているとはいえ、一見、XSSどころかオープンリダイレクトバグにすらならないようにも思えます。https://toolbar.google.com/dc/dcuninstall.html?&navigateto=javascript:alert(1)//スラッシュはURL全体の一番最後にあるので、URL全てが切り取られることになります。このURLがpathという変数に入り、コマンドとして実行されるときの値をみてみましょう。挿入したことで、ページ側が指定したnavigateto=に渡るURLは挿入した&の手前で区切られることになります。その後ろに、自身でもう1つnavigateto=を追加します。すると、navigatetoのコマンドが2つあることになりますが、同じコマンドが複数あるときは、一番後ろにあるコマンドが実行されるようになっているようです。対するものになります。これで、アラートが実行されます!このように、コマンドにユーザー入力値を不用心に引き渡している部分を利用することで、document.googleTokenを知らずとも、XSSに繋げることに成功しました。漁っていると、また面白いページをみつけました。onload="Load()">順に見ていきます。onloadで、Load()関数が実行されます。分解して、パラメータ名と値のペアを取り出しています。ここでは、太字部分にあるようにcustom_button_uriというパラメータを探しています。パラメータがあれば、その値をdocument.custom_button_uidという変数に代入するようになっています。unescape(param_pieces[1]);}}}ここで設定された、document.custom_button_uidはこのすぐ後で、コマンド実行関数へと引き渡されます。document.custom_button_uid);}少なくとも、ユーザー入力値がcustom_button_uriというクエリを介してコマンド文字列として渡っているということです。危なっかしいかんじがしますが、&ごとにクエリを分解しているため、1つ目のXSSで示したような、単純に&で追加のコマンドを紛れ込ますような手は使えません。unescape(param_pieces[1]);なんと都合がいいことに、custom_button_uriの値をunescape関数にかけているではありませんか。以下のようにエンコードしてcustom_button_uriに渡せば、https://toolbar.google.com/buttons/edit/index.html?custom_button_uri=%26navigateto%3Djavascript:alert(document.domain)%26が&、%3Dが=にunescapeされ、最終的に実行されるコマンドは次のような、navigateto=を含むものになります。報奨金を獲得しました。文書化されていないコマンドの動作を把握するのは大変でしたが、古い技術にひっそりと残っている脆弱性を暴けたときの喜びはひとしおでした。古い技術とはいえ、特権が与えられた機能の実装が脆弱性に繋がってしまうことは、最近トレンドマイクロのパスワードマネージャでもあったように、今の時代の技術にも潜んでいる、今後も注意を払う必要がある普遍の部分だと思います。最後に、この時期に毎年紹介しているGoogleからのクリスマスプレゼント、今年も頂いたので紹介したいと思います。Bountopoly(バグハンター版のモノポリー?!)、Googleセキュリティチームからのポストカードです。夏に日本のGoogleオフィスでお会いしたセキュリティチームのStephenさんです。掲載許可をもらったので載せます。