天天看點

特殊權限

SUID

談到SUID不得不說程序的安全上下文,那麼何為程序的安全上下文?在我看來,程序的安全上下文應該分成上文和下文。

我們先來談談程序安全的上文,我們都明白,使用者有是權限的,指令或者所有的檔案和目錄(在linux當中目錄實際上也是一個檔案哦!)也是有權限的,檔案的權限我們可以很直覺的通過ls指令看到:

[user1@A ~]$ ls -l /etc/passwd   #一個配置檔案的權限
-rw-r--r--. 1 root root 2466 9月   9 19:35 /etc/passwd
[user1@A ~]$ ls -ld /etc         #一個目錄的權限
drwxr-xr-x. 141 root root 8192 9月   9 19:36 /etc
[user1@A ~]$ ll `which cat`          #一個指令或者說是一個二進制程式檔案的權限
-rwsr-xr-x. 1 root root 54080 11月  6 2016 /bin/cat      

那麼使用者的權限怎樣了解和檢視呢?剛開始我雖然接受了使用者是有權限的理論,但是實際上并不完全了解,也不知道去哪裡檢視使用者有哪些權限,後來學習的時候長一點兒的時候,忽然想明白了,linux把使用者分類、分組實際就是一個權限的管理呀!!我們使用id指令檢視一個使用者的時候顯示的資訊其實就是使用者的權限。

[user1@A ~]$ id root ; id zhanghe
uid=0(root) gid=0(root) 組=0(root)
uid=1000(zhanghe) gid=1000(zhanghe) 組=1000(zhanghe),10(wheel)      

好了,終于把使用者和檔案的權限給說完了,可是這僅僅是一小步而已,距離把程序的安全的上文說明白還早呢!!繼續吧。我們在上面知道了使用者和檔案(包括指令的二進制檔案、正經檔案、目錄) 都是有權限的。那麼當一個使用者使用cat指令通路一個檔案的時候,作業系統内部的權限動作是怎樣的呢?正面我們就以一個最常用的案例來說明:

[user1@A ~]$ cat /etc/shadow

那麼我們就來分析分析一個普通使用者cat  /etc/shadow時作業系統内部的權限運作:當我們在終端當中的bash當中輸入cat /etc/shadow時,bash會對cat /etc/shadow這一段字元串進行分析,首先bash根據空格分析出哪一段是指令部分和參數部分,然後根據PATH環境變量分析出指令的部分是否正确,能在PATH變量當中查找到的就是認為正确的,如果bash沒有在PATH變量當中沒有找到指令部分的話就傳回”command not found……”,就像下面這樣:

[user1@A ~]$ dkjg   #這是随便輸入的
bash: dkjg: command not found...      

接下來,user1使用者就會根據PATH變量的路徑找到cat指令對應的二進制檔案位置。cat二進制檔案“感受“到有使用者來通路自己,就會根據自己inode檔案當中記錄的權限,首先核對一下來通路自己是不是屬主,如果是屬主的話就按照屬主的權限來運作,如果不是屬主那就核對一下來通路自己的這個使用者有沒有在屬組裡面,如果在屬組裡面話,就按照屬組的權限進行運作,如果來通路即不是屬主,也沒有包含在屬組裡面的話,那麼就按照其他人的權限進行運作。無論按照哪個權限,隻要是運作起來之後,這個原本靜态的程式就變成了動态的程序,并且這個程序也是帶有權限的,注意!注意!!注意!!!cat程序所攜帶的權限與原本的cat二進制程式檔案的權限一毛錢的關系也沒有,這個動态的、運作當中的程序所攜帶的權限是将其運作起來的那個使用者的權限,也就是說如果是user1使用者運作的cat指令,那麼cat程序所攜帶的權限就是user1所攜帶的權限。

到此,程序的安全上下文當中的上文就寫完了。

再補充一點知識之後再講程序安全上下文當中的下文部分。

如果你指令部分輸入正确了,但是參數部分你是胡亂輸入的話,那麼bash是不會去判斷你參數部分是不是輸入正确,你可能可以疑惑了,指令部分正确的輸入 ,但是參數部分胡亂輸入的話也是會報錯的呀?沒錯,這樣同樣也會報錯:“No such file or directory”,但是請你仔細看看,報錯并不是bash這個程式,而是你輸入的指令報錯的,就像下面這樣:

[user1@A ~]$ cd oiejg
-bash: cd: oiejg: No such file or directory   #真正報錯是cd這個指令,而不是bash程式。      

再說的詳細一點,當使用者運作cat時,bash會在PATH變量當中找到cat對應二進制檔案的絕對路徑(/bin/cat),送出給核心,核心會根據其路徑找到真正的cat指令在硬體當中的位址,然後把cat從硬體當中調用到核心當中的核心空間,然後再給cat程序配置設定真正在使用者空間的位址,接下來把cat程序放入到記憶體的的使用者空間,是以說真正的IO其實是兩個步驟。

