歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> Linux教程 >> Linux權限360度赤裸裸華麗麗大曝光連載之二:深入理解SetUID

Linux權限360度赤裸裸華麗麗大曝光連載之二:深入理解SetUID

日期:2017/2/28 16:14:30   编辑:Linux教程

本文為Linux權限系列文章的第二篇,計劃總計三篇終結。

相關閱讀:

Linux權限360度赤裸裸華麗麗大曝光連載之一:從ls開始 http://www.linuxidc.com/Linux/2011-05/36487.htm

Linux權限360度赤裸裸華麗麗大曝光連載之二:深入理解SetUID http://www.linuxidc.com/Linux/2011-05/36488.htm

Linux權限360度赤裸裸華麗麗大曝光連載之三:查缺補漏 http://www.linuxidc.com/Linux/2011-05/36489.htm

在Linux系統中每個普通用戶都可以更改自己的密碼,這是合理的設置。問題是:用戶的信息保存在文件/etc/passwd中,用戶的密碼保存在文件/etc/shadow中,也就是說用戶更改自己密碼時是修改了/etc/shadow文件中的加密密碼,但是,LOOK——

-rw-r--r-- 1 root root 1787 Oct 27 2009 /etc/passwd

-r-------- 1 root root 1187 Oct 27 2009 /etc/shadow

/etc/passwd文件每個用戶都有讀權限但是只有root有寫權限,/etc/shadow文件只有超級用戶root有讀寫權限,也就是說普通用戶對這兩個文件都沒有寫權限無法寫入新密碼,為什麼普通用戶可以更改密碼呢?

PS:Linux中設置或更改用戶密碼,是先寫入到/etc/passwd文件然後通過pwconv命令轉換到/etc/shadow文件,執行pwunconv命令可觀察到轉換前效果,會觀察到/etc/shadow文件神奇的消失掉了,而/etc/passwd文件中原來打x的地方變成了真正的加密密碼。

其實,用戶能更改密碼真正的秘密不在於文件的權限,而在於更改密碼的命令passwd 。

-rwsr-xr-x 1 root root 22960 Jul 17 2006 /usr/bin/passwd

passwd命令有一個特殊的權限標記s ,存在於文件所有者的權限位上。這是一類特殊的權限SetUID ,可以這樣來理解它:當一個具有執行權限的文件設置SetUID權限後,用戶執行這個文件時將以文件所有者的身份執行。passwd命令具有SetUID權限,所有者為root(Linux中的命令默認所有者都是root),也就是說當普通用戶使用passwd更改自己密碼的時候,那一瞬間突然靈魂附體了,實際在以passwd命令所有者root的身份在執行,root當然可以將密碼寫入/etc/shadow文件(不要忘記root這個家伙是superuser什麼事都可以干),命令執行完成後該身份也隨之消失。

可以試驗用root身份修改passwd命令權限去掉SetUID :

chmod u-s /usr/bin/passwd

再嘗試以普通用戶身份登錄後修改密碼,就會發現提示:

passwd

Changing password for user samlee.

Changing password for samlee

(current) UNIX password:

passwd: Authentication token manipulation error

普通用戶無法修改密碼,所以只要能夠想明白為什麼普通用戶可以更改密碼就可以大概了解SetUID權限的作用。

接下來我們用兩個SetUID的按理來進一步诠釋下它的概念——

案例一:SetUID授權示例

為便於深入理解SetUID ,筆者以touch命令為例做一演示。

普通用戶samlee用touch創建文件newfile01 :

touch newfile01

ls -l newfile01

-rw-rw-r-- 1 samlee samlee 0 05-21 01:20 newfile01

文件的創建者默認就是所有者,所以文件newfile01的所有者為samlee 。

管理員root給touch命令添加SetUID權限:

chmod u+s /bin/touch # 或 chmod 4755 /bin/touch

ls -l /bin/touch

-rwsr-xr-x 1 root root 42284 Jul 13 2009 /bin/touch

再用普通用戶samlee創建文件newfile02,看到如下結果:

touch newfile02

ls -l newfile02

-rw-rw-r-- 1 root samlee 0 05-21 01:48 newfile02

通過這個例子,我們可以再诠釋下SetUID的定義,當一個可執行文件(命令touch)設置SetUID權限後,當普通用戶samlee執行touch創建新文件時,實際上是以touch命令所有者root的身份在執行此操作,既然是以root身份執行,當然新建文件的所有者為root ,這就是SetUID的作用。

再看一下與SetUID類似的SetGID權限,看一個例子,給touch命令再授予SetGID :

chmod g+s /bin/touch # 或 chmod 6755 /bin/touch

ls -l /bin/touch

-rwsr-sr-x 1 root root 42284 Jul 13 2009 /bin/touch

此時,再使用touch創建新文件newfile03,會看到如下現象:

touch newfile03

ls -l newfile03

-rw-rw-r-- 1 root root 0 05-21 01:48 newfile02

新建文件的所屬組為touch命令的所屬組,而不是執行touch命令的普通用戶samlee的所屬組,這就是SetGID的作用,與SetUID類似,用戶在執行具有SetGID的命令時會調用命令所屬組的身份。

