Linux Setuid(SUID)和Setgid(SGID) sticky bit


http://www.php100.com/html/webkaifa/Linux/2010/0812/6392.html

 

 1、setuid和setgid的解說

 

  setuid和setgid位是讓普通用戶可以以root用戶的角色運行只有root帳號才能運行的程序或命令。比如我們用普通用戶運行passwd命令來更改自己的口令,實際上最終更改的是/etc/passwd文件,我們知道/etc/passwd文件是用戶管理的配置文件,只有root權限的用戶才能更改:

  [root@localhost ~]# ls -l /etc/passwd

  -rw-r--r-- 1 root root 2379 04-21 13:18 /etc/passwd

  作為普通用戶,如果修改自己的口令通過修改/etc/passwd肯定是不可完成的任務,是不是可以通過一個命令來修改呢?答案是肯定的,作為普通用戶可以通過passwd 來修改自己的口令,這歸功於passwd命令的權限。我們來看一下:

  [root@localhost ~]# ls -l /usr/bin/passwd

  -r-s--x--x 1 root root 21944 02-12 16:15 /usr/bin/passwd

  因為/usr/bin/passwd 文件已經設置了setuid 權限位(也就是r-s--x--x中的s),所以普通用戶能臨時變成root,間接的修改/etc/passwd,以修改自己口令的權限。

  我們在Linux 系統中的超級權限的控制中有提到過我們知道Linux的用戶管理是極為嚴格的,不同的用戶擁有不同的權限,為了完成只有root用戶才能完成的工作,我們必須為普通用戶提升權 限,最常用的方法就是su或sudo,雖然setuid 和setgid也是讓普通用戶超越自身擁有的普通權限達到root權限的方法,但我不推薦大家使用,因為它能為系統帶來隱患!!

  注意:setuid和setgid會面臨風險,所以盡可能的少用,了解了解既可~~~

  2、setuid和setgid的實例應用

  我們想讓一個普通用戶beinan擁有root用戶擁有超級rm刪除權限,我們除了用su或sudo 臨時切換到 root身份操作以外,還能怎么做呢???

  [root@localhost ~]#cd /home 注:進入/home目錄

  [root@localhost home]# touch beinantest.txt 注:創建一個文件;

  [root@localhost home]# ls -l beinantest.txt 注:查看文件屬性;

  -rw-r--r-- 1 root root 0 04-24 18:03 beinantest.txt 注:文件的屬性;

  [root@localhost home]# su beinan 注:切換到普通用戶 beinan

  [beinan@localhost home]$ rm -rf beinantest.txt 注:以普通用戶身份來刪除beinantest.txt文件;

  rm: 無法刪除 beinantest.txt: 權限不夠

  那我們怎么才能讓beinan 這個普通用戶也擁有root超級的rm 刪除功力呢?

  [root@localhost ~]# ls -l /bin/rm

  -rwxr-xr-x 1 root root 93876 02-11 14:43 /bin/rm

  [root@localhost ~]# chmod 4755 /bin/rm 注:設置rm的權限為4755 , 就把setuid 位設置好了

  [root@localhost ~]# ls -l /bin/rm

  -rwsr-xr-x 1 root root 43980 02-11 14:43 /bin/rm

  [root@localhost ~]# cd /home/

  [root@localhost home]# su beinan 注:切換到beinan用戶身份;

  [root@localhost home]$ ls -l beinantest.txt 注:查看文件屬性;

  -rw-r--r-- 1 root root 0 04-24 18:03 beinantest.txt 注:文件的屬性;

  [beinan@localhost home]$ rm -rf beinantest.txt 注:刪除beinantest.txt文件;

  我們只是設置了rm的setuid位,讓普通用戶在rm指令上有超級root的刪除超級權力

  通過這個例子,我們應該能明白setuid和setgid位的應用了,如同前面所說,讓普通用戶超越本身的能力,讓普通用戶能執行只有root才能 執行的命令在這一點,我們要和su和sudo 區分開來請參見su和sudo的文檔:Linux 系統中的超級權限的控制

  3、setuid和setgid的設置方法

  第一種方法:八進制方法:

  setuid位是的設置用八進制的4000,setgid占用的是八進制的2000 ;比如我們前面所說的 chmod 4755 /bin/rm 就是設置的setuid位;

  至於setuid的設置方法,只是在我們通過chmod設置文件或目錄權限位的八進制方法的前面多加一個數字,也就是4比如:

  [root@localhost ~]# chmod 4755 /bin/rm 注:設置rm的權限為4755 , 就把setuid 位設置好了

  作為setgid 位占用的是八進制的2000位,我們下面舉個例子;

  [root@localhost ~]# cd /home/

  [root@localhost home]# mkdir slackdir

  [root@localhost home]# ls -ld slackdir/

  drwxr-xr-x 2 root root 4096 04-24 18:25 slackdir/

  [root@localhost home]# chmod 2755 slackdir/

  [root@localhost home]# ls -ld slackdir/

  drwxr-sr-x 2 root root 4096 04-24 18:25 slackdir/

  我們看到 slackdir這個目錄,經過改變權限后的,目錄所歸屬用戶組的那三個權限位是 r-s 如果我們見到的是小寫的s,表明文件所歸屬的用戶組位有執行權限x因為我們用了2755 ,意思是說文件屬主擁有可讀可寫可執行權限,所歸屬的用戶組擁有可讀可執行權限,並且設置了setuid,所以這時本來文件所歸屬的用戶組擁有r-x,現 在加了setgid位,就把其中的x換成了s如果文件所歸屬的用戶組沒有執行權限,這個權限應該是S同理setuid位的中的大寫的S和小寫的s,也 是這個原理見下面的例子;

  [root@localhost home]# chmod 2740 slackdir/

  [root@localhost home]# ls -ld slackdir/

  drwxr-S--- 2 root root 4096 04-24 18:25 slackdir/

  這個例子是因為目錄slackdir所歸屬的組沒有執行權限,這時本來在執行權限位上顯示-,由於有了setuid,所以顯示為S

  如果我們為一個文件的權限擁有 屬主可讀可寫可執行所歸的組擁有可讀可執行,其它用戶可讀可執行,並且同時設置setuid和setgid位,我們應該怎么運行命令呢?

  [root@localhost ~]# touch gooddoc.txt

  [root@localhost ~]# ls -l gooddoc.txt

  -rw-r--r-- 1 root root 0 04-24 18:47 gooddoc.txt

  [root@localhost ~]# chmod 6755 gooddoc.txt

  [root@localhost ~]# ls -l gooddoc.txt

  -rwsr-sr-x 1 root root 0 04-24 18:47 gooddoc.txt

  所以,同時設置setuid和setgid,就是把setuid和setgid兩個八進位的值相加 (4000 2000=6000),然后加上文件或目錄的權限位的三位數值(上面的例子是755),然后通過chmod 運行就行了所以上面例子中用了6755

  第二種方法:通過助記語法;

  還是延用chmod的助記語法,通過u+s 或u-s 來增減setuid位,同理,我們可以通過g+s 或g-s 來setgid位;

  [root@localhost ~]# touch mydoc.txt 注:創建一個文件;

  [root@localhost ~]# ls -l mydoc.txt

  -rw-r--r-- 1 root root 0 04-24 19:00 mydoc.txt

  [root@localhost ~]# chmod u+s mydoc.txt

  [root@localhost ~]# ls -l mydoc.txt

  -rwSr--r-- 1 root root 0 04-24 19:00 mydoc.txt

  我們也可以用file命令來查看setuid和setgid位,當然也能用file來查看文件的類型;

  比如:

  [root@localhost ~]# file /usr/bin/passwd

  /usr/bin/passwd: setuid ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24,                 BuildID[sha1]=0xc101d30ff4513f2dbad17fcc483dcda4a38e1df0, stripped

 

 http://blog.csdn.net/wowricky/article/details/6894538

