返回文章列表

Linux 系統 SUID 與 SGID 許可權安全管理

本文探討 Linux 系統中 SUID 和 SGID 特殊許可權的設定、風險及管理方法,涵蓋如何使用 find 命令查詢具有 SUID/SGID 的檔案、利用 chattr 命令設定擴充套件屬性 `i` 和 `a` 保護敏感檔案,以及如何透過 nosuid

系統管理 資安

SUID 和 SGID 是 Linux 系統中重要的安全機制,允許使用者以檔案擁有者的許可權執行檔案,方便執行特定系統任務。然而,不當的 SUID/SGID 設定可能導致安全漏洞,允許惡意使用者提權。本文將探討 SUID/SGID 的設定方式、潛在風險以及如何有效管理這些許可權,包含使用 find 命令搜尋系統中所有 SUID/SGID 檔案,並示範如何利用 chmod 命令設定與移除 SUID/SGID。此外,文章也將介紹如何使用 nosuid 選項掛載分割區,限制 SUID/SGID 的使用範圍,以及如何利用擴充套件檔案屬性(例如 ia 屬性)進一步保護敏感檔案,防止未經授權的修改和刪除。透過這些技巧,系統管理員可以更有效地管理 SUID/SGID 許可權,提升 Linux 系統的整體安全性。

管理 SUID 和 SGID 許可權以增強 Linux 系統安全

在 Linux 系統中,SUID(Set User ID)和 SGID(Set Group ID)是一種特殊許可權,允許使用者以檔案擁有者或群組的許可權執行檔案。雖然這些許可權對於某些系統操作是必要的,但它們也可能帶來安全風險,尤其是當使用者在非系統檔案上設定這些許可權時。

SUID 和 SGID 許可權的安全風險

當入侵者找到一個屬於 root 使用者且具有 SUID 許可權的可執行檔案時,他們可以利用它來破壞系統。在離開之前,他們可能會留下一份屬於 root 的檔案並設定 SUID 許可權,以便下次輕易進入系統。即使原始問題已經修復,如果入侵者的 SUID 檔案未被發現,他們仍將擁有存取許可權。

設定 SUID 和 SGID 許可權

SUID 的數值為 4000,SGID 的數值為 2000。要在檔案上設定 SUID,只需將 4000 新增至原本的許可權值。例如,如果一個檔案的許可權值為 755,則設定 SUID 後的許可權值將變為 4755。

# 原始許可權
ls -l example.sh
# -rwxr-xr-x 1 user user 0 Nov 7 13:06 example.sh

# 設定 SUID
chmod 4755 example.sh
ls -l example.sh
# -rwsr-xr-x 1 user user 0 Nov 7 13:06 example.sh

內容解密:

  • chmod 4755 example.sh:將 example.sh 的許可權變更為 4755,其中 4 代表 SUID。
  • ls -l example.sh:顯示 example.sh 的詳細資訊,包括許可權。

尋找系統中的 SUID 和 SGID 檔案

使用 find 命令可以快速找出系統中所有具有 SUID 或 SGID 許可權的檔案,並將結果儲存到文字檔案中,以便稍後比較是否有新增的檔案。

sudo find / -type f \( -perm -4000 -o -perm -2000 \) -ls > suid_sgid_files.txt

內容解密:

  • sudo find / -type f \( -perm -4000 -o -perm -2000 \) -ls:尋找根目錄下所有具有 SUID(4000)或 SGID(2000)許可權的檔案,並顯示詳細資訊。
  • -type f:僅搜尋檔案。
  • -perm -4000-perm -2000:搜尋具有 SUID 和 SGID 許可權的檔案。
  • -ls:顯示符合條件的檔案的詳細資訊。
  • > suid_sgid_files.txt:將結果儲存到 suid_sgid_files.txt

簡化命令

由於 4000 + 2000 = 6000,可以使用以下簡化命令:

sudo find / -type f -perm /6000 -ls > suid_sgid_files.txt

內容解密:

  • -perm /6000:搜尋具有 SUID 或 SGID 許可權的檔案,等同於 -perm -4000 -o -perm -2000

