SUID 和 SGID 是 Linux 系統中重要的安全機制,允許使用者以檔案擁有者的許可權執行檔案,方便執行特定系統任務。然而,不當的 SUID/SGID 設定可能導致安全漏洞,允許惡意使用者提權。本文將探討 SUID/SGID 的設定方式、潛在風險以及如何有效管理這些許可權,包含使用 find 命令搜尋系統中所有 SUID/SGID 檔案,並示範如何利用 chmod 命令設定與移除 SUID/SGID。此外,文章也將介紹如何使用 nosuid 選項掛載分割區,限制 SUID/SGID 的使用範圍,以及如何利用擴充套件檔案屬性(例如 i 和 a 屬性)進一步保護敏感檔案,防止未經授權的修改和刪除。透過這些技巧,系統管理員可以更有效地管理 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 檔案
搜尋整個檔案系統中具有 SUID 或 SGID 的檔案:
sudo find / -type f -perm /6000 -ls > suid_sgid_files.txt登入其他使用者帳戶,建立一個虛擬 shell 指令碼,並設定 SUID 許可權:
su - other_user_account touch dummy_script.sh chmod 4755 dummy_script.sh ls -l dummy_script.sh exit再次執行
find命令,將結果儲存到不同的文字檔案:sudo find / -type f -perm /6000 -ls > suid_sgid_files_2.txt比較兩個檔案的差異:
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命令。您可以在一個檔案上設定多個屬性,但前提是它們是有意義的。例如,您不會在同一個檔案上同時設定a和i屬性,因為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.
內容解密:
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檔案的末尾。- 由於之前設定了
a屬性,該檔案只能被附加內容,而不能被覆寫或刪除。 - 因此,這次操作成功了,並沒有出現錯誤訊息。
除了無法覆寫該檔案外,我也無法刪除它:
[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)可用於增強檔案的安全性。其中,i 和 a 屬性尤其值得注意,因為它們能夠對檔案的修改、刪除等操作施加進一步的限制。
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
內容解密:
sudo chattr +i perm_demo.txt:為perm_demo.txt檔案新增i屬性,使其成為不可變檔案。lsattr perm_demo.txt:列出perm_demo.txt的擴充套件屬性,確認i屬性是否已設定。- 各種嘗試修改或刪除檔案的操作均會失敗,因為檔案具有不可變屬性。
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
內容解密:
sudo chattr +a perm_demo.txt:為檔案新增a屬性,使其僅允許追加內容。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:移除a屬性並新增i屬性,使檔案變為不可變。
實戰實驗:設定安全相關的擴充套件檔案屬性
- 使用你喜歡的文字編輯器建立一個名為
perm_demo.txt的檔案,並加入一行文字。 - 檢視該檔案的擴充套件屬性:
lsattr perm_demo.txt - 新增
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 - 移除
a屬性並新增i屬性,重複步驟 4,並嘗試重新命名檔案和建立硬連結。
系統組態檔案的安全保護
大多數 Linux 發行版的系統組態檔案屬於 root 使用者或特定的系統使用者,並且通常具有讀取和寫入許可權給其所有者,以及讀取許可權給其他使用者。這意味著所有登入系統的使用者都可以讀取這些組態檔案。
對於某些包含敏感資訊的組態檔案(如某些 PHP CMS 的組態檔案),限制其存取許可權至關重要。但對於其他不包含敏感資訊的組態檔案,是否需要嚴格限制存取許可權取決於伺服器的使用場景。
對於可被多個管理員或非管理員使用者遠端存取的伺服器,限制組態檔案的存取許可權可以減少潛在的安全風險。將組態檔案的許可權設為 600 可以確保只有檔案所有者能夠讀取和寫入。
可以使用 find 命令批次修改組態檔案的許可權:
sudo find / -iname '*.conf' -exec chmod 600 {} \;
內容解密:
sudo find / -iname '*.conf':在根目錄下查詢所有副檔名為.conf的檔案。-exec chmod 600 {} \;:對找到的每個.conf檔案執行chmod 600命令,將其許可權設為僅所有者可讀寫。
此命令能夠有效地保護系統組態檔案,防止未授權的存取,從而增強系統的安全性。