setuid 和 setgid (全稱分別是:set user ID upon execution 和 set group ID upon execution)是Unix的訪問權限標志位,它允許用戶以可執行文件owner或group的權限來運行這個可執行文件。它們經常適用於:為了運行特定的任務,可以允許用戶暫時的提高權限。用處:暫時的權限提升
什么情況下需要setuid 和 setgid呢?當task需要的權限高於用戶的權限時,比如修改用戶的登錄密碼。有些任務需要更高的權限可能不會立刻表現出來,比如ping,它需要發送和監聽某個網絡接口的控制包。

1. setuid作用於可執行文件
當一個二進制可執行文件被設置了setuid屬性之后,在所創建的進程內部,有權限執行此文件的用戶將會獲得這個可執行文件的owner的權限(通常是root)。在進程內部,用戶獲取root權限之后,這個用戶將可以做一下常規用戶被限制做的事情,當然有些事情是禁止的:比如使用ptrace 、LD_LIBRARY_PATH, 或者給自己發送信號(但是從終端發送的信號是可以的)。由於潛在競爭條件,如果setuid 作用於shell 腳本,很多操作系統將會忽略掉setuid.
雖然setuid在很多場合是很有用的,但是如果一個可執行程序設計的不夠好並被設置了setuid將會帶來潛在的風險。人們能夠利用有漏洞的程序獲取永久的權限提升,或者讓用戶在無意之間運行一個特洛伊木馬。
setgid能夠改變group的權限,正如setuid改變user權限一樣。

setuid作用於可執行文件解釋了為什么系統調用chroot對於非root用戶是不可用的。

可以通過chmod 來設置setuid 和 setguid的標志位(最高位),
4: for setuid

2: for setguid

1: 這個是粘滯位 //可以參考:http://blog.csdn.net/hzgdiyer/article/details/6788275

"chmod 6711 file" 將會設置setuid 和setguid, bits(6) 即位最高位。
另外還多系統也支持 “chmod ug+s"命令來設置.

下面的演示代碼用來獲取並顯示出進程的real 和 effective 的用戶(user)和組(group)的ID:
1.顯示printid.c的代碼,這段代碼就是打印real/effective user/group ID
2.編譯程序printid
3.運行程序printid,打印出了real/effective user/group ID
4.修改printid的owner為root
5.給文件printid添加setuid和setgid標志位
6.取消文件printid其它用戶(other)的讀r和執行x權限
7.顯示文件printid屬性
8.重新運行printid, 
我們發現printid權限:
owner:root, rws
group:staff, r-s
other:        ---
雖然other沒有任何權限,但以用戶bobie(對於問價printerid,bobie不是owner,也不是group,屬於other)運行printid,依然可以運行,顯然是添加了setuid的原因。
通過打印信息可以看到effective id 是0,正好是root的id,可以參考/etc/passwd(里面有每個用戶/組對應的id)
//備注:如果這個程序是在volumn上運行且mounte時添加了'nosuid'選項,這個程序將會失敗,沒有打印信息;
//volumn: 可以再磁盤上創建卷(volumn),物理卷(PV)=》邏輯卷(LV)=>卷組(VG),最后將這卷組mounte到指定路徑

[bobie]$ cat printid.c

#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
int main(void) {
    printf(
        "         UID           GID  \n"
        "Real      %d  Real      %d  \n"
        "Effective %d  Effective %d  \n",
             getuid (),     getgid (),
             geteuid(),     getegid()
    );
    return getegid() ;       /* always good to return something */
}

[bobie]$ cc printid.c -o printid
[bobie]$ ./printid
          UID           GID  
Real      1008  Real      1008
Effective 1008  Effective 1008  
 
[bobie]$  sudo chown root printid   # to change the owner you need to sudo 
Password:
[bobie]$ sudo chmod ug+s printid     # SetUID and SetGID flags
[bobie]$ sudo chmod o-rx printid     # Don't let Others read or execute it
[bobie]$ ls -l
-rwsr-s--- 1 root staff 6944 2011-10-06 10:22 printid
[bobie]$ ./printid 
        UID              GID  
Real      1008  Real      1008
Effective 0   Effective  20

2.setuid/setgid作用於路徑
setuid和setgid作用於路徑時,有完全不同的含義。

給路徑設置setgid(chmod g+s),會導致路徑下新建的文件和子文件夾繼承它的group id, 而不創建文件或文件夾的用戶的primary group id.【只有group id 受影響,owner id 不受影響】。另外,新創建的子文件夾還將繼承setgid位。注意:給路徑設置setgid,僅僅影響新建的文件和文件夾的group id,已經存在的文件和文件夾不受影響
給已經存在的子文件夾設置setgid,必須手動來做,用如下命令:
[root@foo]# find /path/to/directory -type d -exec chmod g+s {} \;

給路徑設置setuid,將會被Unix 和 Linux系統忽略

3.安全
被設置setuid/setgid的程序必須小心的設計防止緩存區溢出攻擊。緩存區溢出攻擊成功的后果是:能夠使攻擊者利用進程的權限執行任意的代碼。如果一個有漏洞的程序被設置了setuid,權限提升以root運行,攻擊成功就會使攻擊者獲得root權限,這太可怕了。

4.歷史
setuid 是 Dennis Ritchie發明的,他所在的公司AT&T, 於1972年申請專利,1979年專利獲批,專利號:US 4135240 "Protection of data file contents".

 

http://waringid.blog.51cto.com/65148/95407

 

不管是Linux新手還是高手,在使用它的時候不可避免都會遇到Linux權限問題。而這些問題也是初學者問得最多的問題,很多的腳本不能執行的原因就是因為沒有設定正確的權限所致。這里我們來看看Linux下的根限到底是怎么一回事。
  當你新建一個文件時,它的最初的權限取決於你的umask值(將在后面說明)。權限可以使用chmod命令或是chmod()系統調用來修改一個文件的權限模式。只有在文件所有者才能修改文件的權限模式。唯一例外的就是超級用戶:超級用戶可以修改任何文件的權限。下面是chmod命令的格式:
chmod [-Rfh] [agou] [+-=] [rwxXstugol] filelist
Image00001
要修改哪些用戶的特權:
字符 含義
a 修改所有用戶的特權
g 修改組用戶的特權
o 修改其它用戶的特權
u 修改所有者的權限
執行什么操作:
字符 含義
- 刪除當前的權限
= 替換當前的權限
+ 增加當前的權限
要修改哪一項權限:
字符 含義
r 讀訪問
w 寫訪問
x 執行訪問
s SUID或是SGID
t 粘附位
  其中X是表示由BSD衍生出來的UNIX系統特有的選項,它的意思是:如果文件是一個目錄,或有一些其它執行位已設置,那么就將文件設置為只可執行。而l則是由System V衍生出來的UNX系統特有的選項,它的意思是:允許對文件進行強制加鎖。 -R選項表示chmod命令會遞歸執行。如果指定了一個目錄filelist,那么目錄的權限改變了,目錄下所有文件的權限也都改變了。如果該目錄包含子目錄,那么這一地程會一直向下重復。 -f選項表示強制執行,chmod命令不會報告錯誤。通常在shell中比較有用。
  在某些系統中使用-h選項來改變chmod對符號鏈接的工作方式。如果指定了-h選項,而其中一個參數據為符號鏈接的話,那么chmod不會改變符號鏈接所指向的那個文件或目錄的權限。
下圖說明了命令的使用方法:
Image00002
計算機八進制的文件權限:
  chmod允許用戶使用一個四位八進制數字來指定文件權限模式。用戶可以通過將權限相加的方式來計算這一數值。下表說明了每個文件權限對應的八進制數。
八進制數 權限
4000 SUID
2000 SGID
1000 粘附位
0400 所有者可讀
0200 所有者可寫
0100 所有者可執行
0040 組成員可讀
0020 組成員可寫
0010 組成員可執行
0004 其它用戶可讀
0002 其它用戶可寫
001 其它用戶可執行
  因此,一個文件權限如果為“-rwxr-x---”,那么其文件模式為0750,計算過程為:0400+0200+0100+0040+0010=0750。例如常見的/tmp目錄的權限就為1777,表示任何用戶都可以在該目錄下創建文件,但是用戶不能刪除其它用戶的文件。
umask
  umask是“用戶文件創建模式掩碼”的縮寫,是一個四位的八進制數值。用來確定一個新創建文件的權限。每個進程都從父進程那里繼承了自己的umask。一般該命令會在.bashrc,.profile,.cshrc或是/etc/profile及/etc/bashrc中。
Image00003
  最常見的umask值是022,027以及077。022讓文件所有者擁有對新建文件的讀寫權限,但是其它人對此只讀。例如:0666(默認的文件建立模式)+0022(umask)=0644。計算umask值最簡單的方法是記住:umask值中的2屏蔽了寫權限,而7屏蔽了讀,寫及執行權限。
常用的umask設置:
umask 用戶訪問 組訪問 其它
0000 所有 所有 所有
0002 所有 所有 讀,執行
0007 所有 所有
0022 所有 讀,執行 讀,執行
0027 所有 讀,執行
0077 所有
  下面的圖片是顯示新建文件后的權限,大家可以想想看它對應的umask應是多少。
Image00004  
粘附位:
  具有八進制值1000的位叫粘附位,是unix已經發展得不再需要的事物而又不能擺脫其追隨的例子.像unix在其上度過它的孩童期的PDP-11/70這樣的小內存系統,需要一些程序持續地駐留在內存或交換設備上這個時候粘附位就十分重要了.在今天由於有了25美圓的內存模塊和快速磁盤驅動器,在可執行程序上的粘附位已經過時了,現代的內核已經悄然地忽略了它.
  如果在目錄上設置了這個位,那么大多數版本的unix不允許刪除或重新命名該目錄中的文件,除非你是該目錄的屬主,該文件的屬主或超級用戶.在這個目錄上擁有寫入權限是不夠的.這相約定是讓像/tmp之類的目錄變得多少有些隱私性和安全性的一種嘗試.
  Solaris和HP-UX在處理粘附位目錄的時候並不那么嚴格.如果對該目錄有寫入權限,即使不是屬主,也能刪除其中的文件.這實際上有許多意義,雖然對實際應用幾乎沒有什么影響。
