1. 程式人生 > >Linux 特殊許可權 SUID,SGID,SBIT

Linux 特殊許可權 SUID,SGID,SBIT

setuid 和 setgid 分別是 set uid ID upon execution 和 set group ID upon execution 的縮寫。我們一般會再次把它們縮寫為 suid 和 sgid。它們是控制檔案訪問的許可權標誌(flag),它們分別允許使用者以可執行檔案的 owner 或 owner group 的許可權執行可執行檔案。
說明:本文的演示環境為 ubuntu 16.04。

SUID

在 Linux 中,所有賬號的密碼記錄在 /etc/shadow 這個檔案中,並且只有 root 可以讀寫入這個檔案:

如果另一個普通賬號 tester 需要修改自己的密碼,就要訪問 /etc/shadow 這個檔案。但是明明只有 root 才能訪問 /etc/shadow 這個檔案,這究竟是如何做到的呢?事實上,tester 使用者是可以修改 /etc/shadow 這個檔案內的密碼的,就是通過 SUID 的功能。讓我們看看 passwd 程式檔案的許可權資訊:

上圖紅框中的許可權資訊有些奇怪,owner 的資訊為 rws 而不是 rwx。當 s 出現在檔案擁有者的 x 許可權上時,就被稱為 SETUID BITS 或 SETUID ,其特點如下:

  • SUID 許可權僅對二進位制可執行檔案有效
  • 如果執行者對於該二進位制可執行檔案具有 x 的許可權,執行者將具有該檔案的所有者的許可權
  • 本許可權僅在執行該二進位制可執行檔案的過程中有效

下面我們來看 tester 使用者是如何利用 SUID 許可權完成密碼修改的:

  1. tester 使用者對於 /usr/bin/passwd 這個程式具有執行許可權,因此可以執行 passwd 程式
  2. passwd 程式的所有者為 root
  3. tester 使用者執行 passwd 程式的過程中會暫時獲得 root 許可權
  4. 因此 tester 使用者在執行 passwd 程式的過程中可以修改 /etc/shadow 檔案

但是如果由 tester 使用者執行 cat 命令去讀取 /etc/shadow 檔案確是不行的:

原因很清楚,tester 使用者沒有讀 /etc/shadow 檔案的許可權,同時 cat 程式也沒有被設定 SUID。我們可以通過下圖來理解這兩種情況:

如果想讓任意使用者通過 cat 命令讀取 /etc/shadow 檔案的內容也是非常容易的,給它設定 SUID 許可權就可以了:

$ sudo chmod 4755 /bin/cat

現在 cat 已經具有了 SUID 許可權,試試看,是不是已經可以 cat 到 /etc/shadow 的內容了。因為這樣做非常不安全,所以趕快通過下面的命令把 cat 的 SUID 許可權移除掉:

$ sudo chmod 755 /bin/cat

SGID

當 s 標誌出現在使用者組的 x 許可權時稱為 SGID。SGID 的特點與 SUID 相同,我們通過 /usr/bin/mlocate 程式來演示其用法。mlocate 程式通過查詢資料庫檔案 /var/lib/mlocate/mlocate.db 實現快速的檔案查詢。 mlocate 程式的許可權如下圖所示:

很明顯,它被設定了 SGID 許可權。下面是資料庫檔案 /var/lib/mlocate/mlocate.db 的許可權資訊:很明顯,它被設定了 SGID 許可權。下面是資料庫檔案 /var/lib/mlocate/mlocate.db 的許可權資訊:

普通使用者 tester 執行 mlocate 命令時,tester 就會獲得使用者組 mlocate 的執行許可權,又由於使用者組 mlocate 對 mlocate.db 具有讀許可權,所以 tester 就可以讀取 mlocate.db 了。程式的執行過程如下圖所示:

除二進位制程式外,SGID 也可以用在目錄上。當一個目錄設定了 SGID 許可權後,它具有如下功能:

  1. 使用者若對此目錄具有 r 和 x 許可權,該使用者能夠進入該目錄
  2. 使用者在此目錄下的有效使用者組將變成該目錄的使用者組
  3. 若使用者在此目錄下擁有 w 許可權,則使用者所建立的新檔案的使用者組與該目錄的使用者組相同

下面看個例子,建立 testdir 目錄,目錄的許可權設定如下:

此時目錄 testdir 的 owner 是 nick,所屬的 group 為 tester。
先建立一個名為 nickfile 的檔案:

這個檔案的許可權看起來沒有什麼特別的。然後給 testdir 目錄設定 SGID 許可權:

$ sudo chmod 2775 testdir

然後再建立一個檔案 nickfile2:

新建的檔案所屬的組為 tester!

總結一下,當 SGID 作用於普通檔案時,和 SUID 類似,在執行該檔案時,使用者將獲得該檔案所屬組的許可權。當 SGID 作用於目錄時,意義就非常重大了。當用戶對某一目錄有寫和執行許可權時,該使用者就可以在該目錄下建立檔案,如果該目錄用 SGID 修飾,則該使用者在這個目錄下建立的檔案都是屬於這個目錄所屬的組。

SBIT

其實 SBIT 與 SUID 和 SGID 的關係並不大。
SBIT 是 the  restricted  deletion  flag  or  sticky  bit 的簡稱。
SBIT 目前只對目錄有效,用來阻止非檔案的所有者刪除檔案。比較常見的例子就是 /tmp 目錄:

許可權資訊中最後一位 t 表明該目錄被設定了 SBIT 許可權。SBIT 對目錄的作用是:當用戶在該目錄下建立新檔案或目錄時,僅有自己和 root 才有權力刪除。

設定 SUID、SGID、SBIT 許可權

以數字的方式設定許可權
SUID、SGID、SBIT 許可權對應的數字如下:

SUID->4
SGID->2
SBIT->1

所以如果要為一個檔案許可權為 "-rwxr-xr-x" 的檔案設定 SUID 許可權,需要在原先的 755 前面加上 4,也就是 4755:

$ chmod 4755 filename

同樣,可以用 2 和 1 來設定 SGID 和 SBIT 許可權。設定完成後分別會用 s, s, t 代替檔案許可權中的 x。

其實,還可能出現 S 和 T 的情況。S 和 t 是替代 x 這個許可權的,但是,如果它本身沒有 x 這個許可權,新增 SUID、SGID、SBIT 許可權後就會顯示為大寫 S 或大寫 T。比如我們為一個許可權為 666 的檔案新增 SUID、SGID、SBIT 許可權:

執行 chmod 7666 nickfile,因為 666 表示 "-rw-rw-rw",均沒有 x 許可權,所以最後變成了 "-rwSrwSrwT"。

通過符號型別改變許可權

除了使用數字來修改許可權,還可以使用符號:

$ chmod u+s testfile # 為 testfile 檔案加上 SUID 許可權。
$ chmod g+s testdir  # 為 testdir 目錄加上 SGID 許可權。
$ chmod o+t testdir  # 為 testdir 目錄加上 SBIT 許可權。

總結

SUID、SGID、SBIT 許可權都是為了實現特殊功能而設計的,其目的是彌補 ugo 許可權無法實現的一些使用場景。