phil@eecs.nwu.edu (William LeFebvre) (01/13/91)
Archive-name: fixes/sun-fixes/portmap-securelib/1991-01-11 Archive: eecs.nwu.edu:/pub/securelib.tar [129.105.5.103] Original-posting-by: phil@eecs.nwu.edu (William LeFebvre) Original-subject: Enhancing network security by altering libc Reposted-by: emv@ox.com (Edward Vielmetti) 12345678901234567890123456789012345678901234567890123456789012345678901234567890 I think it was Mark Twain that said "Everyone always complains about security, but no one ever does anything about it." (or something like that.) Well, I've taken this to heart and I've actually done something about the security problems that have been discussed here recently. The two problems that I recall are: (1) anyone can access your portmap, and even delete services for you, and (2) anyone can use all of your pwdauthd daemons to parallelize their code guessing techniques (using YOUR cpu time, too!). Both of these problems (and several others) are centered around the fact that most network daemons do not restrict or even check who is connecting to them. They blindly answer every connection regardless of who is on the other end. Well, I have thrown together a package that I think (and hope) will take care of this problem. I call it "securelib". It contains a replacement for three of the libc kernel front-end routines: accept, recvfrom, and recvmsg. I did this using the technique that I described on this list a few weeks ago. This ONLY works on SunOS 4.1 or higher. Why? Because (1) it requires the existence of a shared library mechanism and (2) it requires access to the position-independent object files that make up libc (4.0.x did not provide these). This package is available via anonymous FTP from "eecs.nwu.edu". It is in "pub/securelib.tar". Remember to turn on "binary" before transferring! If you are not on the Internet and want a copy of this, first ask yourself this question: "If you aren't on the Internet, then why do you need this package?" Please take a copy and "kick the tires". Feedback is welcome. I just installed in on my IPC earlier today, and everything seems to be working just fine! I am using it to protect both portmap and rpc.pwdauthd. I have checked from another machine and it really does prevent outside connections to those daemons! I will include the README at the end of this posting. William LeFebvre Computing Facilities Manager and Analyst Department of Electrical Engineering and Computer Science Northwestern University <phil@eecs.nwu.edu> ------------------------ README ------------------------- SunOS 4.1 secure C library package Written by William LeFebvre, EECS Department, Northwestern University. Internet address: phil@eecs.nwu.edu OVERVIEW: This package contains replacement routines for these three kernel calls: accept, recvfrom, recvmsg. These replacements are compatible with the originals, with the additional functionality that they check the Internet address of the machine initiating the connection to make sure that it is "allowed" to connect. Once compiled, these can be used when building a new shared libc. The resulting libc.so can then be put in a special place. Any program that should be protected can then be started with an alternate LD_LIBRARY_PATH. What you need: SunOS version 4.1 or higher, installation of the "shared library" option, root access. You can see if your machine has the shared library option installed by looking for the directory "/usr/lib/shlib.etc". If it is not installed, then you will need to extract it from the distribution tapes (Sun-factory installed machines will NOT have it installed). Do you need to use this? If you can answer all of these questions with "yes", then this package will benefit you: Are you connected to the Internet (even via a local or regional network)? Do all of the routers/gateways between your machine and the "rest of the world" route all packets regardless of protocol or port number? Are you concerned about the fact that any user on any system anywhere on the Internet can connect to any network daemon that runs on your machine? AVAILABILITY: The latest version of securelib is available via anonymous FTP from the host "eecs.nwu.edu". It is stored in the file "pub/securelib.tar". Remember to use the "binary" transfer mode! DETAILS: Each modified system call has the same basic algorithm: { int retval; while ((retval = syscall(...)) >= 0) { if (_ok_address(socket, addr, *addrlen)) { return(retval); } close(retval); /* in the case of "accept" */ /* the other two don't have anything here */ } return(retval); } Connections that are established from a host that is not "okay" will be either closed or ignored and the appropriate system call will be called again. The application will only get the connections that "_ok_address" says are acceptable. It will never even know about any of the others. As I have written it, "_ok_address" is a very simple (some would say stupid) function. This was done for three reasons: first is expediency (I wanted to get this out as quickly as possible); second is the fact that it must run in a shared library, and I'm still not too sure just what I can and cannot do in a shared routine (especially regarding opening and reading files and using the streams library); third, I did not want to slow down the process of opening a connection or receiving data any more than I had to. CONFIGURATION: At the very top of _okaddr.c are a series of #define statements, one for each octet of the Internet address (counted from the left, as in one.two.three.four). If you want a specific octet checked against a known constant value, then #define that octet with the value here. YOU MUST MAKE THIS CHANGE! As distributed, _okaddr.c will not compile until you set the octet definitions. Octets that are not defined here are not checked, and thus any value in that octet is allowed. Here is an example. We are on Class B network 129.105.0.0. I want to allow only connections from that network. So, I use two defines: #define OCTET_1 129 #define OCTET_2 105 If I wanted to further restrict it to machines from subnet 4, I would add this define: #define OCTET_3 4 If you want any checking that is fancier or more involved that this, then you will have to code it yourself. But remember that "_ok_address" is called every time any of "accept", "recvfrom", or "recvmsg" is called. In the case of nfsd (or most any other udp-based protocol), that will happen for every incoming packet. Once you have modified _okaddr.c to suit your needs, you should check and modify the Makefile. The first two lines define SHLIB, the location of the "shlib.etc" directory off of the distribution tape (this will almost certainly be "/usr/lib/shlib.etc"), and DESTDIR, the directory in which you want the secure library placed. I have chosen "/usr/lib/secure" for lack of a better place. REPLACING OR SUPERCEDING THE EXISTING libc LIBRARY IS NOT RECOMMENDED!!! The intent of this package is to provide an alternate libc that can be used only on selected servers (usually servers that are started at boot time). The alternate library is selected by setting LD_LIBRARY_PATH before starting the server. Once you have made these changes, type "make install" and everything should go smoothly. Typing just "make" will build the new library in the SHLIB directory, but it will not install it. Now decide which servers you want to protect. I personally have chosen portmap and rpc.pwdauthd. Another possibility is nfsd, but remember that each packet received by nfsd must be verified by "_ok_address". This may have a noticeable impact on nfs performance. Modify /etc/rc.local so that it starts the daemon with the alternate library path. This can be done by simply putting the following string at the beginning of the line that starts the daemon: LD_LIBRARY_PATH=/usr/lib/secure As an example, I have protected portmap and pwdauthd by replacing the requisite lines in /etc/rc.local with these, respectively: LD_LIBRARY_PATH=/usr/lib/secure portmap; echo -n ' portmap' LD_LIBRARY_PATH=/usr/lib/secure rpc.pwdauthd & echo -n ' pwdauthd' NOTE TO CUSTOM SHARED LIBRARY BUILDERS: If you have already built a customized shared library, for example if you have built a shared library with alternate gethost* routines for name resolution, you can still use this package. Just make sure that before you type "make", the object files for your alternate library are already in place in SHLIB/tmp. If the "tmp" subdirectory already exists, then this package will not recreate it or re-extract libc_pic.a. However, it WILL overwrite tmp/accept.o, tmp/recvfrom.o, and tmp/recvmsg.o. And it will add a line to lorder-sparc (after saving the original in lorder-sparc.orig). DISCLAIMERS: IMPORTANT NOTE: THIS LIBRARY DOES NOT GUARANTEE THAT YOUR MACHINE IS SECURE!!! This library enhances security---it does not guarantee it. It can be used to plug several known security holes on SunOS machines. NO WARRANTY: BECAUSE "securelib" IS DISTRIBUTED FREE OF CHARGE, THERE IS ABSOLUTELY NO WARRANTY PROVIDED, TO THE EXTENT PERMITTED BY APPLICABLE STATE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING, NORTHWESTERN UNIVERSITY, WILLIAM N. LeFEBVRE AND/OR OTHER PARTIES PROVIDE "securelib" "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE "securelib" PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. IN NO EVENT WILL NORTHWESTERN UNIVERSITY, WILLIAM N. LeFEBVRE, AND/OR ANY OTHER PARTY WHO MAY MODIFY AND REDISTRIBUTE "securelib", BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY LOST PROFITS, LOST MONIES, OR OTHER SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH OTHER PROGRAMS) THE PROGRAM, EVEN IF YOU HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY.