Linux process authority、the security risks in running process with high authority

catalogphp

1. Linux進程權限原理
2. 最小權限原則 - 進程降權運行最佳實踐
3. 進程權限控制包含的攻防向量
4. 進程高權限安全風險檢查技術方案

 

1. Linux進程權限原理html

咱們知道,Linux的權限管理體系中,有2個基礎權限規則源java

1. MAC模型: 磁盤ACL權限,在Linux文件管理中,每一個文件又有九位的權限說明,用來指明該文件容許哪些用戶執行哪些操做(讀、寫或者執行)
2. DAC模型: SELINUX權限管理

這2類權限規則是相對靜態的東西,穿插在它們之間,相對動態的東西是mysql

1. 用戶權限: Linux的用戶在登陸(login)以後,就帶有一個用戶身份(user ID, UID)和一個組身份(group ID, GID),用戶權限不能直接做用於DAC、MAC等靜態權限規則體系,而須要藉助進程得以實現
2. 進程權限: 從本質上來講,進程權限表明了啓動它的用戶的權限(父子進程繼承本質仍是從啓動用戶繼承的權限)

可是須要明白的是,這裏靜態的(MAC/DAC磁盤目錄權限)和動態的進程權限也會存在"互相影響"的狀況,基於"最小權限原則",Linux會對一些敏感ELF設置只有root可執行,而在平常的運維中用戶只能使用普通帳戶(例如admin)進行登陸,爲了讓普通帳戶admin可以正常執行這些程序,Linux對這些程序設置了s位,s位是磁盤目錄文件的一個標誌位,可是它能夠影響到進程的動態權限,在啓動這種帶s位的程序的時候,進程的save uid、effect uid都會被置位爲屬主權限(這樣就能以屬主的身份去啓動這個程序),從而得到臨時的只針對這個程序的權限提高,同時又遵循了最小權限原則,保證了系統的安全linux

0x1: 進程權限分類nginx

1. 真實身份
    1) real UID
    2) real GID

2. 有效身份
    1) effective UID
    2) effective GID

3. 存儲身份
    1) saved UID
    2) saved GID

1. 真實身份git

real uid、gid用於在進程建立時標識並驗證用戶身份,也就是說,用戶只有符合相應的ACL限制才能執行某條命令(啓動進程)或者查看某個資源,真實身份是咱們登陸shell終端時使用的身份,進程在啓動時直接繼承的用戶的uid、gid,並賦值給進程的real uid、real gid
2. 有效身份github

有效身份是當該進程真正去操做文件時所檢查的身份,用於在進程運行時,當但願訪問其餘資源時表示並驗證用戶身份,也就是說,進程在運行的時候要去訪問別的資源或者啓動別的程序,這個時候,進程的身份是以euid、egid做爲依據
通常狀況下,當一個用戶登錄系統時,系統會將UID和EUID都賦值爲/etc/passwd文件中的UID,通常狀況下2個ID是相同的(即euid=uid egid=gid),可是sudo狀況下,進程的euid會臨時變化成文件屬主權限,這時候就有可能出現uid != euid的狀況了web

#include <stdio.h>
main()
{
        printf("getuid(): %d\ngeteuid(): %d\ngetgid(): %d\ngetegid(): %d\n", getuid(), geteuid(), getgid(), getegid());
}
/*
su zhenghan
gcc test.c -o test
chmod ug+s test
su root
./test
*/


3. 存儲身份redis

存儲身份就是真實身份以外的另外一個身份。當咱們將一個程序文件執行成爲進程的時候,該程序文件的擁有者(owner)和擁有組(owner group)能夠被存儲成爲進程的存儲身份。在隨後進程的運行過程當中,進程就將能夠選擇將真實身份或者存儲身份複製到有效身份,以擁有真實身份或者存儲身份的權限。並非全部的程序文件在執行的過程都設置存儲身份的。須要這麼作的程序文件會在其九位(bit)權限的執行位的x改成s。這時,這一位(bit)叫作set UID bit或者set GID bit

$ls -l /usr/bin/uuidd
-rwsr-sr-x 1 libuuid libuuid 17976 Mar 30  2012 /usr/sbin/uuidd

當我以root(UID), root(GID)的真實身份運行這個程序的時候,因爲擁有者(owner)有s位的設定,因此saved UID被設置成爲libuuid,saved GID被設置成爲libuuid。這樣,uuidd的進程就能夠在兩個身份之間切換
這實現權限運行態臨時變化的目的,即用戶仍是以非root的低權限進行login登陸,可是有機會可以執行那些本來只有root才能執行的程序(雖然僅僅是運行態臨時能夠)
咱們一般使用chmod來修改set-UID bit和set-GID bit:

$chmod 4700 file

咱們看到,這裏的chmod後面再也不只是三位的數字。最前面一位用於處理set-UID bit/set-GID bit,它能夠被設置成爲4/2/1以及或者上面數字的和。4表示爲set UID bit, 2表示爲set GID bit,1表示爲sticky bit (暫時不介紹)。必需要先有x位的基礎上,才能設置s位