練習實驗室:搜尋 SUID 和 SGID 檔案

  1. 搜尋整個檔案系統中具有 SUID 或 SGID 的檔案

    sudo find / -type f -perm /6000 -ls > suid_sgid_files.txt
    
  2. 登入其他使用者帳戶,建立一個虛擬 shell 指令碼,並設定 SUID 許可權

    su - other_user_account
    touch dummy_script.sh
    chmod 4755 dummy_script.sh
    ls -l dummy_script.sh
    exit
    
  3. 再次執行 find 命令,將結果儲存到不同的文字檔案

    sudo find / -type f -perm /6000 -ls > suid_sgid_files_2.txt
    
  4. 比較兩個檔案的差異

    diff suid_sgid_files.txt suid_sgid_files_2.txt
    

圖表說明:SUID 和 SGID 設定流程圖

@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

title Linux 系統 SUID 與 SGID 許可權安全管理

package "資料庫架構" {
    package "應用層" {
        component [連線池] as pool
        component [ORM 框架] as orm
    }

    package "資料庫引擎" {
        component [查詢解析器] as parser
        component [優化器] as optimizer
        component [執行引擎] as executor
    }

    package "儲存層" {
        database [主資料庫] as master
        database [讀取副本] as replica
        database [快取層] as cache
    }
}

pool --> orm : 管理連線
orm --> parser : SQL 查詢
parser --> optimizer : 解析樹
optimizer --> executor : 執行計畫
executor --> master : 寫入操作
executor --> replica : 讀取操作
cache --> executor : 快取命中

master --> replica : 資料同步

note right of cache
  Redis/Memcached
  減少資料庫負載
end note

@enduml

圖表翻譯: 上圖展示了檢查和設定 SUID/SGID 許可權的流程。首先檢查檔案是否已設定相關許可權,若未設定則進行設定,若已設定則進行安全性檢查。如果發現可疑檔案,則進行移除或修正,最後完成流程。

防止SUID和SGID在分割區上被使用

如前所述,您不希望使用者將SUID和SGID賦予他們建立的檔案,因為這會帶來安全風險。您可以使用nosuid選項掛載分割區,以防止SUID和SGID被使用。因此,我在前一章中建立的luks分割區在/etc/fstab檔案中的條目將如下所示:

/dev/mapper/luks-6cbdce17-48d4-41a1-8f8e-793c0fa7c389 /secrets xfs nosuid 0 0

不同的Linux發行版在安裝作業系統期間有不同的設定預設分割區方案的方式。大多數情況下,預設的做法是將所有目錄(除了/boot/目錄)放在/分割區下。如果您要設定自訂的分割區方案,則可以將/home/目錄放在其自己的分割區中,並在該分割區上設定nosuid選項。請記住,您不希望為/分割區設定nosuid,否則您的作業系統將無法正常運作。

使用擴充套件檔案屬性保護敏感檔案

擴充套件檔案屬性是另一種可以幫助您保護敏感檔案的工具。它們無法阻止入侵者存取您的檔案,但可以幫助您防止敏感檔案被更改或刪除。有相當多的擴充套件屬性,但我們只需要檢視與檔案安全相關的那些屬性。

首先,讓我們使用lsattr命令檢視我們已經設定的擴充套件屬性。在CentOS或AlmaLinux機器上,您的輸出將如下所示:

[donnie@localhost ~]$ lsattr
---
-
---
-
---
-
---
- ./yum_list.txt
---
-
---
-
---
-
---
- ./perm_demo.txt
---
-
---
-
---
-
---
- ./perm_demo_dir
---
-
---
-
---
-
---
- ./donnie_script.sh
---
-
---
-
---
-
---
- ./suid_sgid_files.txt
---
-
---
-
---
-
---
- ./suid_sgid_files2.txt
[donnie@localhost ~]$

到目前為止,我沒有在任何檔案上設定任何擴充套件屬性。

在Ubuntu機器上,輸出將如下所示:

donnie@ubuntu:~$ lsattr
---
-
---
-
---
--e-- ./file2.txt
---
-
---
-
---
--e-- ./secret_stuff_dir
---
-
---
-
---
--e-- ./secret_stuff_for_frank.txt.gpg
---
-
---
-
---
--e-- ./good_stuff
---
-
---
-
---
--e-- ./secret_stuff
---
-
---
-
---
--e-- ./not_secret_for_frank.txt.gpg
---
-
---
-
---
--e-- ./file4.txt
---
-
---
-
---
--e-- ./good_stuff_dir
donnie@ubuntu:~$

