Unix系統的NFS服務相當于MS系統上的檔案共享服務。也許有人認為這是一個不恰當的比喻,但二者在安全問題上有驚人的類似,正如NT/Windows機器上的安全問題很多來自共享資源一樣,NFS服務的錯誤配置,也可以讓你的系統被入侵者接管。NFS建立在RPC(遠端過程調用)機制上,同樣地,基于RPC機制上的NT服務也不安全;針對MS共享資源的攻擊是目前Internet上最流行的攻擊NT方式,對NFS的攻擊也對UNix平台機器的最常用手段。
NFS的不安全性主要展現于以下4個方面:
1、新手對NFS的通路控制機制難于做到得心應手,控制目标的精确性難以實作
2、NFS沒有真正的使用者驗證機制,而隻有對RPC/Mount請求的過程驗證機制
3、較早的NFS可以使未授權使用者獲得有效的檔案句柄
4、在RPC遠端調用中,一個SUID的程式就具有超級使用者權限。
我們分别從這幾個方面加以論述:
1、在大多數Unix系統的預設的情況下,Export目錄時,如果不指定隻讀,該目錄為可寫;NFS的通路控制檔案很容易出現錯誤配置,很多情況下配置為可以被網上任何一台機器通路,遠端使用者可以用這條指令來查到是否有NFS的配置漏洞,這個指令是幾乎所有的NFS攻擊的必經步驟:
# showmount -e www.xxx.com
可能結果如下:
/usr (everyone) /export/target1 -access=target2 /export/target2 -access=target1
可以把這個NFS server上的/usr目錄mount成本地目錄:
# mount www.xxx.com:/usr /tmp
這表明,/usr目錄可以被任何一台機器mount,甚至可能有寫的權限;而/export/target1目錄指定了主機通路限制,必須是target2.xxx.com這個機器或者target2這個Netgroup的成員才能mount。入侵者大多都先用這個指令來查詢目标上的NFS漏洞,正如對NT的Netview指令一樣。值得提醒的是,現在流行的入侵方式已經從以前的對确定目标的攻擊方式轉為不管對方是誰,隻要有機可乘就入侵的方式。
入侵者可能會寫一個腳本或者一個程式,用來對一大段位址進行掃描,列出結果報告給自己。是以,正确的配置是非常重要的。在Internet上,NFS設定錯誤的機器比比皆是。這個配置一般存放于/etc/exports檔案或/etc/dfs/dfstab中。
2、來自用戶端的NFS請求的使用者認證,由使用者的UID和所屬組的GID組成,這種檔案通路的安全驗證對于沒有開NFS的系統當然是安全的;但是在網上,其它機器的root完全有權在自己的機器上設定這樣一個UID,而NFS伺服器不管這個UID是不是自己機器上的,隻要UID符合,就賦予這個使用者對這個檔案的操作權.比如,目錄/home/frank隻能由UID為501的使用者打開讀寫,而這個目錄可以被遠端機器mount,那麼,這台機器的root使用者新增一個UID為501的使用者,然後用這個使用者登入并mount該目錄,就可以獲得相當于NFS server上的UID為501使用者操作權限,進而讀寫/home/frank。要解決這個問題必須正确配置exports,限制客戶的主機位址,明确設定rw=host的選項,ro(隻讀)的選項和access=host的選項。
另外,還有一種UID欺騙,是關于16位UID和32位UID的問題。大多NFS服務接受的來自客戶對NFS請求所發送的UID标志都是16位的(Solaris是一個例外),這是不安全的。
在這種情況下,如果用一個32位UID,并把這個UID最左邊的位置設定為0,那麼,展現在NFS server上,解釋為16位的UID,這個UID就相當于root;任何使用者引用32位UID并且這個UID最左邊的數字是0,那麼就可以讀/寫屬于root的任何檔案。要解決這個問題,可以從Sun的正式站點擷取#1095935更新檔。
3、以前的檔案句柄無須mount守護程序的幫助就可以構造,使客戶直接可以和NFS通信。而現在的Unix系統大多進行了改進。但BSD系統還有問題。關于BSD檔案句柄的問題涉BSD OS2.0,2.1,3.0;FreeBSD2.1.5~2.1.7,openBSD2.0和2.0以前。其它一些BSD也可能有類似的問題。例如在4.4BSD中,與其它的UNix檔案系統不同的是,一個檔案的資訊,除了建立時間、檔案大小、連接配接個數和更新時間等資訊外,還有一個st_gen資訊,st_gen是一個4位的值,目的是使NFS檔案句柄難于猜到。這個資訊是stat(2)系統調用生成的。不幸的是,這個調用用到的一個函數vn_stat()有問題:
...
sb->st_gen = vap->va_gen;
sb->st_blocks = vap->va_bytes / S_BLKSIZE;
return (0); }
上面這段程式碼暴露了用來生成st_gen這個數的所有資訊,利用這些資訊,未授權使用者可以得到檔案的句柄。正确的程式應該隻允許這些資訊暴露給root:
sb->st_flags = vap->va_flags;
if (suser(p->p_ucred, &p->p_acflag)) {
sb->st_gen = 0;
} else {
}
return (0);
這樣,如果不是root,他隻能得到0這個資訊。
4、最危險的錯誤是把含有SUID程式的目錄export,并且該檔案有執行權。SUID程式相當于超級使用者本身。
解決方案
1、和從NT中删除任何共享的解決方案一樣,最好的解決方案是禁止NFS服務,或以AFS服務取而代之(Andrew File System)。
2、如果一定要開NFS,不要讓一個單機可以既是client,也是server;
3、export出的檔案系統隻設定為隻讀
4、禁止那些有SUID特性的程式的執行
5、不要export home 目錄
6、不要export可執行特性
7、使用一些安全NFS實作方案(雖然未必真的很安全)