[转载]rsh的网络通信细节
信息来源:scz的主页文章作者:scz(小四)
由tt调试rsh服务、查看相关源码,并解释了为什么rshd会检查源端口。scz负责前期
协议分析、后期测试代码编写。
rsh服务侦听514/TCP口,而514/UDP口对应syslog服务,与echo、chargen、daytime
等服务不同,这次514/TCP、514/UDP不属于同一服务。下面的讨论基于已经了解rsh
应用这个假设,不熟悉了可以查看rsh、rshd、rhosts、hosts.equiv手册页。
rsh服务是否有RFC对应呢,反正我是没有Google出来,在几本bible上也未找到更多
细节。在*nix上"man rshd"可以看到一些协议细节。如果有相关源码,最好看源码,
man手册大多未能同步更新。
client建立到server的514/TCP的连接。
服务端会先检查TCP连接的源端口是否位于[512,1023]区间,否则服务端进程终止。
*nix最早要求范围是[1,1023],后来为消除一些安全隐患([1]),改成[512,1023]。
但这是实现相关的,并且各个系统的man手册可能与其当前实现不同步,某些版本
Solaris的man手册就有问题,应实测。
为什么rshd有这个限制?
假设B机上的root信任A机上的scz,并未信任A机上的tt,同时rshd对源端口没有限制。
tt登录A机,自己写了一个程序向B机的514/TCP发送"\0scz\0root\0id\0",尽管此时
源端口必将大于等于1024,命令仍将成功地远程执行。反之rshd对源端口有限制,则
tt必须设法使自己所写程序以root身份执行,才有可能指定小于1024的源端口。如果
tt就是root,本就无所谓安全隐患。如果tt不是root,就阻止了tt伪装成scz。
一般rsh、rcp、rlogin被设置成setuid-to-root,tt要想访问远端rshd,只能用系统
自带的rsh、rcp、rlogin,但这三个程序会如实指定client_user字段,不存在伪造
的可能。
*nix历史上多是大型主机带多个哑终端,做这样的安全防范可以理解。
假设client位于NAT后面,请求报文到达server时源端口很可能已经大于等于1024,
由于对源端口的检查,rsh不会成功。要是对协议细节不熟,就无法理解为什么会失
败。
实测中发现,某些NAT实现可能对rsh、rlogin通信过程做了特殊处理,报文经过NAT
后源端口仍将位于[512,1023]区间。
client向server发送如下请求数据:
[port]\0<client_user>\0<server_user>\0<command>\0
port
ANSI字符串形式的端口号,不是短整型形式的端口号。
client_user
客户端当前用户名
server_user
试图远程使用的服务端用户名
command
试图远程使用的服务端命令
由于是TCP通信,客户端实现时未必一次性发送如上数据,有可能分成几次(比如四次
)发送,效果一致。
port本身是可选项。如果指定了port,客户端必须事先主动侦听在port上,服务端会
建立到客户端这个端口(port)的TCP连接,同时rshd会将stderr重定向到这条连接上。
如果不指定port,客户端就不必事先主动侦听在port上,服务端也不会回连,rshd将
stderr与stdout、stdin一并重定向到514/TCP口对应的那条TCP连接(即当前连接)上。
如果客户端提供了port字段,*nix的服务端要求port在[1,1023]上,并且能成功建立
到客户端的TCP连接,否则服务端进程终止。关于port的范围限制是实现相关的,各
个系统的man手册可能与其当前实现不同步,某些版本Linux的man手册就有问题,应
实测。服务端回连客户端时源端口也将在[512,1023]区间。
对port字段的限制其实道理同前,本质上还是阻止tt伪装成scz。不过这个限制实在
没必要,甚至没必要提供port字段。
提供正确的port字段后,server会回连client。一方面client必须事先侦听在port上
等待server的回连,这将多消耗一个套接字。另一方面如果NAT、FW等因素干挠了回
连过程,rsh将失败。FW一般需要特殊对待rsh通信,就像特殊对待FTP通信一样。
有人要问了,既然port是可选项,rsh命令本身一定会提供port字段吗?我们测试了
Solaris、Linux自带rsh命令,抓包表明它们都提供port字段,并且没有命令行开关
改变这个行为,意味着在这些系统上执行rsh很容易受NAT、FW干挠而失败。这些系统
上的rcp、rlogin不会提供这个变态的port字段,相比rsh就少了很多被干挠的可能。
需要说明的是,rcp实际上是rsh的特例,后面会详细解释。rcp为什么不提供port字
段,rsh为什么非要提供port字段?苍天啊、大地啊,哪位仙女能告诉我这是为什么
啊为什么。rlogin服务侦听513/TCP口,其上的协议与514/TCP口有些类似,但不相同。
rlogin服务根本不支持port字段,如果强行提供,rlogin服务会认为请求数据不合法
而终止进程。
Aix的rsh提供了一个命令行开关"-a",可以禁止客户端提供port字段:
$ rsh <target> -l scz -a nonexistcmd
bash: nonexistcmd: command not found
用Ethereal抓包可以看到上述错误信息是直接由514/TCP回送的。当不指定"-a"时,
客户端将提供port字段,上述错误信息经由回连的TCP连接传输。至此,我实在想不
明白提供port字段的现实意义何在。
Aix的rshd会对客户端IP进行反向域名解析,解析不成功的话向客户端返回错误信息
并终止服务进程。解决方案有两种,一是在/etc/hosts中为客户端IP增加相应条目,
二是修改/etc/inetd.conf中rshd的命令行,增加命令行开关"-c",取消反向域名解
析。
client_user、server_user最长16个字符。command可以长些,但也有限制。缓冲区
溢出就不要想了,说不定历史上有过。
server向client发送如下响应数据:
<ret><data>
ret等于0x00表示成功,data对应执行结果,一般是\n分隔、结尾的文本。
ret等于0x01表示失败,data对应错误信息,一般也是\n分隔、结尾的文本。
页:
[1]