荔园在线

荔园之美,在春之萌芽,在夏之绽放,在秋之收获,在冬之沉淀

[回到开始] [上一篇][下一篇]


发信人: Sealed (loving you!), 信区: Hacker
标  题: RPC/XDR/NFS系列之----NFS/Mount协议
发信站: BBS 荔园晨风站 (Wed Jun  7 18:30:34 2000), 转信



  所有系统 Linux UNIX Windows Other



  首页 >> 资料文献 >> Unix

  RPC/XDR/NFS系列之----NFS/Mount协议

发布日期: 2000-5-18
内容:
--------------------------------------------------------------------------------

--- 摘自<<绿盟月刊>>第九期


◆ RPC/XDR/NFS系列之----NFS/Mount协议

作者:scz < mailto: cloudsky@263.net >
主页:http://www.isbase.com
日期:2000-05-14

概述:

    本文用协议分析软件抓取了大量相关协议报文,
    加上注释,以便从协议角度理解一些东西。

测试:

    RedHat6.0/i386

目录:

    ★ Mount协议报文(用协议分析软件抓取)
    ★ NFS协议报文(用协议分析软件抓取)
    ★ 鉴别
    ★ NFS/Mount协议中可能存在的安全问题
    ★ 相关RFC以及参考资料

★ Mount协议报文(用协议分析软件抓取)

研究mount协议远比我当初想象的复杂,因为mount协议使用了动态端口,
用rpcinfo -p serverIp会发现不同底层支持协议的不同版本都注册了
动态端口。只好在NetXray3.03中指定抓TCP和UDP协议报文,同时指定源
端口和目标端口过滤,使用rpcinfo -p serverIp查询到的端口之一(为什
么说之一,因为你不知道会使用tcp还是udp,会使用版本1还是版本3)先
尝试一下。如果指定端口过滤规则下没有抓到包,换用另外的尝试。当然
你也可以先不指定端口过滤直接抓TCP & UDP报文,然后辨别出mount协议
报文,进而确定底层支持协议和当前使用的动态端口号。

曾经在华中站系统安全版上给出过<< NetXray使用说明之(2) >>介绍了
如何指定源端口/目标端口过滤规则,按照这个方法配合一下
rpcinfo -p serverIp的输出,我尝试了一次就找到当前所使用的端口号
和底层支持协议。

scz注:后来我在<< NetXray使用说明之(5) >>中给出了另外一种更方便的
       过滤规则抓取RPC报文,有兴趣的朋友请自行参看。

       通过抓取RPC报文发现,尽管NFS SERVER使用固定的2049端口,但
       NFS CLIENT依旧使用PORTMAPPER的PMAPPROC_GETPORT远程过程获取
       端口号,并不直接使用2049端口。可能是考虑兼容性和可移植性吧。

我们在192.168.67.106上用sniffer pro 2.6设置抓取RPC报文,无论底层
支持协议是TCP还是UDP。然后在192.168.67.107上以scz身份执行

/usr/sbin/rpcinfo -p 192.168.67.108
mount /home/scz/nfsmount
ls /home/scz/nfsmount
umount /home/scz/nfsmount

等操作,可以抓到一批RPC报文,mount协议很容易辨认,因为sniffer pro 2.6
无法识别mount协议,而PMAP和NFS这两个协议它可以识别,于是排他法确定出
mount协议。下面是 mount -t nfs 命令引发的一个RPC CALL报文:

数据链路层
aa bb cc dd ee ff 00 00 21 d4 0b 92 08 00

IP层
45 00 00 a4 02 81 40 00 40 06 2f ab c0 a8 43 6b c0 a8 43 6c

TCP层
03 75 源端口885
03 c5 目标端口965
71 13 44 c1 b1 02 5a 4d 80 18 7d 78 86 42
00 00 01 01 08 0a 00 03 87 1c 00 02 86 2b
80 00 00 6c RPC层(包括Mount协议层)总共108个字节

