A variety of protocols exist primarily to allow users to execute commands on remote systems. This section describes the BSD "r" commands, rexec and rex.
The BSD "r" commands (rsh, rlogin, rcp, rdump, rrestore, and rdist) are designed to provide convenient remote access (access without passwords) to services such as remote command execution (rsh), remote login (rlogin), and remote file copying (rcp and rdist).
These programs are extremely useful, but as we discuss below, they are safe to use only in an environment in which all of the machines are more or less trusted to play by the rules. While it may be appropriate to use these services within a LAN, it's almost never appropriate to use them across the Internet. It's just too easy for someone to convince these services that they're OK and that the service should perform what's requested.
Proxying can be used to allow some of these commands safely, particularly outbound.
The difficulty with these commands is that they use address-based authentication. The server looks at the source address of the request and decides whether or not it trusts the remote host to tell it who the user is (this is controlled by the /etc/hosts.equiv file on UNIX systems).
If the host is not in /etc/hosts.equiv, it can still be granted access if it is in the .rhosts file in the home directory of the user who is asking for the service. (In fact, if the requester is running as root, only /.rhosts is consulted; /etc/hosts.equiv applies only to normal users.) The security can be further weakened by users adding to their .rhosts files; these files specify which additional remote machines and users should be trusted. In some implementations, it is possible to disable checking of .rhosts files with command-line arguments to the servers.
If either of the following is true:
The account the user is coming from, on the host he is coming from, is listed in the .rhosts file for the account he is trying to access on the server.
The account name is the same on both ends and the hostname is listed in .rhosts or /etc/hosts.equiv.
An attacker who convinces one of these servers that he is coming from a "trusted" machine can essentially get complete and unrestricted access to your system. He can convince the server by impersonating a trusted machine and using its IP address, by confusing DNS so that DNS thinks that the attacker's IP address maps to a trusted machine's name, or by any of a number of other methods.
If the trusted host check described above fails (that is, if the user is not coming from a trusted host), most of these services simply deny the client's request and disconnect. The rlogind server, however, will prompt the client for a password if the trusted host check fails. The password entered is sent in the clear over the net, just as with Telnet, so you have to worry about attackers capturing passwords from rlogin sessions, as they can from Telnet sessions. See Chapter 10 for a discussion of ways to address password sniffing attacks.
On some systems, it is possible to disable the trusted host checks with a command line argument to the servers; even if your server doesn't provide a convenient switch to disable the checks, if you have (or can get) source code for the servers, it's usually a relatively simple fix. However, without the trusted host mechanism, the rshd server is completely pointless, because it provides no way to prompt for a password or anything like that if the trusted host check fails. The rlogind server is still somewhat useful without the trusted host check, because it can ask for a password, but it's not much more useful than Telnet.
The "r" commands are TCP-based services. For the server, they use well-known port 513 (rlogin) or 514 (rsh, rcp, rdump, rrestore, and rdist; these are just different clients for the same server). They are somewhat unusual in that they use random ports below 1024 for the client end.
Using ports below 1024 for the client end is an attempt at a security scheme that allows password-less access to these services as long as the requests come from a trusted host and user, as discussed above. The idea is that, if the request comes from a port below 1024 on the client end, then the request must be OK with root on the client machine; if it were not, the client never could have gotten the port below 1024 to use for the request.
Further, some of the clients of the server on port 514 (rsh, for example) use a second TCP connection for error reporting. This second TCP connection is opened from a random port below 1024 on the server to a random port below 1024 on the client; that is, an outgoing rsh command involves an incoming TCP connection for the error channel.
Direc- | Source | Dest. | Pro- | Source | Dest. | ACK | |
---|---|---|---|---|---|---|---|
tion | Addr. | Addr. | tocol | Port | Port | Set | Notes |
In | Ext | Int | TCP | <1024 | 513 | [14] | Incoming rlogin, client to server |
Out | Int | Ext | TCP | 513 | <1024 | Yes | Incoming rlogin, server to client |
Out | Int | Ext | TCP | <1024 | 513 | [14] | Outgoing rlogin, client to server |
In | Ext | Int | TCP | 513 | <1024 | Yes | Outgoing rlogin, server to client |
In | Ext | Int | TCP | <1024 | 514 | [14] | Incoming rsh/rcp/rdump/rrestore/rdist, client to server |
Out | Int | Ext | TCP | 514 | <1024 | Yes | Incoming rsh/rcp/rdump/rrestore/rdist, server to client |
In | Ext | Int | TCP | <1024 | <1024 | Yes | Incoming rsh, error channel, client to server |
Out | Int | Ext | TCP | <1024 | <1024 | [14] | Incoming rsh, error channel, server to client |
Out | Int | Ext | TCP | <1024 | 514 | [14] | Outgoing rsh/rcp/rdump/rrestore/rdist, client to server |
In | Ext | Int | TCP | 514 | <1024 | Yes | Outgoing rsh/rcp/rdump/rrestore/rdist, server to client |
Out | Int | Ext | TCP | <1024 | <1024 | Yes | Outgoing rsh, error channel, client to server |
In | Ext | Int | TCP | <1024 | <1024 | [14] | Outgoing rsh, error channel, server to client |
[14] ACK is not set on the first packet of this type (establishing connection) but will be set on the rest.
The only one of these commands that's widely used across the Internet is rlogin. The TIS FWTK provides a proxy rlogin server that uses modified user procedures to provide outbound rlogin.
The other commands rely completely on address-based authentication, and don't allow the user to specify a password at all. They're used so seldom across the Internet that proxies for them are not widely available. All of them allow the user to specify enough data that's passed to the server that it would be possible to write modified-procedures proxies for them. Modifying the rcmd() and related functions in the standard UNIX library allow you to create clients that use a generic proxy server.
Don't allow any of the "r" commands across your firewall except outbound by proxy; they're unsafe. Use alternative protocols such as Telnet, FTP, and so on that can be made more secure.
There is no way to safely provide outgoing rsh service, because to do so you would have to allow incoming TCP connections to random ports below 1024 for the error channels.
If you absolutely have to allow them, make sure that the trusted host mechanisms are strictly controlled (preferably by disabling that code in the server, which may require modifying the source code).
Beware disclosure of reusable passwords when using rlogin, just as when using Telnet.
rexec is a widely run but rarely used server. It's rarely used because it has few standard clients; the only utility commonly shipped with UNIX systems that we're aware of that uses rexec is the inst software installation tool that's part of the Silicon Graphics IRIX operating system, for remote software installations. It is unclear to us why it is widely run, but almost every UNIX system ships with rexecd enabled in /etc/inetd.conf, apparently just in case somebody should be moved to write a local client for it.
rexec is usually lumped in with the BSD "r" commands, but is actually slightly more secure than the others. Rather than providing source-address authentication, it always requires the user to provide a user name and password. Unfortunately, it passes these across the network in the clear, so it has no security advantage over Telnet, for example.
rexec is a TCP-based service. The server uses port 512. The client uses a random port below 1024 (see the previous explanation for the BSD "r" commands).
Direc- | Source | Dest. | Pro- | Source | Dest. | ACK | |
---|---|---|---|---|---|---|---|
tion | Addr. | Addr. | tocol | Port | Port | Set | Notes |
In | Ext | Int | TCP | <1024 | 512 | [15] | Incoming rexec, client to server |
Out | Int | Ext | TCP | 512 | <1024 | Yes | Incoming rexec, server to client |
Out | Int | Ext | TCP | <1024 | 512 | [15] | Outgoing rexec, client to server |
In | Ext | Int | TCP | 512 | <1024 | Yes | Outgoing rexec, server to client |
[15] ACK is not set on the first packet of this type (establishing connection) but will be set on the rest.
Because there are no widely available clients of rexec, there are no widely available proxies for it. If you had a client that did use rexec, it would not be terribly difficult to modify it to use a generic proxy like SOCKS. If the rexec clients on a given machine were always accessing the same server, you could also use a generic proxy server like the plug-gw program in the TIS FWTK. It would be somewhat trickier, but by no means impossible, to write a dedicated proxy server that would use modified user procedures.
rexec is pointless; disable it.
rex is an RPC-based service for remote command execution. For an understanding of the problems RCP-based services pose for firewalls, see the discussion of RPC-based services in Chapter 6. There are worse problems with rex, however; in particular, it places all of its security checks in the client (which is a program named on), and anyone can use a modified client that bypasses these checks.
rex is an RPC-based service. As described in the section on RPC in Chapter 6, it's very difficult to handle RPC-based services with a packet filtering system, because the servers usually don't use predictable port numbers. While the port numbers to be used are too unpredictable for a packet filtering system to cope with, they're not so unpredictable that an attacker can't find them. (If nothing else, the attacker could try sending rex requests to all ports, to see which respond as they would expect a rex server to.)
rex is provided over TCP. Like other RPC-based services, however, there's no predicting what port number the server is going to use. Clients generally use port numbers above 1023.
RPC-based protocols are almost as unpleasant to proxy as they are to allow with packet filtering; they cannot be adequately handled with generic proxies. A dedicated rex proxy server would be possible, but we do not know of one.
Don't allow rex across your firewall; better yet, don't allow it at all, because it's completely insecure even within a LAN environment.