好了,下面再說一下程序安全上下文當中的下文部分。

在上文我們講到了程序攜帶的權限其實是運作者的權限,是以當user1運作cat /etc/passwd的時,cat程序所攜帶的權限就是user1使用者的權限,然後cat程序再去通路/etc/passwd,同樣的,passwd檔案也是會根據inode當中記錄的權限對來通路的程序進行權限核對,發現user1不是passwd的屬主,也沒有在root組裡面(passwd檔案的屬主和屬組預設都是root),就按照其他人的權限通路(隻讀權限),是以普通使用者user1就成功用cat指令檢視到了passwd裡面的内容。

終于,終于把程序的安全上下文講完了,解釋起來有點麻煩,但是如果明白了之後,其實挺簡單的!程序安全上下文其實是為解釋SUID做鋪墊的,當您了解了程序的安全上下文之後再去了解SUID也變得非常的簡單了,其實一句話就可以了:“所謂的SUID其實就是打破了程序安全上下文當中的上文”。那麼是怎樣打破的呢?

當user1去執行cat /etc/passwd的時候,cat程序攜帶的權限其實是user1的權限,但是如果如果給cat賦予了SUID權限的話,那麼user1再運作cat指令的時候,一旦運作起來了之後,cat程序所攜帶的權限就是cat二進制檔案的權限,cat自己的權限屬主和屬組都是root,也就是說cat程序所攜帶的權限不是user1的權限了,而是root的權限,是以說所謂的SUID就是打破了程序安全上下文當中的上文。其實給一個指令SUID權限是非常危險的,為什麼呢?

[root@A ~]# su - user1 -c "cat /etc/shadow"   #原本user1沒有權限檢視/etc/shadow
cat: /etc/shadow: 權限不夠
[root@A ~]# chmod u+s `which cat`    #給cat二進制檔案加上SUID權限
[root@A ~]# su - user1 -c "cat /etc/shadow"  #然後user1再檢視shadow檔案,成功了!!
bin:*:15980:0:99999:7:::
daemon:*:15980:0:99999:7:::
adm:*:15980:0:99999:7:::      

是以說輕易不要給指令賦予SUID權限,其實系統當中一個現在的有SUID權限的指令就是passwd:

[user1@A ~]$ ll `which passwd`
-rwsr-xr-x. 1 root root 30768 11月 24 2015 /usr/bin/passwd      

這個指令普通使用者在使用的時候也會暫時擷取root的權限,可能你又疑惑了,如果普通使用者運作passwd指令有root的權限,豈不是普通使用者想修改誰的密碼就修改誰的密碼嗎?其實我們用腿想一下就知道了,linux做為一款優秀成熟的作業系統肯定不會出這樣重大的漏洞的,那麼是怎樣解決這個問題的呢?其實在核心代碼就已經做了規定,普通使用者使用passwd指令的時候是不允許攜帶任何參數的,隻能赤裸裸的使用passwd指令修改自己的密碼,就像下面示範的一樣,

[user1@A ~]$ passwd root  #user1想去修改root的密碼
passwd: Only root can specify a user name.   #隻有根使用者才能指定使用者名稱。      

好了,到此,SUID就講完了,那麼來一遍完整的示範:

[root@A ~]# ll `which cat`
-rwxr-xr-x. 1 root root 54080 11月  6 2016 /usr/bin/cat
[root@A ~]# su - user1 -c "cat /etc/shadow"
cat: /etc/shadow: 權限不夠
[root@A ~]# chmod u+s `which cat`
[root@A ~]# su - user1 -c "cat /etc/shadow"
bin:*:17110:0:99999:7:::
daemon:*:17110:0:99999:7:::      

抽象了解:

程序的安全上下文就像“一把普通菜刀”,這把菜刀有多大的權利取決于誰拿着這把菜刀!皇帝(root)可以殺所有人,甚至可以自殺;普通百姓拿着這把菜刀權利就小的很,隻能搞搞與自己相關的東西。

suid就像“尚方寶劍”,這把寶劍有多大的權利取決于這把劍自身!無論認誰拿尚方寶劍都可以“上斬昏君下斬佞臣”。

SGID

SGID可以用于檔案也可以用于目錄,用于檔案時與suid類似,當程式運作于程序時屬組是程式檔案的屬組,但是很少這樣用,經常還是用在目錄上,當用到目錄上時,在目錄裡面建立的檔案或者子目錄都會繼承目錄的屬組,僅僅是繼承屬組。

先示範沒有sgid權限的場景:

[root@linuxprobe ~]# mkdir -m 777 /public
[root@linuxprobe ~]# ll -d /public/
drwxrwxrwx 2 root root 6 6月   4 10:52 /public/
[root@linuxprobe ~]# su - zhanghe -c "touch /public/zhanghe.txt;ls -ld /public/zhanghe.txt"
-rw-rw-r-- 1 zhanghe zhanghe 0 6月   4 10:53 /public/zhanghe.txt   #在public目錄裡面建立檔案的屬主和屬組與public目錄沒有關系,目錄是root:root,而使用者建立檔案的權限是zhanghe:zhanghe      

