su(1)
が使えない
ちょっとしたことでマシンが不調になり、su(1)
ができなくなったときにやってみた知見をまとめた。
再現させて見たけれども、最悪の場合どうしようにもなくなってしまう可能性があるので、壊してもいい環境で遊んでいる。
何が起こったか
su(1)
で実行するのに必要なライブラリがみつからなくなってしまった。
$ su - su: error while loading shared libraries: libaudit.so.1: cannot open shared object file: No such file or directory
で、libaudit.so.1
を探してみると、以下のように誰かが名前を書き換えて、libaudit.so.1
を消してしまった(ここではlibaudit_dymmy.so.1
に書き換えてしまった)らしい。。。
ll /lib/x86_64-linux-gnu/ |grep libaudit -rw-r--r-- 1 root root 133200 8月 16 15:37 libaudit.so.1.0.0 lrwxrwxrwx 1 root root 17 10月 19 01:07 libaudit_dummy.so.1 -> libaudit.so.1.0.0
マシン環境など
$ less /etc/os-release
してみた結果は以下の通り。
Hyper-Vで立ち上げた仮想マシンで、最悪の場合完全に復旧不可能になってしまうため、チェックポイントを立ててバックアップはとっている。
NAME="Ubuntu" VERSION="19.10 (Eoan Ermine)" ID=ubuntu ID_LIKE=debian PRETTY_NAME="Ubuntu 19.10" VERSION_ID="19.10" HOME_URL="https://www.ubuntu.com/" SUPPORT_URL="https://help.ubuntu.com/" BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/" PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy" VERSION_CODENAME=eoan UBUNTU_CODENAME=eoan
どうやって対応するか
よくみると、libaudit.so.1.0.0
自体は無傷でlibaudit.so.1
が見つからなくなってしまっているように見える。
libaudit.so.1.0.0
はライブラリの実態で、ここを書き換えられるとどうしようにもないけれど、libaudit.so.1
は単なるシンボリックリンクに過ぎない。
といったことを考えた。
シンボリックリンクを張る
こんな感じで、適当な場所にシンボリックリンクを張る。 今回は一般ユーザのホームディレクトリ直下に張ってみた。
$ ln -s /lib/x86_64-linux-gnu/libaudit.so.1.0.0 libaudit.so.1 $ ls ダウンロード デスクトップ ビデオ ミュージックlibaudit.so.1 テンプレート ドキュメント ピクチャ 公開
シンボリックリンクを見るようにする
環境変数LD_LIBRARY_PATH
とLD_PRELOAD
を使ってなんとかならないかやってみた。
LD_LIBRARY_PATH
を使う
環境変数LD_LIBRARY_PATH
を使うことで、バイナリ実行時に動的ライブラリを探索するパスを追加することが可能になる。
以下のように、libaudit.so.1
が見つからなかったのが、見つかるようになったので動くようになるはずなのだが、やっぱり動かない。
$ ldd /bin/su linux-vdso.so.1 (0x00007fe4ee3b9000) libpam.so.0 => /lib/x86_64-linux-gnu/libpam.so.0 (0x00007fe4ee37f000) libpam_misc.so.0 => /lib/x86_64-linux-gnu/libpam_misc.so.0 (0x00007fe4ee37a000) libutil.so.1 => /lib/x86_64-linux-gnu/libutil.so.1 (0x00007fe4ee375000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fe4ee184000) libaudit.so.1 => not found libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fe4ee17e000) /lib64/ld-linux-x86-64.so.2 (0x00007fe4ee3ba000) $ export LD_LIBRARY_PATH=./:$LD_LIBRARY_PATH $ ldd /bin/su linux-vdso.so.1 (0x00007ffe16fd6000) libpam.so.0 => /lib/x86_64-linux-gnu/libpam.so.0 (0x00007f1c13374000) libpam_misc.so.0 => /lib/x86_64-linux-gnu/libpam_misc.so.0 (0x00007f1c1336f000) libutil.so.1 => /lib/x86_64-linux-gnu/libutil.so.1 (0x00007f1c1336a000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f1c13179000) libaudit.so.1 => ./libaudit.so.1 (0x00007f1c1314d000) libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f1c13147000) /lib64/ld-linux-x86-64.so.2 (0x00007f1c133ab000) libcap-ng.so.0 => /lib/x86_64-linux-gnu/libcap-ng.so.0 (0x00007f1c1313d000) $ su - su: error while loading shared libraries: libaudit.so.1: cannot open shared object file: No such file or directory
LD_PRELOAD
を使う
環境変数 LD_PRELOAD
を使うことで、動的ライブラリの関数を置き換えることができる。
こっちを使ってみても、やっぱり動かない。
$ LD_PRELOAD=./libaudit.so.1 su - su: error while loading shared libraries: libaudit.so.1: cannot open shared object file: No such file or directory
なんで?
セキュリティ的なものが原因で、su(1)
のようなコマンドでは、LD_LIBRARY_PATH
やLD_PRELOAD
が無効にされてしまうらしい。
悪意のあるユーザがLD_LIBRARY_PATH
、LD_PRELOAD
を使って認証を回避してしまうようなライブラリによる差し替えを行うことを防ぐためらしい。
もちろん、PATH
などを置き換えることもできないらしい。
まぁ言われてみればそれはそうか。。。となるけれど、セキュアなプログラミングはきちんと身につけておきたい。。。