RPC层
37 a5 1c 99 XID
00 00 00 00 RPC CALL报文
00 00 00 02 RPC协议版本号2
00 01 86 a5 远程程序号100005
00 00 00 01 远程程序版本号1( 100005 1 tcp 965 mountd )
00 00 00 01 远程过程号1(MOUNTPROC_MNT)
00 00 00 01 AUTH_UNIX鉴别机制
00 00 00 2c AUTH_UNIX鉴别信息总长度44个字节,从时间戳开始算
38 bb 21 2f rpc client本地时间戳
00 00 00 12 client的主机名共18个字节
48 69 67 67 73 2e XX XX XX XX XX 2e 63 6f 6d 2e 63 6e 00 00
    higgs.xxxxx.com.cn,注意这里不要求是asciiz串,因为有长度字段,
    00是填充字节。
00 00 00 00 UID = 0(为什么这里是root,而不是scz,后面给个解释)
00 00 00 64 GID = 100(为什么这里是users,而不是root,后面有解释)
00 00 00 01 总共1个组
00 00 00 64 GID=100
00 00 00 00 使用AUTH_NULL鉴别机制
00 00 00 00 AUTH_NULL鉴别信息总长度0个字节

Mount协议层
00 00 00 13
    MOUNTPROC_MNT(dirpath)远程过程的参数dirpath的长度,
    总共19个字节
2f 68 6f 6d 65 2f 73 63 7a 2f 6e 66 73 65 78 70 6f 72 74 00
    /home/scz/nfsexport,结束的00是填充字节,需要4字节对齐。

[scz@ /home/scz]> id
uid=500(scz) gid=100(users) groups=100(users)
[scz@ /home/scz]> ls -l /bin/mount
-rwsr-xr-x 1 root root /bin/mount
[scz@ /home/scz]>

注意到/bin/mount的属性是rwsr-xr-x,所以只有SUID没有SGID,上面发送出去
的RPC CALL报文中符合这一点。需要理解的是,/etc/fstab文件中允许了
User mountable,否则即使mount是SUID了的,scz也无法执行mount -t nfs命令。

关于Mount协议,最好的参考资料就是RFC 1094中的
<< Appendix A. MOUNT PROTOCOL DEFINITION >>,有我们前面介绍的那么多文章
做铺垫,现在阅读这份RFC想必心情愉快,很容易看下去。我当时用sniffer pro 2.6
抓取了Mount协议报文,最后的Mount协议层就是通过查阅RFC才明白的,当然还需要
理解XDR对变长数据类型的处理,请参看<< RPC/XDR/NFS系列之----外部数据表示 >>。

下面是Mount协议的RPC REPLY报文,其中含有server:/home/scz/nfsexport的根
句柄,不知道这个被snoop上来的根句柄可以利用否:

数据链路层
00 00 21 d4 0b 92 aa bb cc dd ee ff 08 00

IP层
45 00 00 74 00 c0 40 00 40 06 31 9c c0 a8 43 6c c0 a8 43 6b

TCP层
03 c5 源端口965(当前mountd使用的动态端口)
03 75 目标端口885
b1 02 5a 4d 71 13 45 31 80 18 7c 70 fa 92
00 00 01 01 08 0a 00 02 86 2b 00 03 87 1c
80 00 00 3c RPC层(包括Mount协议层)总共60个字节

RPC层
37 a5 1c 99 XID
00 00 00 01 RPC REPLY报文

00 00 00 00 status字段为0,表明Message Accepted
00 00 00 00 使用AUTH_NULL鉴别机制
00 00 00 00 AUTH_NULL鉴别信息总长度0个字节
00 00 00 00 accept status字段为0,表明远程过程被成功调用并返回

Mount协议层
00 00 00 00 status为0,表明远程过程调用成功返回
ca ba eb fe 2a 68 0e 00 04 30 1d 00 04 03 00 00
04 03 00 00 2a 68 0e 00 a1 a5 5a 4c 00 00 00 00
    这是一个32字节的根句柄

现在让我们从RFC 1094中摘录一点东西来帮助理解最后的这个Mount协议
层,也是对XDR的一个复习:

    union fhstatus switch ( unsigned status )
    {
    case 0:
        fhandle directory;
    default:
        void;
    }

