2012年5月28日月曜日

Nexus S を素のまま root 化する方法 ? アンロック不要、リカバリROM書換も初期化も不要

Android 端末の root 権限を取得するには大別して次の二つの方法がある:

  1. ブートローダをアンロックしてリカバリを書換 (fastboot oem unlock)
  2. セキュリティホールを利用して root 権限を奪取 (RageAgainstTheCage)

1. の方法は Google 正規の方法。 開発目的で Android 端末をいじるときは root 権限を取得したほうが何かと便利なので、 Nexus One や Nexus S など開発者用の Android 端末は、 「仕様」 として root 権限を取得できるようになっている。

開発用でない端末の root を取れてしまうとセキュリティ上の脅威となる (他人の端末で勝手に root を取ってプライベートデータを盗み読むなど) ので、 端末上の全データを消去した上でないとアンロックできない。 なので、 root を取る前にアプリをインストールしたり、 設定を変更したりすると、 アンロックしたとき全て消えてしまって二度手間になる。 だから Nexus S を入手したら、 何よりも真っ先にアンロックすべき (← くどい)。

2. の方法は、 (root 権限で起動される) adbd が、 setuid(2) を使って root 権限を手放す (adbd は shell ユーザ権限で動く) ときに、 エラー (setuid の返値) チェックを行なっていない、 というバグ (セキュリティホール) を利用する。 具体的には RageAgainstTheCage exploit を利用して (再起動した) adbd が setuid を呼び出すときにリソース不足 (errno = EAGAIN) で失敗させ、 adbd が root 権限を手放さずにそのまま走るようにすることにより、 root 権限が利用できるようになる。

一般の (開発者用でない) 端末をいじり倒したい場合には便利な方法だが、 当然ながら悪用もできるわけで、 ユーザが意図しないところでアプリが勝手に root 権限を奪取してしまうと、 極めてやっかいなことになる。 実際そういうマルウェアも出回っているらしい。

Android Gingerbread 2.3.3 以降でこのバグが修正され、 RageAgainstTheCage では root 権限を奪取できないようになったのは当然と言える。 むしろ遅きに失したくらい。 これだけ有名かつ重大なセキュリティホールを今まで放置した Google は万死に値する。

というわけで、 Nexus S の箱を開封して真っ先にアンロックしようと FASTBOOT MODE にした (音量大ボタンを押しながら電源を入れる) のだが、 アンロックコマンド (fastboot oem unlock) が使えるなら、 もしかすると、 その他の fastboot コマンドも使えるのではないか? という思いがよぎり...

senri:~ $ fastboot boot recovery-clockwork-3.0.0.5-crespo.img  downloading 'boot.img'... OKAY  booting... OKAY  

ありゃ (^^;)、 clockwork リカバリで起動してしまった。 リカバリイメージをフラッシュしていない点に注目。 フツーは、 アンロックした上でリカバリイメージを書込み、 リカバリモードで起動して root 化するのだが、 そうした手順をすっ飛ばして起動できてしまった。

ちなみに、 リカバリイメージを書込むにはアンロックが必要であるようだ:

senri:~ $ fastboot flash recovery recovery-clockwork-3.0.0.5-crespo.img   sending 'recovery' (3980 KB)... OKAY  writing 'recovery'... FAILED (remote: Bootloader Locked - Use "fastboot oem unlock" to Unlock)  senri:~ $   

フラッシュに書込みできなくても、 任意のカーネルを起動できたら何でもできるわけで、 ロックする意味がなくなってしまう。 実際、 root 権限があれば flash_image コマンドでリカバリイメージを書き込むことができた。 アンロック不要で 「fastboot boot」 コマンドが実行できてしまうのは、 バグなのではないか?

バグか仕様かはサテオキ、 現状の Nexus S は、 アンロックせず、 フラッシュへの書込みもせずに clockwork リカバリが起動できたので、 初期状態のフルバックアップが可能。 しかも、 clockwork リカバリは、 adbd が root 権限で動いている (これはバグではなく仕様) ので、 adb でアクセスすれば root になれる。

senri:~ $ adb shell  ~ #   

う〜ん、簡単すぎ。 こんなことでいいのだろうかと思いつつ、 アンロックする手間が省けたので、 clockwork リカバリのメニューから 「mount /system」 を実行し、 su コマンドをインストール:

senri:~ $ adb push su-2.3.6.1-ef/system/bin/su /system/bin/  596 KB/s (26264 bytes in 0.042s)  senri:~ $ adb install su-2.3.6.1-ef/system/app/Superuser.apk  1825 KB/s (196521 bytes in 0.105s)  	pkg: /data/local/tmp/Superuser.apk  Success  senri:~ $ adb shell  ~ # chmod 4711 /system/bin/su  ~ #   

というわけで、 Nexus S を素のまま root 化できてしまった。 ブートイメージやリカバリイメージを変更する必要がないので、 文鎮化リスクが全く無い安全な root 化方法と言えるが、 逆に言うと端末に痕跡を全く残さずに root 権限を奪取できてしまうわけで、 いいんだか悪いんだか...

同日 23:00 追記:

Android 2.3.3 (ビルド番号 GRI40) へアップデートしたら、 「fastboot boot」 が実行できる穴は塞がれてしまった。 GRH78 で、 ロック状態にもかかわらず任意のカーネルをブートできたのは仕様ではなくバグだったようだ。 しかたないので素直にアンロックした:

senri:~ $ fastboot boot recovery-clockwork-3.0.0.5-crespo.img  downloading 'boot.img'... OKAY  booting... FAILED (remote: Bootloader Locked - Use "fastboot oem unlock" to Unlock)  senri:~ $ fastboot oem unlock  ... OKAY  senri:~ $ fastboot flash recovery recovery-clockwork-3.0.0.5-crespo.img  sending 'recovery' (3980 KB)... OKAY  writing 'recovery'... OKAY  senri:~ $  

Nexus S は /sdcard ディレクトリが 「SDカード」 ではなく内部フラッシュメモリなので、 アンロックすると全消去されてしまう。 アンロックする前に /sdcard 以下のバックアップファイルを PC に退避しておかないとリストアできなくなるので注意。

0 件のコメント:

コメントを投稿