0x2: 進程權限繼承

當進程fork的時候,真實身份和有效身份都會複製給子進程。大部分狀況下,真實身份和有效身份都相同。當Linux完成開機啓動以後,init進程會執行一個login的子進程。咱們將用戶名和密碼傳遞給login子進程。login在查詢了/etc/passwd和/etc/shadow,並肯定了其合法性以後,運行(利用exec)一個shell進程,shell進程真實身份被設置成爲該用戶的身份。因爲此後fork此shell進程的子進程都會繼承真實身份,因此該真實身份會持續下去,直到咱們登出並以其餘身份再次登陸(當咱們使用su成爲root的時候,實際上就是以root身份再次登陸,此後真實身份成爲root)

0x3: 最小權限原則

Linux一般但願進程只擁有足夠完成其工做的特權,而不但願賦予更多的特權給它。從設計上來講,最簡單的是賦予每一個進程以super user的特權,這樣進程就能夠想作什麼作什麼。然而,這對於系統來講是一個巨大的安全漏洞,特別是在多用戶環境下,若是每一個用戶都享有無限制的特權,就很容易破壞其餘用戶的文件或者系統自己。"最小特權"就是收縮進程所享有的特權,以防進程濫用特權
然而,進程的不一樣階段可能須要不一樣的特權。好比一個進程最開始的有效身份是真實身份,但運行到中間的時候,須要以其餘的用戶身份讀入某些配置文件,而後再進行其餘的操做。爲了防止其餘的用戶身份被濫用,咱們須要在操做以前,讓進程的有效身份變動回來成爲真實身份。這樣,進程須要在兩個身份之間變化,這就是seteuid() api、磁盤文件-s標誌位的做用,它們能夠起到運行態臨時改變權限的目的 

0x4: 進程權限在內核態的存儲

正如uid,euid的關係同樣,task_struct也有兩種身份cred

struct task_struct
{
    ...
    /* process credentials */
    const struct cred __rcu *real_cred;    /* objective and real subjective task credentials (COW) */
    const struct cred __rcu *cred;        /* effective (overridable) subjective task credentials (COW) */
    ...
}

struct cred

http://www.cnblogs.com/LittleHann/p/3865490.html
//搜索:0x2: struct cred 

Relevant Link:

http://avaj.iteye.com/blog/657185
http://www.cnblogs.com/vamei/archive/2012/10/07/2713593.html
http://blog.chinaunix.net/uid-27105712-id-3349522.html
http://onestraw.net/linux/linux-struct-cred/
http://www.pizzhacks.com/personal/stesab79/univ/so2/esercitazioni/02-hello-world/hello_world.c

 

2. 最小權限原則 - 進程降權運行最佳實踐

0x1: Linux Nginx最小權限運行

在配置文件最外層增長配置:

worker_process 1;
user user;

也能夠在編譯安裝時就顯式指定帳戶、屬主

ps -ax -o ruid -o euid -o suid -o fuid -o pid -o fname | grep nginx

權限出讓使用最多的場景是相似apache或mysql程序,啓動的時候使用root用戶啓動,設置一些root用戶才能操做的系統配置。建立子進程時候經過setuid降級爲nobody用戶
可是對於nginx這種master-slave架構來講,nginx master必須一直保持root root帳戶權限,而fork出來的slave worker權限則是降權後的user user(具體名稱根據配置文件而定) 

0x2: Linux Apache最小權限運行

/etc/httpd/conf/httpd.conf

User daemon
Group daemon

apache沒有master-slave的概念,全部apache都是獨立的進程,由一個apache父進程fork出多個子進程,它們共同接收HTTP請求
對於apache來講,須要以root權限啓動apache,處理完必要的事情後,而後主進程fork出子進程,同時主動讓出root權限,主動降權

ps -ax -o ruid -o euid -o suid -o fuid -o pid -o fname | grep httpd

0x3: Linux Tomcat最小權限運行

tomcat本質是一個java程序,對於這類web容器來講,最佳安全實踐都是創建一個獨立的低權限(僅僅夠用)的賬號來運行web容器

0x4: Linux lighttpd最小權限運行

Lighttpd: Lighttpd是一個具備很是低的內存開銷,cpu佔用率低,效能好,以及豐富的模塊等特色。
lighttpd是衆多OpenSource輕量級的web server中較爲優秀的一個。支持FastCGI, CGI, Auth, 輸出壓縮(output compress), URL重寫, Alias等重要功能。Lighttpd使用fastcgi方式運行php,它會使用不多的PHP進程響應很大的併發量

vim /etc/lighttpd/lighttpd.conf
server.username  = "lighttpd"
server.groupname = "lighttpd"

ps -ax -o euid -o egid -o pid -o fname | grep lighttpd

