Bugtraq mailing list archives
NIS+ and signed directory objects (not!)
From: wpaul () CTR COLUMBIA EDU (Bill Paul)
Date: Thu, 27 Mar 1997 11:33:07 -0500
Okay, I have some questions about security on NIS+ clients. It seems to me there's a gaping hole, but I could be wrong. NIS+ clients run a daemon called nis_cachemgr which is designed to cache directory 'objects' returned from NIS+ servers. The object is really an XDR encoded directory_obj structure (as defined in <rpcsvc/nis_object.x>). The tricky part about nis_cachemgr is that any local process on the system is allowed to send it requests to cache objects; nis_cachemgr is basically just an RPC server, with a protocol defined in <rpcsvc/nis_cache.x>. Since NIS+ directory lookups are performed by library code in libnsl, they might be made by anyone on the system; hence nis_cachemgr must be prepared to accept updates from privileged and unprivileged users alike. The cache (/var/nis/NIS_SHARED_DIRCACHE) is later accessed by other processes: if, say, user 'foo' does an 'niscat passwd.org_dir,' this will cause the org_dir object to be saved in /var/nis/NIS_SHARED_DIRCACHE. Subsequently, user 'bar' may issue the same command, but rather than asking the remote server to do a directory lookup all over again, the client NIS+ library reads the org_dir object from the cache. An obvious question is: what happens if a malicious user decides to write his own client program to talk to nis_cachemgr and instructs it to load the cache with bogus objects? How can nis_cachemgr tell if the request is legitimate or if the user is just trying to be a wiseass? The answer is supposed to be the 'signature' contained in the fd_result structure returned by the NIS+ server (rpc.nisd). The server is supposed to compute an MD5 digest of the encoded directory object and encrypt it (with ecb_crypt()) using a Secure RPC conversation key. This conversation key consists of the server's secret key and the requester's public key. (You can get it from the keyserv daemon with the key_get_conv() function.) Since nis_cachemgr runs as root, its principal name is the same as the 'requester' listed in the finddirectory request, hence it will be able to compute its own signature and compare it to the one generated by the server (using its secret key and the server's public key). Since only the server knows its RPC secret key, it should be impossible for a user to forge a directory object because it can't create a proper signature. But here's the problem: from what I can tell, rpc.nisd never signs its directory objects and nis_cachemgr never checks for them. I've run several tests with Solaris 2.5.1 on a couple of different machines. I've set up a dummy root server and a single dummy client, with all the right credentials. Authentication of the client works correctly and the service seems to function properly. However, when I use a test program to call the NIS_FINDDIRECTORY procedure on rpc.nisd, the server sends back an object without a signature. I tried several different variations (using AUTH_DES authentication, using AUTH_SYS authentication, using no authentication, running the program on the server host itself) but I could never get rpc.nisd to supply a signed directory object. At first I was convinced that I was omitting some magic in my test program since I could tell that nis_cachemgr was adding directory objects to the client's cache. The nis_cachemgr man page states that it will always attempt to authenticate the signature unless you start it with the -i flag (to activate insecure mode). I did not start nis_cachemgr with the -i flag, so it should have been checking for signatures and if rpc.nisd wasn't sending them, it would never have updated the cache. Finally, after simplifying the test program as much as I could and still not getting any results, I started to think that maybe the problem was with rpc.nisd after all. Thanks go gdb, I finally learned what was going on: the insecureMode flag in nis_cachemgr starts off initialized to 0 but is forced to 1 later in the program even though nis_cachemgr was _NOT_ started with -i. In other words, nis_cachemgr doesn't really check for signatures at all, which bore out my hunch that rpc.nisd was never sending them. As a further test, I even toggled the insecureMode flag back off with gdb and let nis_cachemgr continue running; now, as I expected, it would no longer add any directory objects to the cache since it couldn't verify the signatures. I haven't tried running gdb on rpc.nisd since I'm confused enough as it is. So here's what I'm wondering: can anyone think of a reason why the signature generation and checking has been lobotomized? And for that matter, does this impact security on NIS+ clients as much as I think it does? It occured to me that maybe there might be some special encryption kit that has to be installed for this stuff to work right, but that doesn't make sense since Secure RPC already works with the stock Solaris distribution, and that's all that's really needed for generating signatures. I'm also wondering if maybe there's something fishy going on between nis_cachemgr and nscd (the name service cache daemon) that somehow negates the risk of not having signatures. I can't see how though. -Bill -- ============================================================================= -Bill Paul (212) 854-6020 | System Manager, Master of Unix-Fu Work: wpaul () ctr columbia edu | Center for Telecommunications Research Home: wpaul () skynet ctr columbia edu | Columbia University, New York City ============================================================================= "Now, that's "Open" as used in the sentence "Open your wallet", right?" =============================================================================
Current thread:
- NIS+ and signed directory objects (not!) Bill Paul (Mar 27)