Gobble up pudding

プログラミングの記事がメインのブログです。

MENU

bashの実行権を落としてCentOSが起動せず四苦八苦して復旧した記録

スポンサードリンク

f:id:fa11enprince:20150730082548j:plain
このところHOTな話題のbashの脆弱性で小手先の対策で

1. 全ユーザのデフォルトのシェルをtcshに
2. /bin/bashの実行権をなくす

という方法を暫定的に採用しようことで
検証していたらCentOSが起動しなくなって泣きそうになった記録をダラダラと書きます。

断片的なLinuxの知識しか持ち合わせていないと簡単なことでも苦しみますね。
bashの脆弱性についてはここが詳細に書かれています。bashの脆弱性(CVE-2014-6271) #ShellShock の関連リンクをまとめてみた - piyolog

ちなみにCygwinはどうなのかなーと思ったらやっぱりだめでした。

$ env x='() { :;}; echo vulnerable' bash -c "echo this is a test"
vulnerable
this is a test

$ bash -version
GNU bash, version 4.1.11(2)-release (x86_64-unknown-cygwin)
Copyright (C) 2009 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

おめでとう。見事にばるねらぼーでした。

ということでCygwinのほうはとりあえず新しいbashを入れてみた

$ env x='() { :;}; echo vulnerable' bash -c "echo this is a test"
bash: warning: x: ignoring function definition attempt
bash: error importing function definition for `x'
this is a test

やったね!!!

とまあ、本題のCentOSですが、
CentOS 6.5で検証してみました。
Cygwinからsshでrootで操作していました。

とりあえず全ユーザのデフォルトのシェルをtcshにしてみる

脆弱性チェック

[root@localhost ~]# env x='() { :;}; echo vulnerable' bash -c "echo this is a test"
vulnerable
this is a test

うん…
現在のシェル

[root@localhost ~]# echo $SHELL
/bin/bash

bashをがデフォルトシェルになっているユーザ一覧を出力します

[root@localhost ~]# grep bash /etc/passwd | cut -d: -f1
root
centuser

と、これとログインシェルを変える

chsh [-s login_shell] [user]

このコマンドを組み合わせればいいので

[root@localhost ~]# grep bash /etc/passwd | cut -d: -f1 | xargs -I{} chsh -s /bin/tcsh {}
root のシェルを変更します。
シェルを変更しました。
centuser のシェルを変更します。
シェルを変更しました。

ちなみにxargsのIオプションはここを参照してね。Linuxコマンド集 - 【xargs】標準入力から生成したコマンドラインを実行する:ITpro


ちなみにちなみにbashですがCentosではshはbashとして解釈されるようになっています。
tcshとcshも同様です。

[root@localhost ~]# ls -l /bin/*sh
-rwxr-xr-x. 1 root root 903336  7月 18 06:19 2013 /bin/bash
lrwxrwxrwx. 1 root root      4  9月 26 15:24 2014 /bin/csh -> tcsh
-rwxr-xr-x. 1 root root 106216 10月 17 00:48 2012 /bin/dash
lrwxrwxrwx. 1 root root      4  9月 26 15:19 2014 /bin/sh -> bash
-rwxr-xr-x. 1 root root 383016  2月 21 20:19 2013 /bin/tcsh

いったんログアウトして再び$SHELLを見てみます。

[root@localhost ~]# echo $SHELL
/bin/tcsh

この状態でも脆弱性チェックコマンドを叩いても当然結果は変わりません。

/bin/bashの実行権をなくします

[root@localhost ~]# ls -l /bin/*sh
-rwxr-xr-x. 1 root root 903336  7月 18 06:19 2013 /bin/bash
lrwxrwxrwx. 1 root root      4  9月 26 15:24 2014 /bin/csh -> tcsh
-rwxr-xr-x. 1 root root 106216 10月 17 00:48 2012 /bin/dash
lrwxrwxrwx. 1 root root      4  9月 26 15:19 2014 /bin/sh -> bash
-rwxr-xr-x. 1 root root 383016  2月 21 20:19 2013 /bin/tcsh
[root@localhost ~]# chmod -x /bin/bash
[root@localhost ~]# ls -l /bin/*sh
-rw-r--r--. 1 root root 903336  7月 18 06:19 2013 /bin/bash
lrwxrwxrwx. 1 root root      4  9月 26 15:24 2014 /bin/csh -> tcsh
-rwxr-xr-x. 1 root root 106216 10月 17 00:48 2012 /bin/dash
lrwxrwxrwx. 1 root root      4  9月 26 15:19 2014 /bin/sh -> bash
-rwxr-xr-x. 1 root root 383016  2月 21 20:19 2013 /bin/tcsh

んでもういっちょ脆弱性チェック

[root@localhost ~]# env x='() { :;}; echo vulnerable' bash -c "echo this is a test"
env: bash: 許可がありません

へへへ、やったね!!!
と思ったがこれが悲劇の始まりだった。
ここでやめればよかったのだが。。。
このままだと問題は起きません。

ここから自分で起こした事件です………

姉さん事件です。

何を思ったかいろいろやってて再び/bin/bashの実行権をもとに戻して
ふたたび全ユーザのデフォルトシェルをbashにしました。

[root@localhost ~]# chmod +x /bin/bash
[root@localhost ~]# chsh -s /bin/bash root
root のシェルを変更します。
シェルを変更しました。
[root@localhost ~]# chsh -s /bin/bash centuser
centuser のシェルを変更します。
シェルを変更しました。
[root@localhost ~]# chmod -x /bin/bash

そう、そしてまた実行権を落として……
デフォルトシェルがbashなのに……bashの実行権を落としてしまいました。
そうこうしていてsshを抜けて
再びログインしようとすると……

$ ssh root@192.168.100.150
root@192.168.100.150's password:
Permission denied, please try again.
root@192.168.100.150's password:
Permission denied, please try again.
root@192.168.100.150's password:

えっ?なにが起きているかわからなかった。
そう、デフォルトシェルがbashにも関わらず、bashの実行権がないという……。
まぁ、僕みたいなあほな操作しない限り起きないんだけども。

そんなわけで、CentOSは時間がたちハイバーネート状態になっていました。
さらにユーザもログアウト状態になっており、入ろうとしても入れない。
ログインしようとしたらこんな画面で止まります。
f:id:fa11enprince:20140926234534p:plain
やばい……
ということでCentOSをパワーオフして再起動……
あれダメじゃん……

…………
そうだ!シングルユーザモードで立ち上げよう。インフラ系SEのやさぐれblog 【CentOS】強制的にシングルユーザーモードで起動する

あれ……
じょうきのてじゅんどおりにやってもだめじゃん。。。
こんな画面が、
これ、bashのせいだ。
f:id:fa11enprince:20140926235406p:plain

init: Failed to spawn readahead-collector main process: unable to execute: Permission denaied
init: Failed to spawn rcS pre-start process: unable to execute: Permission denied
...
...
...

黒い画面に無情な文字列
振られたよ。絶望だよ。
つんだ?おわた?じんせいおわた?
出来心で変なタイミングで/bin/bashをchmod -xダメだった。
あぁああぁあぁあぁあ。
何の情報もみつからないまま時間が過ぎてゆく。
と、ググっていたら
GRUBの起動でinit=/bin/tcshとかが指定できることが分かったので
絶望しながらやってみる。
initスキップというものです。

"init" は UNIXマシンを立ち上げる唯一の方法ではない。最近のブートローダ(たとえばLILOやGRUB)では、カーネルが初期化の最後に何を起動するかを指定することができる(既定値はもちろん /sbin/init である)。これは、ブートローダのプロンプトに init=/foo/bar などと打ち込むことで実現される。これは直接シェル(bashやzsh)を使いたい場合に便利な機能である。たとえば、init=/bin/bash を使えば、シェルが使える状態で立ち上がり、パスワードを入力する必要もない。システム管理者がこれを安全でないと判断する場合は、ブートローダのパスワードを設定すればよい。

http://ja.wikipedia.org/wiki/Init

とりあえずinitスキップでtcshを起動します。

<=pc KEYTABLE=us rd_NO_DM rhgb quiet single init=/bin/tcsh

1. 起動してすぐにeボタンを押す。
2. CentOS(...)を選んでeを押す。
f:id:fa11enprince:20140926235835p:plain
3. kernel /vmliuz-2.6...を選んでeを押す。
f:id:fa11enprince:20140927000058p:plain
4. single init=/bin/tcshをスペースをあけて追記する。

<=pc KEYTABLE=us rd_NO_DM rhgb quiet single init=/bin/tcsh

US配列になっているので=の入力は頑張ってください。
f:id:fa11enprince:20140927000139p:plain
5. 編集が終わってさっきの画面に戻るので今度はbを押す。
f:id:fa11enprince:20140927000236p:plain

やったーきどうした(*´Д`)!!
よーしあとはbashの実行権を復活させるぞー

[root@(none) ~]# chmod +x /bin/bash
chmod: changing permissions of '/bin/bash': Read-only file system
[root@(none) ~]# bash
'/bin/bash: Permission denied.

あれっ
f:id:fa11enprince:20140927000813p:plain
…………
……………………
………………………………

シングルユーザーモードで起動する - maruko2 Note.

そうだった……シングルユーザモードならマウントしなきゃダメだった。

[root@(none) ~]# mount -o remount /
[root@(none) ~]# chmod +x /bin/bash
[root@(none) ~]# ls -l /bin/bash
-rwxr-xr-x. 1 root root 903336 Jul 18 2013 /bin/bash
[root@(none) ~]# exit

ふう。これでCentOSの起動ができるようになりました。
でもexitしたらカーネルパニックになって止まりました。
Kernel panic - not syncing Attempted to kill init
でもそのあと普通に起動できています。

というかinitスキップで起動してるので終了時にinitを終了させにいこうとしてしまうので当たり前の挙動でした\(^o^)/回避策は電源ブッチンしかないのかな。。。

というわけで、何やってんだこいつ記録でした。