0x5: Linux mysql最小權限運行

在linux下,新建一個mysql帳號,並在安裝的時候就指定mysql以mysql帳戶來運行,給與程序所在目錄的讀取權限,data所在目錄的讀取和寫入權限

1. mysql運行帳號的磁盤權限

1. mysql運行帳號須要給予程序所在目錄的讀取權限,以及data目錄的讀取和寫入權限 
2. 不允許給予其餘目錄的寫入和執行權限,特別是有網站的目錄
3. 取消mysql運行帳戶對於cmd,sh等一些程序的執行權限 

2. 獨立帳戶運行

vim /etc/my.cnf
user=mysql

能夠看到,mysql的udf擴展目錄plugin是不容許other運行寫操做的,若是咱們使用獨立帳戶運行mysql,僅給予程序所在目錄的讀取權限,以及data目錄的讀取和寫入權限,這樣即便mysql被入侵黑客也沒法向plugin下寫入udf文件 

0x6: Linux mongdb最小權限運行

爲mongdb創建獨立的帳戶,並賦值mongdb所須要的文件夾的操做權限,以獨立帳戶啓動mongdb

0x7: Linux redis最小權限運行

0x8: Linux memcache最小權限運行

0x9: Linux PHP-FPM最小權限運行

建議以獨立帳戶運行,並將相關目錄的owner、owngourp改成該帳戶

Relevant Link:

http://www.z-dig.com/nginx-optimization-25.html
http://www.cnblogs.com/LittleHann/p/4902573.html
http://howiefh.github.io/2014/04/26/mongodb-note-1-install-mongodb/
http://blog.csdn.net/stronglyh/article/details/46830919
http://linux.it.net.cn/m/view.php?aid=15509

 

3. 進程權限控制包含的攻防向量

在Linux下進行進程運行權限控制的核心在於: 當進程以獨立的非root賬號在運行的時候,它對全部磁盤文件的ACL權限矩陣來講都屬於other組,若是磁盤文件ACL自己配置得當,這將極大地保證的web容器的權限範圍被控制在一個很小的區間內

0x1: mysql入侵提權分析及防止措施

通常來講,mysql的提權有這麼幾種方式

1. udf提權 
此方式的關鍵導入一個dll文件,我的認爲只要合理控制了進程帳戶對目錄的寫入權限便可防止被導入dll文件;而後若是萬一被攻破,此時只要進程帳戶的權限夠低,也沒辦執行高危操做,如添加帳戶等 

2. 寫入啓動文件
這種方式同上,仍是要合理控制進程帳戶對目錄的寫入權限 

3. 普通帳戶泄露 
此處說的普通帳戶指網站使用的帳戶,一個比較方便的建議是直接給予特定庫的全部最低權限。帳戶泄露包括存在注入及web服務器被入侵後直接拿到數據庫帳戶密碼 

Relevant Link:

http://drops.wooyun.org/tips/2245
http://blog.chinaunix.net/uid-20639775-id-3249105.html
http://www.cnblogs.com/LittleHann/p/4903789.html

0x2: mongdb未受權訪問

未受權訪問漏洞成因:Mongodb 在啓動的時候提供了不少參數,如日誌記錄到哪一個文件夾,是否開啓認證等。形成未受權訪問的根本緣由就在於啓動Mongodb的時候未設置 --auth

Relevant Link:

https://phphub.org/topics/328
http://blog.itpub.net/26250550/viewspace-1364758/
http://segmentfault.com/a/1190000003002017

0x3: Redis未受權訪問漏洞

redis 默認不須要密碼便可訪問,黑客直接訪問便可獲取數據庫中全部信息,形成嚴重的信息泄露

Relevant Link:

http://help.aliyun.com/knowledge_detail/5988808.html
http://www.goingtodo.net/linux-install-redis-and-autorun/
http://shift-alt-ctrl.iteye.com/blog/1882850
http://www.osyunwei.com/archives/7225.html

0x4: memcached未受權訪問漏洞

Relevant Link:

http://lcx.cc/?i=3340
http://securityer.lofter.com/post/1d0f3ee7_79e25bb

 

4. 進程高權限安全風險檢查技術方案

0x1: 進程checklist

1. Nginx
3. Apache/httpd 
3. Tomcat 
4. lighttpd 
5. mysqld 
6. mongdb 
7. redis 
8. memcache 
9. PHP-FPM
10. jeklin

0x2: 檢測流程

1. 枚舉/proc/pid
2. 檢查/proc/pid/cmdline是否在checklist中出現(findstr)
3. 若是命中則繼續查看/proc/pid/status,獲取euid、egid這2個字段
4. 判斷當前獲取的euid、egid是否爲0、0,若是是,則報告異常

Relevant Link:

euid egid
ps -ax -o euid -o egid -o pid -o fname | grep nginx

 

Copyright (c) 2015 LittleHann All rights reserved

相關文章
相關標籤/搜索