SUID和SGID
  setuid和setgid的位值是04000和02000。這些位允許程序訪問運它們的用戶本來無權訪問的文件和進程。當某個目錄上設置setgid位時,在這個目錄中新創建的文件具有該目錄的屬組權而不是創建該文件的用戶的默認屬組。這項約定使得在幾個用戶之間(只要這些用戶都屬於同一個組)共享一個目錄中的文件變得更簡單。在使用這些特性之前,請檢查自己的系統,因為並不是所有版本的unix都支持這個特性,當然BSD,REDHAT,HP-UX,SOLARIS都是支持的。對setgid位的這種解釋跟它在可執行文件上設置時的含義沒有什么關系,但不要混淆了這兩種意義。一些系統允許在非可執行的純文本文件上設置setgid位,以在該文件被打開時請求特殊的鎖定。有關它的詳細說明可以參考: [url]http://www.linuxeden.com/html/unix/20071031/36892.html[/url]。在linux下,有關SUID最常用的一個命令就是ping,下面是關於它的圖片,好好看看吧。
Image00005
 
 
 
 
 

Linux中的粘滯位

Sticky 位是一個訪問權限標志位,可以用來標示文件和路徑。

歷史:

粘滯位是在1974年Unix的第5版中引入的,用來設置可執行文件。當可執行文件設置粘滯位之后,它能夠指示操作系統在程序退出后,保留程序的代碼段到swap空間。當程序再次執行時,內核只需將程序從swap搬到內存即可,這能夠加速程序的執行。所以,頻繁使用的程序比如編輯器能夠更快的打開。目前,這種應用只是適用於HP-UX, NetBSD和UnixWare,Solaris在2005年放棄了這種應用,linux沒有版本支持過這種行為。

當今使用:

當今,粘滯位最常用是應用於路徑。當路徑被設置粘滯位后,路徑下的文件只有文件的owner, 或者root 才能夠重命名、刪除文件。如果沒有粘滯位,任何用戶,不管是不是owner, 只要有路徑的寫/執行權限就可以重命名、刪除文件。典型的應用就是/tmp路徑,粘滯位可以阻止一般用戶刪除/重命名其他用戶的文件。這種特性首次引入是在1986年4.3BSD, 今天在現在的Unix系統中都可以找到這個特性。另外,Solaris定義了獨有的行為:當粘滯位設置到非執行文件時,當訪問這種文件時,內核將不會緩存。這常用於設置swap文件,用來阻止訪問這些文件時沖刷掉系統緩存中更重要的數據。

 

Sticky bit在不同系統中的異同

HP-UX:當程序的最后一個用戶退出時,阻止系統丟棄程序段swap-space image. 當下一個用戶執行這個程序時,系統只需要swap in,而不需要重從磁盤新讀入文件到內存,節約程序啟動時間。

[...] prevents the system from abandoningthe swap-space image of the program-text portion of the file when its last userterminates. Then, when the next user of the file executes it, the text need notbe read from the file system but can simply be swapped in, thus saving time.

Linux: 當粘滯位設置到文件時,內核將會忽略。當設置路徑時,路徑中的文件只能夠被root或者文件的owner重命名或者unlinked。

[...] the Linux kernel ignores the stickybit on files. [...] When the sticky bit is set on a directory, files in thatdirectory may only be unlinked or renamed by root or their owner.

舉例:

Sticky bit 設置:

chmod 命令,可以用八進制模式1000或者它的符號t.

比如:添加粘滯位到路徑/usr/local/tmp,

1.      chmod +t /usr/local/tmp

2.      chmod 1777 /usr/local/tmp

在Unix 文件系統 符號中,sticky bit t 是在最后一位。比如:在Solaris 8, /tmp路徑默認有粘滯位,如下:

$ ls -ld /tmp
 drwxrwxrwt   4 root     sys          485 Nov 10 06:01 /tmp
如果粘滯位設置的路徑或者文件沒有可執行(x)位,它的符號用T(大寫的t)
# ls -l test
 -rw-r--r--   1 root     other          0 Nov 10 12:57 test
 # chmod +t test; ls -l test
 -rw-r--r-T   1 root     other          0 Nov 10 12:57 test

From http://en.wikipedia.org/wiki/Sticky_bit


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM