在Linux系統中每一個普通用戶均可以更改本身的密碼,這是合理的設置。linux
問題是:用戶的信息保存在文件/etc/passwd中,用戶的密碼保存在文件/etc/shadow中,也就是說用戶更改本身密碼時是修改了/etc/shadow文件中的加密密碼,可是,shell
-rw-r--r-- 1 root root 1787 Oct 27 2009 /etc/passwd安全
-r-------- 1 root root 1187 Oct 27 2009 /etc/shadowbash
/etc/passwd文件每一個用戶都有讀權限可是隻有root有寫權限,/etc/shadow文件只有超級用戶root有讀寫權限,也就是說普通用戶對這兩個文件都沒有寫權限沒法寫入新密碼,爲何普通用戶能夠更改密碼呢?ui
PS:在linux中設置或更改用戶密碼,是先寫入到/etc/passwd文件而後經過pwconv命令轉換到/etc/shadow文件,執行pwunconv命令可觀察到轉換前效果,會觀察到/etc/shadow文件神奇的消失掉了,而/etc/passwd文件中原來打x的地方變成了真正的加密密碼。加密
其實,用戶能更改密碼真正的祕密不在於文件的權限,而在於更改密碼的命令passwd 。spa
-rwsr-xr-x 1 root root 22960 Jul 17 2006 /usr/bin/passwd.net
passwd命令有一個特殊的權限標記s ,存在於文件全部者的權限位上。這是一類特殊的權限SetUID ,能夠這樣來理解它:當一個具備執行權限的文件設置SetUID權限後,用戶執行這個文件時將以文件全部者的身份執行。passwd命令具備SetUID權限,全部者爲root(Linux中的命令默認全部者都是root),也就是說當普通用戶使用passwd更改本身密碼的時候,那一瞬間忽然靈魂附體了,實際在以passwd命令全部者root的身份在執行,root固然能夠將密碼寫入/etc/shadow文件(不要忘記root這個傢伙是superuser什麼事均可以幹),命令執行完成後該身份也隨之消失。token
能夠試驗用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文件會提示「PermissionDenied」,這是合理的設置,可是若是賦予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 | grephttpd
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無任何意義。