/dev/fd 如何使在 sudo 下執行的 shell 腳本安全?
在手冊頁的末尾
sudo
,有以下註釋:Running shell scripts via sudo can expose the same kernel bugs that make setuid shell scripts unsafe on some operating systems (if your OS has a /dev/fd/ directory, setuid shell scripts are generally safe).
那段中的幾乎所有內容對我來說都是模糊的。特別是,我想了解典故
/dev/fd
的全部內容。我試圖猜測一些可能的手冊頁,我可以在其中找到這些資訊,但我沒有找到。有什麼建議麼?
(如果可能的話,最終我想通過 cron 在 sudo 下執行一些腳本,但我當然擔心這種非監督式安排中可能存在的安全漏洞。)
我看不出這如何適用於
sudo
.對於 setuid 腳本,想法是這樣的:
假設您有一個
/usr/local/bin/myscript
setuid root 並以#! /bin/sh
./usr/local/bin
沒有人對or有寫權限myscript
,但任何人都可以:ln -s /usr/local/bin/myscript /tmp/-i
並且
/tmp/-i
還成為一個 setuid 腳本,即使您仍然沒有對它的寫訪問權,但您確實對/tmp
.在不通過 執行 setuid 腳本的系統上
/dev/fd
,當您執行時cd /tmp && -i
,setuid 位意味著它將/bin/sh -i
以 root 身份執行:
- 程序將euid更改為文件所有者
- 系統解析shebang
- 系統執行(仍以 root 身份),
/bin/sh -i
現在,對於這種特殊情況,簡單的解決方法是按照推薦的方式編寫 shebang:
#! /bin/sh -
,但即便如此,仍然存在競爭條件。現在它變成了:
- 程序將euid更改為文件所有者
- 系統解析shebang
- 系統執行(仍以 root 身份),
/bin/sh - -i
- “sh”在目前目錄中打開“-i”文件(你會想的很好)。
但是在上面的 3 和 4 之間,你有足夠的時間將“-i”或(“any-file”,因為它是不同的攻擊向量)更改為一些邪惡的“-i”文件,例如只包含“sh”你得到一個 root shell(對於一個 setuid root 腳本)。
對於舊版本
ksh
,您甚至不需要這樣做,因為在 4 中,ksh 首先在 中查找“-i”$PATH
,因此將您的邪惡“-i”放入$PATH
(ksh
將打開那個而不是那個)就足夠了中/tmp
)。如果你這樣做,所有這些攻擊向量都是固定的:
cd /tmp; -i
,系統改為(仍在 execve 系統呼叫中):
- 原子地:找出文件是 setuid 並在程序的某個文件描述符上打開文件
x
。- 處理對文件所有者的 euid 更改。
- 跑
/bin/sh /dev/fd/x
sh
打開/dev/fd/x
只能引用execve
d 的文件。關鍵是該文件是作為 execve 的一部分打開的,因此我們知道它是具有受信任內容的程式碼,它將以更改的權限進行解釋。
現在這並不適用,
sudo
因為該sudo
策略基於path
.如果
sudo
規則說您可以以 root 身份執行 /usr/local/bin/myscript,那麼您可以執行以下操作:sudo /usr/local/bin/myscript
但你不能這樣做:
sudo /tmp/any-file
即使“任何文件”是指向
/usr/local/bin/myscript
.sudo
不使用/dev/fd
AFAICT。