アプリ開発やサイト制作のスマホ端末実機検証・テスト-Remote TestKit

Androidアプリセキュリティ ~Webサイト閲覧でroot権限を取得されてしまう脆弱性(2)~

本記事では管理者権限を取得するにはどうしたらよいのかについて説明していきます。

前回はWebkitの脆弱性を利用して任意のコードを実行する方法を説明しました。
今回はその状態から管理者権限を取得するにはどうしたらよいのか?について説明していきます。

3.Voldの脆弱性

この章では、Gingerbreakというアプリケーションを使用した管理者権限の取得方法について説明します。
GingerbreakはVold(VolumeDaemon)といわれるAndroidのsystemサービスの脆弱性を使用しています。
下のコードを見てください。

Android2.2のソースコード中の、/system/vold/DirectVolume.cpp

入手元:Android Open Source Project

上記のソースコードはVoldのソースコードです。
まず、ソースコード上部の黄枠内に注目してください。
このNetlinkEventは外部アプリケーション(今回はGingerbreak)からVoldにメッセージを送信することができる仕組みになっています。

次に、ソースコード下部の黄枠内に注目してください。
この部分のソースコードではmPartMinors配列に値を代入しているにも関わらず、part_numが配列の要素数を超過しているかどうかのパラメータチェックを行っていません。
つまりmPartMinors配列の最大要素数を超えた領域からの読み書きが可能であり、バッファオーバーフローを引き起こす可能性があります。
また、ここで注目しなくてはならないのが、「part_num変数はNetlinkEventによって指定可能である」という点です。
つまり、Voldのバッファオーバーフローは外部アプリケーションによって意図的に引き起こすことが可能です。
今回説明するGingerbreakはこのバッファオーバーフローを利用して管理者権限を取得しています。

では、どのようにして管理者権限を取得するのでしょうか?下の図を見てください。

上記の図はプログラムが動作しているときのメモリイメージです。
図左側のようにmPartMinors[]でオーバーフローが発生しています。
この図中にあるGOT領域とはGlobalOffsetTableといわれていて、printfやsizeofの様な共有ライブラリ関数が存在するアドレスが記載されています。
それを右図では、バッファオーバーフローを利用してすべてsystem関数に置き換えてしまいます。

では、すべてsystem関数に置き換わると何が起こるのでしょうか?下のソースコードを見てください。

Android2.2のソースコード中の、/system/vold/DirectVolume.cpp

入手元:Android Open Source Project

上記ソースコードは同じくVoldの関数の一部です。共有ライブラリがsystem関数に置き換わった結果、上記のようにstrncmp関数がsystem関数に置き換わってしまいます。
この関数には前述したようにNetlinkEventが引数として与えられていますので、strncmp関数の第一引数には外部アプリケーションから任意のパラメータを与えることができます。
もともとVoldはsystemサービスですので、管理者権限で動いています。
ゆえに、外部アプリケーションから任意のパラメータを送り、system関数を経由して管理者権限で任意のコマンドが実行できるようになるわけです。

ここまでが、「Android端末からWebサイト閲覧で管理者権限を取得されてしまう」一連の説明になります。
でも、「そんな危ないリンクなんて踏むわけがないじゃないか!」と考える方もいると思います。
次章では、身近な想定されるケースについて紹介します。

4.想定されるケース

想定されるケースとしては下図のようなケースです。
たとえば社内メールを装ってリンク付のメールが来たとします。
そこに悪意のあるPCが公開しているWebページのリンクが記載されていた場合、そのリンクをクリックするだけでここまでで説明した通りWebkitの脆弱性が利用され任意のコマンドが実行できるようになり、Gingerbreakのような管理者権限を取得するツールを送り込まれて、管理者権限で任意のコマンドが実行可能な状態にされてしまうかもしれません。

また、今回説明した方法はウイルスを使用した攻撃ではありません。
よって、一般的なアンチウイルスソフトでは検出することができません。
悪意のあるユーザが任意のコマンドを実行する場合には、「/system/bin/sh」をリモートから実行するケースが多いようです。
対策としては、管理者権限や不明なプロセスのshコマンドが動作していないかどうかを定期的に監視し、それらを発見した場合はプロセスを強制停止させる事です。
データの保守を目的とするアプリケーションで「system/bin/su」を検知するアプリケーションは多く見かけますが、今回の様にリモートから任意のコマンドを実行されてしまうようなケースでは、前述したようなsh監視機能の実装が効果的です。

5.対象端末

最後に対象端末です。
今回の現象はAndroid2.2でのみ発生する脆弱性です。
Android2.2とはいえ、Googleの昨年10月の調査結果によれば、Android2.2は全体の12%を占めています。
依然として高い数値である事には変わりません。

2013年2月4日現在

入手元:http://developer.android.com/about/dashboards/index.html

いかがだったでしょうか?今回説明したのは一例にすぎません。
任意のコードが実行可能な脆弱性というのは多くのOS、アプリケーションに潜んでいます。

  • アプリケーション開発者の方は脆弱性の有無に関係なく、不具合を見つけたら迅速にアップデートを提供する事。
  • エンドユーザの方はそれらアップデートをきちんと適用する事。

基本的な事になりますがこの2点の心がけを忘れないでください。

執筆者プロフィール 片沼 怜、安部 剛

NTT-CERTメンバとして、セキュリティインシデントの対応支援、再発防止策の 検討、トレーニングプログラムの開発およびセキュリティ関連情報の提供など を実施中。