nix系統的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 {
sb->st_gen = vap->va_gen;
}
sb->st_blocks = vap->va_bytes / S_BLKSIZE;
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實現方案(雖然未必真的很安全)