案例二:危險的SetUID

對於SetUID的使用,可以做一個的比喻:一個絕密機關,要讓一些人進來做一些事情,但是不能讓他們看見機關內部的情況,於是授權一些特殊的“車輛”(沒有窗戶,車門緊閉,看不到外面,只有一個小洞允許乘坐的人伸出手臂做事),帶著所乘坐的人開到要去的地方,允許它辦完事情馬上帶他出來。這樣是不是很安全?不一定。如果“車輛”沒有經過精挑細選,可能有很多“門窗”,那可就危險了,這種類似的場景相信大家在一些警匪電影中已經見過多次了。

普通用戶使用vi編輯/etc/shadow文件會提示“Permission Denied”,這是合理的設置,但是如果賦予vi以SetUID權限:

chmod u+s /bin/vi

ls -l /bin/vi

-rwsr-xr-x 1 root root 594740 Jun 12 2009 /bin/vi

此時,普通用戶使用vi即可以編輯/etc/shadow文件,因為具備root身份,可以進行任意讀寫操作(比如可以把任何一個用戶密碼位清空,則用戶登錄不需要輸入密碼)。但是使用more、cat等命令仍然無法查看文件/etc/shadow的內容,只有被授予了SetUID的vi可以查看和修改。同樣,vi如果具有了SetUID權限,普通用戶可以vi編輯/etc/passwd文件把自己的UID改為0 ,則他的權限就和root一樣;可以vi編輯/etc/inittab文件把缺省運行級別改成6 ,則Linux會開機後不停的重啟……

再來看一個令人不安的情況,用普通用戶嘗試關閉Apache服務:
ps -le | grep httpd

140 S 0 8916 1 0 76 0 - 3697 - ? 00:00:00 httpd

kill 8916

-bash: kill: (8916) - Operation not permitted

可以看到,普通用戶不可以關閉root啟動的進程,但是如果做下面一個動作:

chmod 6555 /bin/kill

現在當普通用戶執行kill時,因為kill被授予了SetUID權限,在執行的一瞬間具有了root權限,只要用戶不爽想關閉任何服務都可以!

所以,SetUID權限不能隨便設置,同時要防止黑客的惡意修改,怎樣避免SetUID的不安全影響,有幾點建議:
1. 關鍵目錄應嚴格控制寫權限。比如“/”、“/usr”等;
2. 用戶的密碼設置要足夠強壯,8位以上,大小寫字母、數字、符號的組合,如:Am@ri31n,且定期更換;
3. 對系統中應該具有SetUID權限的文件作一列表,定時檢查有沒有這之外的文件被設置了SetUID權限。

可以對系統中應該具有SetUID權限的文件作一列表,定時檢查有沒有非列表中的命令被設置了SetUID權限。
在Linux安裝部署完成後,執行下面命令生成SetUID列表文件:

mkdir /script # 創建目錄/script

find / -perm -4000 -o -perm -2000 > /script/setuid.list

命令find選項“-perm”為指定文件權限,SetUID權限位對應數字標識為4 ,SetGID權限位對應數字標識為2 ,後面寫為“000”標識對所有者所屬組其他人三類用戶的權限不限制;“-o”表示or,就是文件具有SetUID或者具有SetGID都在搜索之列,生成的搜索結果存放在文件/script/setuid.list中。

在需要對系統做檢查時,執行以下shell程序。也可以放在計劃任務中定時檢查。

/usr/bin/find / -perm -4000 -o -perm -2000 > /tmp/setuid.check

for file in `/bin/cat /tmp/setuid.check`

do

/bin/grep $file /script/setuid.list > /dev/null

if [ "$?" != "0" ]

then

echo "$file isn't in list! it's danger!!"

fi

done

/bin/rm /tmp/setuid.check
假設命令kill被設置了SetUID ,則會檢測提示:

/bin/kill isn't in list! it's danger!!

另外,如果在一些數據存放的分區想禁用SetUID功能,還可以做如下設置,編輯配置文件/etc/fstab ,找到要設置的分區(如/home)所對應的設置行:

vi /etc/fstab

LABEL=/home /home ext3 defaults 1 2

在設置“defaults”後,添加“nosuid”選項,並重新掛載/home分區:

vi /etc/fstab

LABEL=/home /home ext3 defaults,nosuid 1 2

mount -o remount /home

設置後,分區/home上任何可執行文件即使被設置了SetUID權限也無法執行(讀者可自行拷貝一個SetUID命令至/home目錄下執行試驗),在一些存放數據、用來備份等功能的分區上做此設置,可以保護系統安全。

友情提示:請您作完本文中的實驗後,別忘把文件的權限恢復原狀,以免帶來不必要的麻煩。

至此相信讀者已經對SetUID的作用有所了解,最後,還有一個大家要注意的問題,SetUID只針對具有可執行權限的文件有效,不具有x權限的文件被授予了SetUID會顯示標記為S(一下子由小s變成姐姐了),仔細想一下,如果沒有可執行權限的話設置SetUID無任何意義。

Copyright © Linux教程網 All Rights Reserved