我們不會擔心e屬性,因為它只表示該分割區是以ext4檔案系統格式化的。CentOS和AlmaLinux沒有設定該屬性,因為它們的分割區是以XFS檔案系統格式化的。

本文中我們將檢視的兩個屬性如下:

  • a:您可以將文字附加到具有此屬性的檔案末尾,但無法覆寫它。只有具有適當的sudo許可權的人才能設定或刪除此屬性。
  • i:這使得檔案不可變,只有具有適當的sudo許可權的人才能設定或刪除它。具有此屬性的檔案無法被刪除或以任何方式更改。也無法建立指向具有此屬性的檔案的硬連結。

要設定或刪除屬性,您需要使用chattr命令。您可以在一個檔案上設定多個屬性,但前提是它們是有意義的。例如,您不會在同一個檔案上同時設定ai屬性,因為i將覆寫a

讓我們開始建立perm_demo.txt檔案,其中包含以下文字:

This is Donnie's sensitive file that he doesn't want to have overwritten.

現在,讓我們繼續設定屬性。

設定a屬性

現在,我將設定a屬性:

[donnie@localhost ~]$ sudo chattr +a perm_demo.txt
[sudo] password for donnie:
[donnie@localhost ~]$

您使用+來新增屬性,使用-來刪除它。同樣,無論該檔案屬於我且位於我的主目錄中,我仍然需要sudo許可權才能新增或刪除此屬性。

現在,讓我們看看當我嘗試覆寫此檔案時會發生什麼:

[donnie@localhost ~]$ echo "I want to overwrite this file." > perm_demo.txt
-bash: perm_demo.txt: Operation not permitted
[donnie@localhost ~]$ sudo echo "I want to overwrite this file." > perm_demo.txt
-bash: perm_demo.txt: Operation not permitted
[donnie@localhost ~]$

無論是否具有sudo許可權,我都無法覆寫它。那麼,如果我嘗試將內容附加到它呢?

[donnie@localhost ~]$ echo "I want to append this to the end of the file." >> perm_demo.txt
[donnie@localhost ~]$

這次沒有錯誤訊息。讓我們看看檔案中的內容:

This is Donnie's sensitive file that he doesn't want to have overwritten.
I want to append this to the end of the file.

內容解密:

  1. echo "I want to append this to the end of the file." >> perm_demo.txt:這行命令嘗試將字串"I want to append this to the end of the file.“附加到perm_demo.txt檔案的末尾。
  2. 由於之前設定了a屬性,該檔案只能被附加內容,而不能被覆寫或刪除。
  3. 因此,這次操作成功了,並沒有出現錯誤訊息。

除了無法覆寫該檔案外,我也無法刪除它:

[donnie@localhost ~]$ rm perm_demo.txt
rm: cannot remove ‘perm_demo.txt’: Operation not permitted
[donnie@localhost ~]$ sudo rm perm_demo.txt
[sudo] password for donnie:
rm: cannot remove ‘perm_demo.txt’: Operation not permitted
[donnie@localhost ~]$

因此,a屬性生效了。但是,我已經決定不再需要這個屬性,所以我將刪除它:

[donnie@localhost ~]$ sudo chattr -a perm_demo.txt
[donnie@localhost ~]$ lsattr perm_demo.txt
---
-
---
-
---
-
---
- perm_demo.txt
[donnie@localhost ~]$

設定i屬性

(待續)

檔案擴充套件屬性與系統安全

在 Linux 系統中,除了傳統的檔案許可權外,還有擴充套件屬性(Extended Attributes)可用於增強檔案的安全性。其中,ia 屬性尤其值得注意,因為它們能夠對檔案的修改、刪除等操作施加進一步的限制。

i 屬性:不可變屬性

當一個檔案被設定為 i 屬性(不可變),它將變得無法被修改、移動、刪除或重新命名,甚至無法建立硬連結。讓我們來測試一下:

