セキュリティコンテスト入賞者に聞く

x86コードのサンドボックス、グーグルの「NaCl」は安全か?

2009/08/06

 Webブラウザ上で、ネットワークからダウンロードしたx86バイナリを安全に実行する――。2008年暮れにグーグルがオープンソースプロジェクトとして公開した「NaCl」(Native Client)は、本当に安全なものに仕上げることができるのか。先日グーグルが主催したセキュリティ・コンテスト、「Native Client Security Contest」でNaClの脆弱性を2つ発見して、日本人で唯一入賞したサイバーディフェンス研究所 上級分析官の福森大喜氏に話を聞いた。

静的解析で安全にx86コードを実行

photo.jpg Native Client Security Contestで入賞した、サイバーディフェンス研究所 上級分析官 福森大喜氏

 福森氏は、Webブラウザ上にx86バイナリを実行するサンドボックスを載せるというアイデアを評価する。「基本的には、いい考え。コードに悪意がある場合でも、WebブラウザやOSが被害を受けないようにできている。ソースコードを見た印象ではOSのカーネルに似ている」(福森氏)。NaClでは、メモリ空間をセグメントで分離し、特定のプログラムがほかのメモリ空間にアクセスできないようにしているという。

 x86コードの実行環境として、NaClではほかにも安全性を高める仕組みがある。NaClではNaClモジュールのコンパイルにgccにパッチを当てたnacl-gccが使われるが、コンパイル時にさまざまな静的解析を行っている。例えばLinuxのシステムコールを発行する命令の「int 80h」は静的解析によってハネられる。NaClではホワイトリストによるアセンブリ命令のチェックを行っていて、システムコールの発行やセグメントレジスタの操作ができなくなっているという。

 NaCl環境ではシステムコールは「トランポリン」と呼ばれる領域を経由してから行うため、コードの自己書き換えによってシステムコールを隠蔽しても、やはり実行時に補足される。

 ほかにも、jmp命令で飛べるアドレスは、必ず32バイト境界に強制されていて、典型的な攻撃手法の1つである「逆アセンブラだまし」が難しくなっているという。逆アセンブラだましとは、コードの中途半端な場所に制御を飛ばすことで、隠蔽しておいた悪意のあるコードを実行する手法だ。

trampoline.jpg NaClモジュールは直接システムコールが呼び出せず、いったん「トランポリン」と呼ばれる領域を経由する
jmp.jpg jmp命令では、飛び先のアドレスが必ず32バイト境界となるようになっていて、中途半端な場所に悪意のあるコードを隠蔽する手法が使えない

発見したNaClの2つの脆弱性

 福森氏は次々と既知の攻撃手法でNaClの脆弱性を調べていき、2つの問題を発見したという。

 1つはNaClモジュールから、ローカルPCの環境変数にアクセスできてしまうという問題だ。「メモリが分離されているというので、片っ端からアクセスできる領域を見ていき、環境変数が入っていることに気が付いた」という。環境変数には、必ずしもクリティカルな情報が入っているとは限らないが、「ユーザーはブラウザを見ているだけで、ローカル上のユーザー名が取得されると思っていない」(福森氏)ため、違和感があるのではないかという。特定のソフトウェアが入っているかどうか、バージョンはいくつかといった情報が漏れれば、ほかの脆弱性につながる可能性もある。

found.jpg アクセス可能なメモリ領域を見ていくと、環境変数が保存されている領域が見つかったという
env.jpg 実際にNaClモジュールを使ってローカルPCの環境変数を読み出した例

 福森氏が発見したNaClのもう1つの脆弱性は「Same-Originポリシー」の破れだ。embedタグを用いてHTMLファイルをNaClのモジュールであるかのようにブラウザに読み込ませると、NaClはこれをローカルのテンポラリディレクトリに保存してしまう。このファイルを再び読み込むことで、実際には外部サイトから取得したHTMLファイルであるのに、ローカル上のファイルとして認識してしまうため、クロスドメインアクセスが可能となってしまう。これにより、「例えばGmailの内容が読み取られる可能性がある」(福森氏)という。

クラウド時代のセキュリティとは

 福森氏が発見したのはNaClの脆弱性だが、現在の技術トレンドに照らせば、特定ソフトウェアのみの脆弱性とも言い切れない面がある。

 例えば、最近ではローカルで動かすWebアプリケーションや、動的に生成されるエラーページやレポートページがHTMLであるケースが増えている。こうした設計だと、NaClにあった上記のクロスドメインアクセスと同じ脆弱性を抱える可能性がある。福森氏は、Webアプリケーションが急増するクラウド時代に向けて、「脆弱性の考え方も変わってくるのではないか。Webアプリケーションであっても、仮想化のインフラやマルチテナント型サービスで、OS自体を巻き込んだような検証が今後は重要」(福森氏)と指摘する。

 80番、443番ポートに関連したXSSやSQLインジェクションなど、Webアプリケーションの脆弱性については、攻撃方法も対応法も比較的よく知られていて、ある意味では安定してきている。それがクラウドの普及で変わる。福森氏自身も、これまではWebを中心にセキュリティの専門家として活動していたが、サイバーディフェンス研究所では最近、海外の仮想化インフラ専門の技術者と協力するなど、違うジャンルの専門家との連携を重視しているという。

 「今回のNaClのセキュリティコンテストの参加者は、みんな自分の好きなところを突いてみたというところ。まだ十分に脆弱性が洗い出されているとは言えない」(福森氏)という。「コンテストという形式はセキュリティを考える上でいい面がある。コンテスト1位の人に監査をお願いしてセキュリティの問題を洗い出してくださいと言っても、2位や3位の人が見つけた問題を発見できるとは限らない。さまざまなジャンルの専門家が違ったアングルから見なければならない。クラウド時代には特にそうした傾向が強くなる。特定の専門家が、“これでセキュアだ”と言い切るのは難しい。そういう意味で、今回のコンテストの結果は、監査を受ける側の人たちにもいいサンプルになるのではないか」(福森氏)。

 コンテストに入賞した脆弱性の指摘を見ると、Webアプリケーションの脆弱性に似たものがある一方、x86バイナリ固有のものも多く、多岐にわたっている。

サンドボックスは破られるたびに強くなる

 x86関連では、まだNaClが初期段階の技術だと認識させられる脆弱性も発見されている。

 NaClではホワイトリストベースでアセンブリ命令の実行を明示的に許可しているが、使い方によって危険となる命令も許可されていたようだ。例えば、x86にはメモリ内容を連続してコピーする命令があるが、このコピー方向を設定する「std」命令はNaClモジュールで利用が許可されている。これが問題を引き起こすという指摘が入賞している。NaClモジュールからメモリのコピー方向を変更して、システムコールを発行すると、コピー方向を保持するEFLAGSの内容がシステムコールをまたいで保持されたままとなる。OSが想定するのと逆方向にメモリコピーを実行させることでスタック破壊を引き起こし、任意のコードを実行させることができる。

 NaClチームは、この脆弱性に対処するために、システムコールを発行する前に慎重にフラグをクリアするコードを追加したという。こうした例を見ると、NaClで十分な安全性が確保できるまで、まだしばらく時間がかかると考えられるが、福森氏はNaClの今後について、「サンドボックスは破られる。しかし破られるたびに強くなる」と前向きな評価をしている。

(@IT 西村賢)

情報をお寄せください:



Security&Trust フォーラム 新着記事

注目のテーマ

Security & Trust 記事ランキング

本日 月間