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
可能结果如下:
/usr (everyone)
/export/target1 -access=target2
/export/target2 -access=target1
可以把这个NFS server上的/usr目录mount成本地目录:
# mount :/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实现方案(虽然未必真的很安全)