关于Mount协议,我们可以考虑自己写个程序调用MOUNTPROC_MNT过程
获取文件句柄,研究文件句柄是否可以猜测并由rpc client端自行制造。

★ NFS协议报文(用协议分析软件抓取)

我们在192.168.67.106上用NetXray3.03抓一切和192.168.67.108有关的UDP NFS报文
然后在192.168.67.107上执行了一个列目录的操作引发NFS报文的传输,得到下面的结果:

数据链路层
aa bb cc dd ee ff 00 00 21 d4 0b 92 08 00

IP层
45 00 00 90 14 ef 00 00 40 11 5d 46 c0 a8 43 6b c0 a8 43 6c

UDP层,注意这里目标端口是2049(0x0801),长度124字节(包括UDP Header)
03 20 08 01 00 7c 0c 73

RPC层,NFS是基于RPC的。总共116字节
14 f0 63 9c XID=0x14f0639c(351298460)
00 00 00 00 RPC CALL报文
00 00 00 02 RPC版本号总为2
00 01 86 a3 远程程序号100003
00 00 00 02 远程程序版本号2( 100003 2 udp 2049 nfs )
00 00 00 01 远程过程号1(GetAttr)
00 00 00 01 AUTH_UNIX鉴别机制
00 00 00 2c AUTH_UNIX鉴别信息总长度44个字节,从时间戳开始算
00 00 50 b0 rpc client本地时间戳(20656)
00 00 00 12 client的主机名共18个字节
48 69 67 67 73 2e XX XX XX XX XX 2e 63 6f 6d 2e 63 6e 90 90
    higgs.xxxxx.com.cn,注意这里不要求是asciiz串,因为有长度字段,
    90应该是填充字节。好象所有经XDR转换来的数据都以4字节为填充对
    齐单位。
00 00 01 f4 UID=500
00 00 00 64 GID=100
00 00 00 01 总共1个组
00 00 00 64 GID=100
00 00 00 00 使用AUTH_NULL鉴别机制
00 00 00 00 AUTH_NULL鉴别信息总长度0个字节

NFS层,下面的数据全部是NFS File Handle,总共32个字节
ca ba eb fe 2a 68 0e 00 04 30 1d 00 04 03 00 00
04 03 00 00 2a 68 0e 00 a1 a5 5a 4c 00 00 00 00

上面这个报文是一个由rpc client发起的RPC CALL报文,现在让我们简单猜
测一下这个NFS File Handle是如何组成的:

ca ba eb fe
2a 68 0e 00
    显然这个数据0x000e682a = 944170,就是server端/home/scz/nfsexport
    的i-node号
04 30 1d 00
04 03 00 00
04 03 00 00
2a 68 0e 00 同上,server端/home/scz/nfsexport的i-node号
a1 a5 5a 4c
00 00 00 00

scz注:要猜测一个NFS File Handle的编码方式,应该研究NFS Server Code。
       现在的问题是如何编程得到一个i-node号的生成号,反正我不知道,也
       不知道有什么工具可以让我看到这个i-node号的生成号,stat命令的显
       示中没有这个数据。

       根据以前讨论的结果,似乎只要拥有nfs server端的根文件句柄(export
       出来的目录),就可以做允许权限下的任意操作,那么第三者snoop到正在
       使用中的NFS File Handle,能否加以利用呢?句柄编码中是否含有client
       端的IP信息?faint

       还有,为了提高安全性,NFS SERVER可以限制句柄生命周期,我如何知道
       这种限制在当前实现中已经存在,句柄生命周期究竟多长,可以配置否?

接下来的这个报文是由rpc server应答的RPC REPLY报文:

数据链路层
00 00 21 d4 0b 92 aa bb cc dd ee ff 08 00
IP层
45 00 00 7c 0c 84 00 00 40 11 65 c5 c0 a8 43 6c c0 a8 43 6b
UDP层,注意这里源端口为2049
08 01 03 20 00 68 e3 43