sudo chattr +i perm_demo.txt
lsattr perm_demo.txt

執行上述命令後,perm_demo.txt 檔案將無法被修改或刪除,無論是使用一般許可權還是 sudo 許可權:

sudo echo "I want to overwrite this file." > perm_demo.txt
# -bash: perm_demo.txt: Permission denied

echo "I want to append this to the end of the file." >> perm_demo.txt
# -bash: perm_demo.txt: Permission denied

rm -f perm_demo.txt
# rm: cannot remove ‘perm_demo.txt’: Operation not permitted

sudo rm -f perm_demo.txt
# rm: cannot remove ‘perm_demo.txt’: Operation not permitted

要移除 i 屬性,可以使用以下命令:

sudo chattr -i perm_demo.txt
lsattr perm_demo.txt

內容解密:

  1. sudo chattr +i perm_demo.txt:為 perm_demo.txt 檔案新增 i 屬性,使其成為不可變檔案。
  2. lsattr perm_demo.txt:列出 perm_demo.txt 的擴充套件屬性,確認 i 屬性是否已設定。
  3. 各種嘗試修改或刪除檔案的操作均會失敗,因為檔案具有不可變屬性。
  4. sudo chattr -i perm_demo.txt:移除 i 屬性,使檔案還原可修改狀態。

a 屬性:僅可追加屬性

i 屬性不同,a 屬性允許對檔案進行追加操作,但禁止修改或刪除檔案內容。設定 a 屬性的示例如下:

sudo chattr +a perm_demo.txt
lsattr perm_demo.txt

此時,你可以向檔案追加內容,但無法覆寫或刪除檔案:

echo "I want to append this line to the end of the file." >> perm_demo.txt
# 成功追加內容

sudo chattr -a perm_demo.txt
sudo chattr +i perm_demo.txt

內容解密:

  1. sudo chattr +a perm_demo.txt:為檔案新增 a 屬性,使其僅允許追加內容。
  2. echo "I want to append this line to the end of the file." >> perm_demo.txt:成功向檔案追加內容。
  3. sudo chattr -a perm_demo.txtsudo chattr +i perm_demo.txt:移除 a 屬性並新增 i 屬性,使檔案變為不可變。

實戰實驗:設定安全相關的擴充套件檔案屬性

  1. 使用你喜歡的文字編輯器建立一個名為 perm_demo.txt 的檔案,並加入一行文字。
  2. 檢視該檔案的擴充套件屬性:lsattr perm_demo.txt
  3. 新增 a 屬性並檢視結果:sudo chattr +a perm_demo.txtlsattr perm_demo.txt
  4. 嘗試覆寫和刪除檔案,確認操作是否被禁止。
  5. 追加內容到檔案:echo "I want to append this line to the end of the file." >> perm_demo.txt
  6. 移除 a 屬性並新增 i 屬性,重複步驟 4,並嘗試重新命名檔案和建立硬連結。

系統組態檔案的安全保護

大多數 Linux 發行版的系統組態檔案屬於 root 使用者或特定的系統使用者,並且通常具有讀取和寫入許可權給其所有者,以及讀取許可權給其他使用者。這意味著所有登入系統的使用者都可以讀取這些組態檔案。

對於某些包含敏感資訊的組態檔案(如某些 PHP CMS 的組態檔案),限制其存取許可權至關重要。但對於其他不包含敏感資訊的組態檔案,是否需要嚴格限制存取許可權取決於伺服器的使用場景。

對於可被多個管理員或非管理員使用者遠端存取的伺服器,限制組態檔案的存取許可權可以減少潛在的安全風險。將組態檔案的許可權設為 600 可以確保只有檔案所有者能夠讀取和寫入。

可以使用 find 命令批次修改組態檔案的許可權:

sudo find / -iname '*.conf' -exec chmod 600 {} \;

內容解密:

  1. sudo find / -iname '*.conf':在根目錄下查詢所有副檔名為 .conf 的檔案。
  2. -exec chmod 600 {} \;:對找到的每個 .conf 檔案執行 chmod 600 命令,將其許可權設為僅所有者可讀寫。

此命令能夠有效地保護系統組態檔案,防止未授權的存取,從而增強系統的安全性。