用了sgid權限之後的場景:

[root@linuxprobe ~]# mkdir -m 777 /test
[root@linuxprobe ~]# ll -d /test
drwxrwxrwx 2 root root 6 6月   4 10:55 /test
[root@linuxprobe ~]# chmod g+s /test;ls -ld /test   #加上sgid權限
drwxrwsrwx 2 root root 6 6月   4 10:56 /test
[root@linuxprobe ~]# su - zhanghe -c "touch /test/zhanghe.txt;ls -ld /test/zhanghe.txt"
-rw-rw-r-- 1 zhanghe root 0 6月   4 10:59 /test/zhanghe.txt      

sgid對目錄使用時就是讓此目錄裡建立的檔案繼承該目錄的屬組,就是這麼簡單,根本也用不着抽象,但是這個知識點還挺常用,我們應該講一下sgid會用到什麼場景當中(下文摘自《鳥哥的私房菜》):

有兩個使用者tom和jerry,兩個使用者除了屬性自己的使用者組之外還屬于project組,兩個使用者需要共同擁有對/srv/ahome目錄的開發權,且該目錄不允許其他人進入查閱,請先用傳統的權限實作,然後再用sgid實作。

準備工作:

[root@linuxprobe ~]# groupadd project   #建立一個使用者組project
[root@linuxprobe ~]# useradd -G project tom  #把tom使用者加入到project裡面
[root@linuxprobe ~]# useradd -G project jerry  #把jerry使用者加入到project裡面
[root@linuxprobe ~]# id tom ; id jerry
uid=1002(tom) gid=1003(tom) 組=1003(tom),1002(project)
uid=1003(jerry) gid=1004(jerry) 組=1004(jerry),1002(project)      

實作的方式:

我們隻要把/srv/ahome的屬組改成project,然後把權限改成770,即可以實作上述要求。

[root@linuxprobe /]# mkdir /srv/ahome
[root@linuxprobe /]# chmod 770 /srv/ahome
[root@linuxprobe /]# chgrp project /srv/ahome
[root@linuxprobe /]# ll   /srv/ahome -d
drwxrwx--- 2 root project 6 6月   4 14:56 /srv/ahome      

這樣就好了嗎?我們可以試一試

[root@linuxprobe /]# su - tom -c "touch /srv/ahome/tom.txt"
[root@linuxprobe /]# su - jerry -c "touch /srv/ahome/jerry.txt"
[root@linuxprobe /]# ll /srv/ahome/
-rw-rw-r-- 1 jerry jerry 0 6月   4 15:12 jerry.txt
-rw-rw-r-- 1 tom   tom   0 6月   4 15:11 tom.txt      

通過上面的操作我們可以知道,在/srv/ahome這個目錄裡面tom的檔案對jerry來講是其他人,也就是說jerry在對tom建立的檔案進行操作時,是以其他人的身份進行操作的,隻有讀的權限,互相之間并不能修改,這是不符合要求,我們想實作他們之間可以互相編輯,我們可以這麼做:

[root@linuxprobe /]# rm -rf /srv/ahome/*
[root@linuxprobe /]# chmod g+s /srv/ahome/
[root@linuxprobe /]# su - tom -c "touch /srv/ahome/tom.txt"
[root@linuxprobe /]# su - jerry -c "touch /srv/ahome/jerry.txt"      

我們再看兩個檔案的權限:

[root@linuxprobe /]# ll /srv/ahome/
-rw-rw-r-- 1 jerry project 0 6月   4 15:19 jerry.txt
-rw-rw-r-- 1 tom   project 0 6月   4 15:19 tom.txt      

當tom再去通路jerry的檔案時是以屬組的權限去通路的,這樣互相之間就有讀寫權限,可以互相編輯檔案。

sticky

我們如果把一個目錄的屬組改為開發組,開發組裡面的成員都對目錄有讀寫執行的權限,開發組有那麼多人,如果一個要看另一個不順眼将其檔案删除了怎麼辦?是以有了sticky權限,當我們對一個目錄使用了sticky權限 之後,使用者隻能删除自己的檔案,而不能删除别的檔案。

/tmp/和/usr/tmp這兩個目錄預設有sticky權限。

[root@linuxprobe ~]# ll /tmp/ -d ; ll /usr/tmp/ -d
drwxrwxrwt. 79 root root 8192 6月   4 10:52 /tmp/
drwxrwxrwt. 20 root root 4096 6月   4 09:01 /usr/tmp/      

那麼誰可以删除呢?

l  root

l  檔案所有者

l  該目錄所有者

suid針對檔案,以所有者身份執行

繼續閱讀