RPC层
14 f0 63 9c XID=0x14f0639c,rpc server从rpc client的请求报文复制该数据
00 00 00 01 RPC REPLY报文
00 00 00 00 status字段为0,表明Message Accepted
00 00 00 00 使用AUTH_NULL鉴别机制
00 00 00 00 AUTH_NULL鉴别信息总长度0个字节
00 00 00 00 accept status字段为0,表明远程过程被成功调用并返回

NFS层,下面的数据是依赖于GetAttr远程过程本身的
00 00 00 00 返回状态为0,OK
00 00 00 02 是目录
00 00 41 ed 二进制111101101,rwxr-xr-x权限
00 00 00 02 Number of links = 2
00 00 01 f4 UID=500
00 00 00 64 GID=100
00 00 04 00 File Size       = 1024
00 00 10 00 File Block Size = 4096
00 00 00 00 File Device Number = 0
00 00 00 02 Num of File Blocks = 2
00 00 03 04 File System ID     = 772(0x0304)
00 0e 68 2a File ID = 944170(0x0e682a)
38 ba f6 bf 00 00 00 00 st_atime
38 b9 95 c7 00 00 00 00 st_mtime
38 b9 95 c7 00 00 00 00 st_ctime

可以在192.168.67.108上执行stat /home/scz/nfsexport,看看输出
结果和这里的报文信息什么关系。

★ 鉴别

NFS系统依赖Mount协议提供的鉴别,nfs server本身不对nfs client的请求进行鉴别。
而Mount协议一般使用RPC的AUTH_UNIX/AUTH_NONE鉴别机制,前面提过,这些鉴别机制
本身存在安全问题。一旦nfs client获得了一个远程目录树的根句柄,就可以对该远
程目录树进行很多操作。

早期NFS版本中,nfs server使用一种固定的方式创建32字节长的句柄。于是nfs client
可以针对任意的nfs server端export出来的文件制造句柄,从而绕过Mount协议提供的
鉴别保护。

★ NFS/Mount协议中可能存在的安全问题

    1. 考虑编写一个程序,利用Mount协议获取server端的文件句柄,研究句柄可能
       的编码方式,以及当前是否使用着AUTH_UNIX鉴别机制。这个也可以通过协议
       分析软件达到目的,但我觉得还是编程更能锻炼你。

       利用这个程序检查某个nfs server是否具有一定安全性。
       主要是指检查server端的i-node generation number是否随机化了。
       scz注:如此含混,只因为我对inode数据结构的C语言定义不了解,sigh

    2. 写一个程序,利用Mount协议提供的远程过程,获取nfs server端export出来
       的远程目录清单。实际上就是showmount -e 达到的效果,如果你觉得自己编
       写这个程序比较困难,可以找到showmount的源代码研究研究。

    3. NFS版本3与2相比,句柄和magic cookie有了变化,句柄由固定大小的32字节
       变成可变大小最多64字节。版本3允许nfs server在大文件句柄(安全)和小文
       件句柄(高效)之间作出选择。

★ 相关RFC以及参考资料

RFC 1094 << NFS: Network File System Protocol Specification >>

Sun Microsystems 公司定义的NFS协议版本2和mount协议

RFC 1813 << NFS Version 3 Protocol Specification >>

NFS协议的第3版

Douglas E. Comer & David L. Stevens
<< Internetworking With TCP/IP Vol III >>

W.Richard Stevens
<< TCP/IP Illustrated Volume I >>

(待续)






版权所有,未经许可,不得转载
欢迎访问我们的站点http://www.isbase.com/
绿色兵团给您安全的保障





 关于我们   合作伙伴   绿盟月刊   安全论坛   系统漏洞   安全文献   工具介绍   服
务项目   客户专区

--------------------------------------------------------------------------------

绿盟计算机网络安全技术有限公司版权所有   联系:isbase@isbase.net
&copy; 1999,2000 isbase Corporation. All rights Reserved.

--
☆ 来源:.BBS 荔园晨风站 bbs.szu.edu.cn.[FROM: bbs@192.168.28.106]


[回到开始] [上一篇][下一篇]

荔园在线首页 友情链接:深圳大学 深大招生 荔园晨风BBS S-Term软件 网络书店