We discuss intermediary protocols here because they form the basis for many of the protocols we discuss later. However, intermediary protocols are usually invisible, and they are often complex. If you are not already familiar with network protocols, you may want to skip this chapter initially, and come back to it as needed.
ultiple remote procedure call protocols are known as RPCs. In particular, on Unix systems, the protocol normally known as "RPC" is one developed by Sun and later standardized as Open Network Computing RPC. On Microsoft systems, the protocol normally known as "RPC" is compatible with a descendent of Sun's RPC standardized by the Open Systems Foundation (OSF) as part of its Distributed Computing Environment (DCE). For clarity, we will call these "Sun RPC" and "Microsoft RPC". It is arguably more correct to call them "ONC RPC" and "DCE RPC"; however, we find that in this case, correctness and clarity are at odds with each other.
Other remote procedure call mechanisms are used on particular implementations, but these two account for most of the market, and the other RPC mechanisms are similar in concept and difficulties. For simplicity, when we are making statements that refer to all protocols we know of that anybody calls "RPC", we'll say just "RPC".
Sun RPC and icrosoft RPC are quite similar and are related, but they do not interoperate. Microsoft RPC is an implementation of DCE RPC and can interoperate with other DCE RPC implementations. Some Unix machines support both Sun RPC and DCE RPC (usually Sun RPC is a default, and DCE RPC is an option or an add-on product). In practice, even if you run DCE RPC on a Unix machine, you will very rarely notice any interoperability with Microsoft RPC. The DCE RPC standard covers only a small amount of functionality, and most applications use features that are not in the base set. These features are not guaranteed to be interoperable between implementations. Since DCE RPC is relatively little used on Unix, Unix applications often stick to base features. icrosoft, however, makes extensive use of RPC and needs more functionality. They therefore almost always use incompatible features (mostly by using DCOM, which is discussed later). This is the main reason for our stubborn insistence on referring to "Microsoft RPC"; we are attempting to avoid the suggestion that Microsoft applications that use RPC can be expected to work with other DCE RPC servers or clients.
Like TCP and UDP, the RPCs are used as general-purpose transport protocols by a variety of application protocols; on Unix machines, this includes NFS and NIS, and on Windows NT machines, it includes Microsoft Exchange and the administrator applications for a number of services, including DHCP and Exchange. NFS and NIS are vulnerable services from a network security point of view. An attacker with access to your NFS server can probably read any file on your system. An attacker with access to your NIS server can probably obtain your password file and then run a password-cracking attack against your system. The Windows NT applications that use RPC are less security-critical but by no means safe. While it's not immediately fatal to have an attacker controlling your mail server, it's not pleasant either.
In the TCP and UDP protocols, port numbers are two-byte fields. This means that there are only 65,536 possible port numbers for TCP and UDP services. There aren't enough ports to be able to assign a unique well-known port number to every possible service and application that might want one. Among other things, RPC addresses this limitation. Each RPC-based service is assigned a unique four-byte RPC service number. This allows for 4,294,967,296 different services, each with a unique number. That's more than enough to assign a unique number to every possible service and application you'd need.
RPC is built on top of TCP and UDP, so there needs to be some way of mapping the RPC service numbers of the RPC-based servers in use on a machine to the particular TCP or UDP ports those servers are using. This is where the location server comes in. On Unix machines, the location server is a program called portmapper ; under Windows NT, it's the RPC Locator service. The functions and characteristics of the two are the same.
The location server is the only RPC-related server that is guaranteed to run on a particular TCP or UDP port number (for Sun RPC, it is at port number 111 on both; for icrosoft RPC, it is at port number 135 on both). When an RPC-based server such as an NFS or NIS server starts, it allocates a TCP and/or UDP (some use one, some the other, some both) port for itself. Then, it contacts the location server on the same machine to "register" its unique RPC service number and the particular port(s) it is using at the moment.
Servers usually choose arbitrary port numbers, but they can consistently choose the same port number every time if they wish. There is no guarantee that a server that does this will be able to register itself; some other server may have gotten there first, in which case the registration will fail. Obviously, if every server requests a fixed port number, there's not much point in using RPC at all. One of the major features of RPC is that it provides access that is not based on fixed port numbers.
An RPC-based client program that wishes to contact a particular RPC-based server on a machine first contacts the location server on that machine (which, remember, always runs on both TCP and UDP port 111 or 135). The client tells the location server the unique RPC service number for the server it wishes to access, and the location server responds with a message saying, in effect, either "I'm sorry, but that service isn't available on this machine at the moment", or "That service is currently running on TCP (or UDP) port n on this machine at the moment". At that point, the client contacts the server on the port number it got from the location server and continues its conversation directly with the server, without further involvement from the location server. (Figure 14-1 shows this process.)
Logically enough, "AUTH_NONE" means that there is no authentication at all. Applications that use AUTH_NONE are available to all users and ask for no authentication data. "AUTH_UNIX" could more appropriately be called "AUTH_ALMOST_NONE". Applications that use "AUTH_UNIX" ask the client to provide the numeric Unix user and group IDs for the user and enforce the permissions appropriate to those user and group IDs on the server machine. This information is completely forgeable; a hostile client can provide any user or group ID that seems desirable.
RPC servers are free to implement their own authentication schemes, but Sun RPC does not normally provide any reliable authentication for them except through Secure RPC. You do not want to allow access to RPC services unless you are sure that they do have their own, reliable authentication. (In general, this means simply disabling remote access to RPC altogether.)
Secure RPC provides another authentication scheme, known as "AUTH_DES". Secure RPC is an extension to Sun RPC that improves user authentication. Secure RPC has become available much more slowly than normal Sun RPC; for many years, Sun was effectively the only vendor that supported it, and it is still relatively rare and difficult to use in large heterogeneous networks.
This is partly because Secure RPC requires more infrastructure than regular RPC, and this infrastructure is often annoyingly visible to the user. Logically, Secure RPC is a classic combination of public key cryptography and secret key cryptography; Diffie-Hellman public key cryptography is used to securely determine a shared secret used for encryption with the DES algorithm. Cryptography, Diffie-Hellman, and the DES algorithm are discussed further in Appendix C, "Cryptography".
Secure RPC is based upon using a public key algorithm that has a maximum key size of only 192 bits in length. This size of key is too small and is considered to make Secure RPC vulnerable to factoring attacks, where an attacker can discover the private key from computations based upon captured key exchange data. An attacker would have to use considerable computing resources to break a key, but once a key was broken, it could be used to impersonate the user at any place those credentials were used.
There are two major difficulties: distributing information about public keys, and getting private keys for human beings. Public and private keys are both big numbers, and they're security critical. If somebody can change the database of public keys, that person can put his or her public key in place of some other public key, and authenticate as any entity he or she would like to be. If somebody can read a private key, he or she can then authenticate as the entity that owns that private key. Normally, you might deal with this by not storing the private key on the computer, but human beings are very bad at providing large numbers on demand.
The Secure RPC infrastructure can deal with the public key information in a number of ways. On Suns, the normal method is to use NIS+, which has a credentials database. You can also distribute the same information as a regular NIS map or as a file. If you put the information in a file, you then have to distribute the file, which is normally done with NFS. As we discuss in Chapter 20, "Naming and Directory Services", normal NIS is not secure; therefore, if you distribute the public key information this way, it will be vulnerable to replacement by attackers. As we discuss in Chapter 17, "File Transfer, File Sharing, and Printing", normal NFS isn't secure, either. To secure it, you run NFS over Secure RPC, which isn't going to work if you need to have access to NFS before you can get Secure RPC running. If you're going to rely on Secure RPC, you must ensure that the public keys are distributed via a secure method (which will generally be NIS+). NIS+ itself uses Secure RPC, but because it is authenticating as the machine (instead of as a particular user, which is necessary for NFS), and is communicating with a known server, it can locally store the information necessary to start up a connection to the NIS+ service, avoiding the bootstrapping problem.
|Direction||Source Addr.||Dest. Addr.||Protocol||Source Port||Dest. Port||ACK Set||Notes|
|Request, external client to internal Sun RPC location server|
|Out||Int||Ext||UDP||111||>1023||Response, internal Sun RPC location server to external client|
|Out||Int||Ext||UDP||>1023||111||Request, internal client to external Sun RPC location server|
|In||Ext||Int||UDP||111||>1023||Response, external Sun RPC location server to internal client|
|Request, external client to internal Sun RPC location server|
|Out||Int||Ext||TCP||111||>1023||Yes||Response, internal Sun RPC location server to external client|
|Out||Int||Ext||TCP||>1023||111||Request, internal client to external Sun RPC location server|
|In||Ext||Int||TCP||111||>1023||Yes||Response, external Sun RPC location server to internal client|
|In||Ext||Int||UDP||>1023||135||Request, external client to internal Microsoft/DCE RPC location server|
|Out||Int||Ext||UDP||135||>1023||Response, internal Microsoft/DCE RPC location server to external client|
|Out||Int||Ext||UDP||>1023||135||Request, internal client to external Microsoft/DCE RPC location server|
|In||Ext||Int||UDP||135||>1023||Response, external Microsoft/DCE RPC location server to internal client|
|In||Ext||Int||TCP||>1023||135||Request, external client to internal Microsoft/DCE RPC location server|
|Out||Int||Ext||TCP||135||>1023||Yes||Response, internal Microsoft/DCE RPC location server to external client|
|Out||Int||Ext||TCP||>1023||135||Request, internal client to external Microsoft/DCE RPC location server|
|In||Ext||Int||TCP||135||>1023||Yes||Response, external Microsoft/DCE RPC location server to internal client|
|In||Ext||Int||UDP||>1023||Any||Request, external client to internal RPC server|
|Out||Int||Ext||UDP||Any||>1023||Response, internal RPC server to external client|
|Out||Int||Ext||UDP||>1023||Any||Request, internal client to external RPC server|
|In||Ext||Int||UDP||Any||>1023||Response, external RPC server to internal client|
|In||Ext||Int||TCP||>1023||Any||Request, external client to internal RPC server|
|Out||Int||Ext||TCP||Any||>1023||Yes||Response, internal RPC server to external client|
|Out||Int||Ext||TCP||>1023||Any||Request, internal client to external RPC server|
|In||Ext||Int||TCP||Any||>1023||Yes||Response, external RPC server to internal client|
TIP: Even though it is not sufficient, you should still block access to the location server because some versions of the location server are capable of being used as proxies for an attacker's clients.So, what do you do to guard RPC-based services? A couple of observations: First, it turns out that most of the "dangerous" RPC-based services (particularly NIS and NFS) are offered by default over UDP. Second, most services you'd want to access through a packet filter are TCP-based, not UDP-based; the notable exceptions are DNS, NTP, and syslog. These twin observations lead to the common approach many sites take in dealing with RPC using packet filtering: block UDP altogether, except for specific and tightly controlled "peepholes" for DNS, NTP, and syslog. With this approach, if you wish to allow any TCP-based RPC service in a given direction, you'll need to allow them all, or use a packet filter that can contact the location service.
Windows NT provides more control over the ports used by RPC. This will help if you want to allow remote clients to access your servers, but it will not help you allow internal clients to access external servers (unless you can talk the owners of the servers into modifying their machines). Most uses of RPC are actually uses of DCOM, which provides a user interface to configuring ports that is discussed later in this chapter. You can also control the size of the port range used by RPC directly. To limit the size of the port range, modify the following registry key:
so that the "Ports" key is set to the port range you wish to use, the "PortsInternetAvailable" key is set to "Y", and "UseInternetPorts" is also set to "Y".HKEY_LOCAL_MACHINE\Software\Microsoft\RPC
The procedure for setting the port for a given service varies from service to service. It is sometimes documented in the manuals, and the Microsoft web site gives instructions on setting RPC ports for services that are particularly frequently used through firewalls. Again, most RPC services are DCOM services, and there is a user interface for changing DCOM parameters. It is worth checking the DCOM interface even if you see documentation that advises you to edit the registry directly.
If you set the port that a service uses, be sure to pick a port that is not in use by another server, and a port that is not at the beginning of the RPC port range. Since most servers choose the first free number in the RPC port range, a server that asks for a number very close to the beginning of the port range is quite likely to find it already in use. At this point, either the server will fail to start at all, because the RPC registration fails, or the server will select a random port and start on it. In either case, remote clients who are relying on the server being at a fixed port number will be unable to access it.
A number of transparent proxy servers do support Sun RPC; a smaller number are now adding support for DCE/Microsoft RPC. Products vary in the amount of support they provide, with some providing all-or-none support, and others allowing you to specify which RPC services you wish to allow.
|13.6. Controlling Unsafe Configurations||14.2. Distributed Component Object Model|
Copyright © 2002 O'Reilly & Associates. All rights reserved.