如何防止 chgrp 清除「setuid 位元」?

如何防止 chgrp 清除「setuid 位元」?

我們有基於 RH 的 Linux 鏡像;我必須「應用」一些「特殊存檔」才能將它們升級到我們產品的最新開發版本。

建立存檔的人認為在我們的基礎映像中,某些權限是錯誤的;所以我們被告知要跑

sudo chgrp -R nobody /whatever

我們做到了;後來,當我們的應用程式運行時,出現了一些不起眼的問題。

我後來發現:調用chgrp將要清除/whatever 中二進位檔案的 setuid 位元資訊。

實際的問題是:我們的一些二進位文件必須設定 setuid 位元才能正常運作。

長話短說:有沒有辦法執行「chgrp」指令沒有殺死我的 setuid 位?

我剛剛在本地 Ubuntu 上運行了以下命令;導致相同的結果:

mkdir sticky
cd sticky/
touch blub
chmod 4755 blub 
ls -al blub 

--> 顯示紅色背景的檔名 --> 所以,是的,setuid

chgrp -R myuser .
ls -al blub 

--> 顯示沒有紅色背景的檔案名稱 --> setuid 消失了

答案1

如果您想chgrp -R nobody /whatever在保留 setuid 位元的同時實現您可以使用這兩個find命令

find /whatever ! -type l -perm -04000 -exec chgrp nobody {} + \
                                      -exec chmod u+s {} +
find /whatever ! -type l ! -perm -04000 -exec chgrp nobody {} +

find ... -perm 04000選項拾取設定了 setuid 位元的檔案。然後,第一個指令套用 a chgrp,然後套用 achmod來恢復已取消的 setuid 位元。第二個適用chgrp於所有沒有 setuid 位元的檔案。

在任何情況下,您都不想在符號連結上調用chgrp或 ,chmod因為這會影響它們的目標,因此! -type l.

答案2

清除chgrp(或chown)上的 SUID 和 SGID 位元是完全合理的。這是為了防止安全問題而採取的安全措施。對於 SGID(我認為是在可執行檔上)意味著使用群組所有者的有效群組運行此程序

如果您變更群組擁有者,那麼就安全性和存取控製而言,這是完全不同的,即uvw程式現在使用 effective group 運行,而不是使用 effective group 運行xyz

因此,您必須在所有權變更時明確還原 SUID 或 SGID 位元。

附錄:關於 chgrp(或 chown)應該只清除 SGID(或 SUID)的主張

透過chowning 或chgrping,您可以更改可執行檔的安全性設置,這足以清除任何特權提升屬性。 Unix 的強大源自於概念的簡單性,而 Unix 的安全性已經相當棘手。為此,在任何所有權變更時刪除 SUID 和 SGID 只是一個安全網 - 畢竟,在 Unix/Linux 的歷史上,由於錯誤的 SUID 或 SGID 設定而存在相當多的漏洞。

所以 Unix 的行為方式沒有更深層的原因,這只是一個保守的設計決策。

答案3

setuid非目錄上的,位元(至少在 Linux 上)的清除setgid是由核心在chown()完成系統呼叫時完成的chgrp,而不是由其chgrp本身完成。所以唯一的辦法就是事後恢復。

它還清除了安全功能。

所以,在 GNU Linux 上:

chown_preserve_sec() (
  newowner=${1?}; shift
  for file do
    perms=$(stat -Lc %a -- "$file") || continue
    cap=$(getfattr -m '^security\.capability$' --dump -- "$file") || continue
    chown -- "$newowner" "$file" || continue
    [ -z "$cap" ] || printf '%s\n' "$cap" | setfattr --restore=-
    chmod -- "$perms" "$file"
  done
)

並運行(如root):

chown_preseve_sec :newgroup file1 file2...

更改群組,同時嘗試保留權限。

遞歸地,你可以這樣做:

# save permissions (and ACLs). Remove the "# owner" and "# group" lines
# to prevent them being restored!
perms=$(getfacl -RPn . | grep -vE '^# (owner|group): ')
# save capabilities
cap=$(getfattr -Rhm '^security\.capability$' --dump .)

chgrp -RP nobody .

# restore permissions, ACLs and capabilities
printf '%s\n' "$perms" | setfacl --restore=-
[ -z  "$cap" ] || printf '%s\n' "$cap" | setfattr -h --restore=-

(這都是假設沒有其他情況同時破壞文件的情況)。

答案4

像往常一樣,在管理方面有很多方法可以走。

我提出的解決方案是這樣的:

cd /home/me
getfacl -R /whatever > whatever-permissions.org 2> /dev/null

# A) change lines starting with      # group: root
# to                                 # group: whatineed
sed 's/^# group: root/# group: whatineed/g' whatever-permissions.org > whatever-permissions.new

# B) change lines with               group::x.y
# to                                 group::xwy
# (where x, y mean: whatever was there before)
sed 's/^group::\(.\).\(.\)/group::\1w\2/g' whatever-permissions.new > whatever-permissions.new

cd /
setfacl --restore /home/me/whatever-permissions.new

相關內容